access levels, actions and triggers removed. Restructuring and refactoring
This commit is contained in:
parent
ff73cfba48
commit
3564fec064
|
@ -17,6 +17,7 @@ import path from "path"
|
|||
const production = !process.env.ROLLUP_WATCH
|
||||
|
||||
const lodash_fp_exports = [
|
||||
"pipe",
|
||||
"union",
|
||||
"reduce",
|
||||
"isUndefined",
|
||||
|
|
|
@ -36,6 +36,6 @@
|
|||
|
||||
{#if $store.clientId}
|
||||
<Modal>
|
||||
<Router {routes} />
|
||||
<Router {routes} />
|
||||
</Modal>
|
||||
{/if}
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
<script>
|
||||
import IconButton from "components/common/IconButton.svelte"
|
||||
import { store } from "builderStore"
|
||||
import UserInterfaceRoot from "components/userInterface/UserInterfaceRoot.svelte"
|
||||
import { fade } from "svelte/transition"
|
||||
</script>
|
||||
|
||||
<div class="root">
|
||||
<div class="content uk-container">
|
||||
|
||||
<h1>Settings</h1>
|
||||
|
||||
<label>
|
||||
<input
|
||||
type="checkbox"
|
||||
class="uk-checkbox"
|
||||
bind:checked={$store.useAnalytics} />
|
||||
Send analytics
|
||||
</label>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
|
@ -1,12 +0,0 @@
|
|||
import { createNewHierarchy } from "components/common/core"
|
||||
|
||||
export const createPackage = (packageInfo, store) => {
|
||||
packageInfo.createNewPackage("")
|
||||
const root = createNewHierarchy()
|
||||
store.importAppDefinition({
|
||||
hierarchy: root,
|
||||
actions: [],
|
||||
triggers: [],
|
||||
accessLevels: { version: 0, levels: [] },
|
||||
})
|
||||
}
|
|
@ -1,5 +1,4 @@
|
|||
import { filter, map, reduce, toPairs } from "lodash/fp"
|
||||
import { pipe } from "components/common/core"
|
||||
import { filter, map, reduce, toPairs, pipe } from "lodash/fp"
|
||||
|
||||
const self = n => n
|
||||
const join_with = delimiter => a => a.join(delimiter)
|
||||
|
|
|
@ -5,6 +5,7 @@ export const loadLibs = async (appId, appPackage) => {
|
|||
const allLibraries = {}
|
||||
|
||||
for (let lib of libsFromPages(appPackage.pages)) {
|
||||
console.log(libModule);
|
||||
const libModule = await import(makeLibraryUrl(appId, lib))
|
||||
allLibraries[lib] = libModule
|
||||
}
|
||||
|
|
|
@ -6,6 +6,8 @@ import {
|
|||
constructHierarchy,
|
||||
} from "components/common/core"
|
||||
|
||||
import backendActions from "../../actions/backend";
|
||||
|
||||
export const getBackendUiStore = () => {
|
||||
const INITIAL_BACKEND_UI_STATE = {
|
||||
breadcrumbs: [],
|
||||
|
@ -79,9 +81,6 @@ export const getBackendUiStore = () => {
|
|||
}
|
||||
|
||||
// Store Actions
|
||||
export const createShadowHierarchy = hierarchy =>
|
||||
constructHierarchy(JSON.parse(JSON.stringify(hierarchy)))
|
||||
|
||||
export const createDatabaseForApp = store => appInstance => {
|
||||
store.update(state => {
|
||||
state.appInstances.push(appInstance)
|
||||
|
@ -98,248 +97,4 @@ export const saveBackend = async state => {
|
|||
},
|
||||
accessLevels: state.accessLevels,
|
||||
})
|
||||
}
|
||||
|
||||
// export const newModel = (store, useRoot) => () => {
|
||||
// store.update(state => {
|
||||
// state.currentNodeIsNew = true
|
||||
// const shadowHierarchy = createShadowHierarchy(state.hierarchy)
|
||||
// const parent = useRoot
|
||||
// ? shadowHierarchy
|
||||
// : getNode(shadowHierarchy, state.currentNode.nodeId)
|
||||
// state.errors = []
|
||||
// state.currentNode = templateApi(shadowHierarchy).getNewModelTemplate(
|
||||
// parent,
|
||||
// "",
|
||||
// true
|
||||
// )
|
||||
// return state
|
||||
// })
|
||||
// }
|
||||
|
||||
export const selectExistingNode = store => nodeId => {
|
||||
store.update(state => {
|
||||
state.currentNode = getNode(state.hierarchy, nodeId)
|
||||
state.currentNodeIsNew = false
|
||||
state.errors = []
|
||||
return state
|
||||
})
|
||||
}
|
||||
|
||||
// export const newIndex = (store, useRoot) => () => {
|
||||
// store.update(state => {
|
||||
// state.shadowHierarchy = createShadowHierarchy(state.hierarchy)
|
||||
// state.currentNodeIsNew = true
|
||||
// state.errors = []
|
||||
// const parent = useRoot
|
||||
// ? state.shadowHierarchy
|
||||
// : getNode(state.shadowHierarchy, state.currentNode.nodeId)
|
||||
|
||||
// state.currentNode = templateApi(state.shadowHierarchy).getNewIndexTemplate(
|
||||
// parent
|
||||
// )
|
||||
// return state
|
||||
// })
|
||||
// }
|
||||
|
||||
// export const saveCurrentNode = store => () => {
|
||||
// store.update(state => {
|
||||
// const errors = validate.node(state.currentNode)
|
||||
// state.errors = errors
|
||||
// if (errors.length > 0) {
|
||||
// return state
|
||||
// }
|
||||
// const parentNode = getNode(
|
||||
// state.hierarchy,
|
||||
// state.currentNode.parent().nodeId
|
||||
// )
|
||||
|
||||
// const existingNode = getNode(state.hierarchy, state.currentNode.nodeId)
|
||||
|
||||
// let index = parentNode.children.length
|
||||
// if (existingNode) {
|
||||
// // remove existing
|
||||
// index = existingNode.parent().children.indexOf(existingNode)
|
||||
// if (isIndex(existingNode)) {
|
||||
// parentNode.indexes = parentNode.indexes.filter(
|
||||
// node => node.nodeId !== existingNode.nodeId
|
||||
// )
|
||||
// } else {
|
||||
// parentNode.children = parentNode.children.filter(
|
||||
// node => node.nodeId !== existingNode.nodeId
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
|
||||
// // should add node into existing hierarchy
|
||||
// const cloned = cloneDeep(state.currentNode)
|
||||
// templateApi(state.hierarchy).constructNode(parentNode, cloned)
|
||||
|
||||
// if (isIndex(existingNode)) {
|
||||
// parentNode.children = sortBy("name", parentNode.children)
|
||||
// } else {
|
||||
// parentNode.indexes = sortBy("name", parentNode.indexes)
|
||||
// }
|
||||
|
||||
// if (!existingNode && state.currentNode.type === "record") {
|
||||
// const defaultIndex = templateApi(state.hierarchy).getNewIndexTemplate(
|
||||
// cloned.parent()
|
||||
// )
|
||||
// defaultIndex.name = hierarchyFunctions.isTopLevelIndex(cloned)
|
||||
// ? `all_${cloned.name}s`
|
||||
// : `${cloned.parent().name}_${cloned.name}s`
|
||||
|
||||
// defaultIndex.allowedModelNodeIds = [cloned.nodeId]
|
||||
// }
|
||||
|
||||
// state.currentNodeIsNew = false
|
||||
|
||||
// saveBackend(state)
|
||||
|
||||
// return state
|
||||
// })
|
||||
// }
|
||||
|
||||
// export const deleteCurrentNode = store => () => {
|
||||
// store.update(state => {
|
||||
// const nodeToDelete = getNode(state.hierarchy, state.currentNode.nodeId)
|
||||
// state.currentNode = hierarchyFunctions.isRoot(nodeToDelete.parent())
|
||||
// ? state.hierarchy.children.find(node => node !== state.currentNode)
|
||||
// : nodeToDelete.parent()
|
||||
|
||||
// const isModel = hierarchyFunctions.isModel(nodeToDelete)
|
||||
|
||||
// const check = isModel
|
||||
// ? canDeleteModel(nodeToDelete)
|
||||
// : canDeleteIndex(nodeToDelete)
|
||||
|
||||
// if (!check.canDelete) {
|
||||
// state.errors = check.errors.map(e => ({ error: e }))
|
||||
// return state
|
||||
// }
|
||||
|
||||
// const recordOrIndexKey = isModel ? "children" : "indexes"
|
||||
|
||||
// // remove the selected record or index
|
||||
// const newCollection = remove(
|
||||
// node => node.nodeId === nodeToDelete.nodeId,
|
||||
// nodeToDelete.parent()[recordOrIndexKey]
|
||||
// )
|
||||
|
||||
// nodeToDelete.parent()[recordOrIndexKey] = newCollection
|
||||
|
||||
// state.errors = []
|
||||
// saveBackend(state)
|
||||
// return state
|
||||
// })
|
||||
// }
|
||||
|
||||
// export const saveField = store => field => {
|
||||
// store.update(state => {
|
||||
// state.currentNode.fields = state.currentNode.fields.filter(
|
||||
// f => f.id !== field.id
|
||||
// )
|
||||
|
||||
// templateApi(state.hierarchy).addField(state.currentNode, field)
|
||||
// return state
|
||||
// })
|
||||
// }
|
||||
|
||||
// export const deleteField = store => field => {
|
||||
// store.update(state => {
|
||||
// state.currentNode.fields = state.currentNode.fields.filter(
|
||||
// f => f.name !== field.name
|
||||
// )
|
||||
// return state
|
||||
// })
|
||||
// }
|
||||
|
||||
const incrementAccessLevelsVersion = state => {
|
||||
state.accessLevels.version = state.accessLevels.version
|
||||
? state.accessLevels.version + 1
|
||||
: 1
|
||||
return state
|
||||
}
|
||||
|
||||
export const saveLevel = store => (newLevel, isNew, oldLevel = null) => {
|
||||
store.update(state => {
|
||||
const levels = state.accessLevels.levels
|
||||
|
||||
const existingLevel = isNew
|
||||
? null
|
||||
: find(a => a.name === oldLevel.name)(levels)
|
||||
|
||||
if (existingLevel) {
|
||||
state.accessLevels.levels = levels.map(level =>
|
||||
level === existingLevel ? newLevel : level
|
||||
)
|
||||
} else {
|
||||
state.accessLevels.levels.push(newLevel)
|
||||
}
|
||||
|
||||
incrementAccessLevelsVersion(state)
|
||||
|
||||
saveBackend(state)
|
||||
return state
|
||||
})
|
||||
}
|
||||
|
||||
export const deleteLevel = store => level => {
|
||||
store.update(state => {
|
||||
state.accessLevels.levels = state.accessLevels.levels.filter(
|
||||
t => t.name !== level.name
|
||||
)
|
||||
incrementAccessLevelsVersion(state)
|
||||
saveBackend(state)
|
||||
return state
|
||||
})
|
||||
}
|
||||
|
||||
export const saveAction = store => (newAction, isNew, oldAction = null) => {
|
||||
store.update(s => {
|
||||
const existingAction = isNew
|
||||
? null
|
||||
: find(a => a.name === oldAction.name)(s.actions)
|
||||
|
||||
if (existingAction) {
|
||||
s.actions = s.actions.map(action =>
|
||||
action === existingAction ? newAction : action
|
||||
)
|
||||
} else {
|
||||
s.actions.push(newAction)
|
||||
}
|
||||
saveBackend(s)
|
||||
return s
|
||||
})
|
||||
}
|
||||
|
||||
export const deleteAction = store => action => {
|
||||
store.update(state => {
|
||||
state.actions = state.actions.filter(a => a.name !== action.name)
|
||||
saveBackend(state)
|
||||
return state
|
||||
})
|
||||
}
|
||||
|
||||
export const saveTrigger = store => (newTrigger, isNew, oldTrigger = null) => {
|
||||
store.update(s => {
|
||||
const existingTrigger = isNew
|
||||
? null
|
||||
: s.triggers.find(a => a.name === oldTrigger.name)
|
||||
|
||||
if (existingTrigger) {
|
||||
s.triggers = s.triggers.map(a => (a === existingTrigger ? newTrigger : a))
|
||||
} else {
|
||||
s.triggers.push(newTrigger)
|
||||
}
|
||||
saveBackend(s)
|
||||
return s
|
||||
})
|
||||
}
|
||||
|
||||
export const deleteTrigger = store => trigger => {
|
||||
store.update(s => {
|
||||
s.triggers = s.triggers.filter(t => t.name !== trigger.name)
|
||||
return s
|
||||
})
|
||||
}
|
||||
}
|
|
@ -24,8 +24,6 @@ export const getStore = () => {
|
|||
apps: [],
|
||||
appname: "",
|
||||
hierarchy: {},
|
||||
actions: [],
|
||||
triggers: [],
|
||||
pages: defaultPagesObject(),
|
||||
mainUi: {},
|
||||
unauthenticatedUi: {},
|
||||
|
@ -35,14 +33,11 @@ export const getStore = () => {
|
|||
currentFrontEndType: "none",
|
||||
currentPageName: "",
|
||||
currentComponentProps: null,
|
||||
currentNodeIsNew: false,
|
||||
errors: [],
|
||||
hasAppPackage: false,
|
||||
accessLevels: { version: 0, levels: [] },
|
||||
currentNode: null,
|
||||
// accessLevels: { version: 0, levels: [] },
|
||||
// currentNode: null,
|
||||
libraries: null,
|
||||
showSettings: false,
|
||||
useAnalytics: true,
|
||||
appId: ""
|
||||
}
|
||||
|
||||
|
@ -50,28 +45,25 @@ export const getStore = () => {
|
|||
|
||||
store.setPackage = setPackage(store, initial)
|
||||
|
||||
store.saveLevel = backendStoreActions.saveLevel(store)
|
||||
store.deleteLevel = backendStoreActions.deleteLevel(store)
|
||||
// store.saveLevel = backendStoreActions.saveLevel(store)
|
||||
// store.deleteLevel = backendStoreActions.deleteLevel(store)
|
||||
store.createDatabaseForApp = backendStoreActions.createDatabaseForApp(store)
|
||||
store.saveAction = backendStoreActions.saveAction(store)
|
||||
store.deleteAction = backendStoreActions.deleteAction(store)
|
||||
store.saveTrigger = backendStoreActions.saveTrigger(store)
|
||||
store.deleteTrigger = backendStoreActions.deleteTrigger(store)
|
||||
// store.saveAction = backendStoreActions.saveAction(store)
|
||||
// store.deleteAction = backendStoreActions.deleteAction(store)
|
||||
// store.saveTrigger = backendStoreActions.saveTrigger(store)
|
||||
// store.deleteTrigger = backendStoreActions.deleteTrigger(store)
|
||||
store.importAppDefinition = importAppDefinition(store)
|
||||
|
||||
store.saveScreen = saveScreen(store)
|
||||
store.addComponentLibrary = addComponentLibrary(store)
|
||||
store.renameScreen = renameScreen(store)
|
||||
store.deleteScreen = deleteScreen(store)
|
||||
store.setCurrentScreen = setCurrentScreen(store)
|
||||
store.setCurrentPage = setCurrentPage(store)
|
||||
store.createScreen = createScreen(store)
|
||||
store.removeComponentLibrary = removeComponentLibrary(store)
|
||||
// store.removeComponentLibrary = removeComponentLibrary(store)
|
||||
store.addStylesheet = addStylesheet(store)
|
||||
store.removeStylesheet = removeStylesheet(store)
|
||||
store.savePage = savePage(store)
|
||||
store.showSettings = showSettings(store)
|
||||
store.useAnalytics = useAnalytics(store)
|
||||
store.createGeneratedComponents = createGeneratedComponents(store)
|
||||
store.addChildComponent = addChildComponent(store)
|
||||
store.selectComponent = selectComponent(store)
|
||||
|
@ -136,20 +128,6 @@ const setPackage = (store, initial) => async (pkg) => {
|
|||
return initial
|
||||
}
|
||||
|
||||
const showSettings = store => () => {
|
||||
store.update(state => {
|
||||
state.showSettings = !state.showSettings
|
||||
return state
|
||||
})
|
||||
}
|
||||
|
||||
const useAnalytics = store => () => {
|
||||
store.update(state => {
|
||||
state.useAnalytics = !state.useAnalytics
|
||||
return state
|
||||
})
|
||||
}
|
||||
|
||||
const importAppDefinition = store => appDefinition => {
|
||||
store.update(s => {
|
||||
s.hierarchy = appDefinition.hierarchy
|
||||
|
@ -341,45 +319,45 @@ const savePage = store => async page => {
|
|||
})
|
||||
}
|
||||
|
||||
const addComponentLibrary = store => async lib => {
|
||||
const response = await api.get(
|
||||
`/_builder/api/${s.appId}/componentlibrary?lib=${encodeURI(lib)}`,
|
||||
undefined,
|
||||
false
|
||||
)
|
||||
// const addComponentLibrary = store => async lib => {
|
||||
// const response = await api.get(
|
||||
// `/_builder/api/${s.appId}/componentlibrary?lib=${encodeURI(lib)}`,
|
||||
// undefined,
|
||||
// false
|
||||
// )
|
||||
|
||||
const success = response.status === 200
|
||||
// const success = response.status === 200
|
||||
|
||||
const components = success ? await response.json() : []
|
||||
// const components = success ? await response.json() : []
|
||||
|
||||
store.update(s => {
|
||||
if (success) {
|
||||
const componentsArray = []
|
||||
for (let c in components) {
|
||||
componentsArray.push(expandComponentDefinition(components[c]))
|
||||
}
|
||||
// store.update(s => {
|
||||
// if (success) {
|
||||
// const componentsArray = []
|
||||
// for (let c in components) {
|
||||
// componentsArray.push(expandComponentDefinition(components[c]))
|
||||
// }
|
||||
|
||||
s.components = pipe(s.components, [
|
||||
filter(c => !c.name.startsWith(`${lib}/`)),
|
||||
concat(componentsArray),
|
||||
])
|
||||
// s.components = pipe(s.components, [
|
||||
// filter(c => !c.name.startsWith(`${lib}/`)),
|
||||
// concat(componentsArray),
|
||||
// ])
|
||||
|
||||
s.pages.componentLibraries.push(lib)
|
||||
_savePage(s)
|
||||
}
|
||||
// s.pages.componentLibraries.push(lib)
|
||||
// _savePage(s)
|
||||
// }
|
||||
|
||||
return s
|
||||
})
|
||||
}
|
||||
// return s
|
||||
// })
|
||||
// }
|
||||
|
||||
const removeComponentLibrary = store => lib => {
|
||||
store.update(state => {
|
||||
state.pages.componentLibraries = state.pages.componentLibraries.filter(l => l !== lib);
|
||||
_savePage(state);
|
||||
// const removeComponentLibrary = store => lib => {
|
||||
// store.update(state => {
|
||||
// state.pages.componentLibraries = state.pages.componentLibraries.filter(l => l !== lib);
|
||||
// _savePage(state);
|
||||
|
||||
return state;
|
||||
})
|
||||
}
|
||||
// return state;
|
||||
// })
|
||||
// }
|
||||
|
||||
const addStylesheet = store => stylesheet => {
|
||||
store.update(s => {
|
||||
|
|
|
@ -1,123 +0,0 @@
|
|||
<script>
|
||||
import { cloneDeep, map, some, filter } from "lodash/fp"
|
||||
import Textbox from "../common/Textbox.svelte"
|
||||
import Checkbox from "../common/Checkbox.svelte"
|
||||
import ButtonGroup from "../common/ButtonGroup.svelte"
|
||||
import Button from "../common/Button.svelte"
|
||||
import ActionButton from "../common/ActionButton.svelte"
|
||||
import { validateAccessLevels, nodeNameFromNodeKey } from "../common/core"
|
||||
import ErrorsBox from "../common/ErrorsBox.svelte"
|
||||
|
||||
export let level
|
||||
export let allPermissions
|
||||
export let onFinished
|
||||
export let isNew
|
||||
export let allLevels
|
||||
export let hierarchy
|
||||
export let actions
|
||||
export let close
|
||||
export let title
|
||||
|
||||
let errors = []
|
||||
let clonedLevel = cloneDeep(level)
|
||||
|
||||
const matchPermissions = (p1, p2) =>
|
||||
p1.type === p2.type &&
|
||||
((!p2.nodeKey && !p1.nodeKey) || p2.nodeKey === p1.nodeKey)
|
||||
|
||||
const hasPermission = hasPerm =>
|
||||
clonedLevel.permissions.some(permission =>
|
||||
matchPermissions(permission, hasPerm)
|
||||
)
|
||||
|
||||
$: permissionMatrix = allPermissions.map(permission => ({
|
||||
permission,
|
||||
hasPermission: hasPermission(permission),
|
||||
}))
|
||||
|
||||
$: allPermissionsSelected = permissionMatrix.every(
|
||||
permission => permission.hasPermission
|
||||
)
|
||||
|
||||
const getPermissionName = perm =>
|
||||
perm.nodeKey
|
||||
? `${perm.type} - ${nodeNameFromNodeKey(hierarchy, perm.nodeKey)}`
|
||||
: perm.type
|
||||
|
||||
const save = () => {
|
||||
const newLevels = isNew
|
||||
? [...allLevels, clonedLevel]
|
||||
: [...allLevels.filter(l => l.name !== level.name), clonedLevel]
|
||||
|
||||
errors = validateAccessLevels(hierarchy, actions, newLevels)
|
||||
|
||||
if (errors.length > 0) return
|
||||
|
||||
onFinished(clonedLevel)
|
||||
close()
|
||||
}
|
||||
|
||||
const permissionChanged = perm => ev => {
|
||||
const hasPermission = ev.target.checked
|
||||
|
||||
if (hasPermission) {
|
||||
clonedLevel.permissions.push(perm)
|
||||
} else {
|
||||
clonedLevel.permissions = filter(p => !matchPermissions(p, perm))(
|
||||
clonedLevel.permissions
|
||||
)
|
||||
}
|
||||
allPermissions = allPermissions
|
||||
}
|
||||
</script>
|
||||
|
||||
<div>
|
||||
|
||||
<div class="uk-modal-header">
|
||||
<h4 class="budibase__title--4">{title}</h4>
|
||||
</div>
|
||||
|
||||
<ErrorsBox {errors} />
|
||||
|
||||
<form on:submit|preventDefault class="uk-form-horizontal">
|
||||
|
||||
<Textbox label="Access Level Name" bind:text={clonedLevel.name} />
|
||||
|
||||
<h4 class="budibase__title--4">Permissions</h4>
|
||||
|
||||
<Checkbox
|
||||
label={'Select All'}
|
||||
checked={allPermissionsSelected}
|
||||
on:change={ev => {
|
||||
permissionMatrix.forEach(permission =>
|
||||
permissionChanged(permission.permission)(ev)
|
||||
)
|
||||
}} />
|
||||
{#each permissionMatrix as permission}
|
||||
<div class="permission-container">
|
||||
<Checkbox
|
||||
label={getPermissionName(permission.permission)}
|
||||
checked={permission.hasPermission}
|
||||
on:change={permissionChanged(permission.permission)} />
|
||||
</div>
|
||||
{/each}
|
||||
|
||||
</form>
|
||||
|
||||
<div class="uk-modal-footer uk-text-right">
|
||||
<ButtonGroup>
|
||||
<ActionButton primary grouped on:click={save}>Save</ActionButton>
|
||||
<ActionButton alert grouped on:click={() => onFinished()}>
|
||||
Cancel
|
||||
</ActionButton>
|
||||
</ButtonGroup>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.permission-container {
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
</style>
|
|
@ -1,132 +1,5 @@
|
|||
import {
|
||||
hierarchy as hierarchyFunctions,
|
||||
common,
|
||||
getTemplateApi,
|
||||
getAuthApi,
|
||||
} from "../../../../core/src"
|
||||
import { _getNew } from "../../../../core/src/recordApi/getNew"
|
||||
import { find, filter, keyBy, flatten, map } from "lodash/fp"
|
||||
import { generateSchema } from "../../../../core/src/indexing/indexSchemaCreator"
|
||||
import { generate } from "shortid"
|
||||
import { common } from "../../../../core/src"
|
||||
|
||||
export { canDeleteIndex } from "../../../../core/src/templateApi/canDeleteIndex"
|
||||
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"
|
||||
export const pipe = common.$
|
||||
|
||||
export const events = common.eventsList
|
||||
|
||||
export const getNode = (hierarchy, nodeId) =>
|
||||
pipe(hierarchy, [
|
||||
hierarchyFunctions.getFlattenedHierarchy,
|
||||
find(n => n.nodeId === nodeId || n.nodeKey() === nodeId),
|
||||
])
|
||||
|
||||
export const constructHierarchy = node => {
|
||||
if (!node) return node
|
||||
return templateApi(node).constructHierarchy(node)
|
||||
}
|
||||
|
||||
export const createNewHierarchy = () => {
|
||||
return templateApi().getNewRootLevel()
|
||||
}
|
||||
|
||||
export const templateApi = hierarchy => getTemplateApi({ hierarchy })
|
||||
export const authApi = (hierarchy, actions) =>
|
||||
getAuthApi({
|
||||
hierarchy,
|
||||
actions: keyBy("name")(actions),
|
||||
publish: () => { },
|
||||
})
|
||||
|
||||
export const allTypes = templateApi({}).allTypes
|
||||
|
||||
export const validate = {
|
||||
all: templateApi({}).validateAll,
|
||||
node: templateApi({}).validateNode,
|
||||
field: templateApi({}).validateField,
|
||||
}
|
||||
|
||||
export const getPotentialReverseReferenceIndexes = (hierarchy, refIndex) => {
|
||||
const res = pipe(hierarchy, [
|
||||
hierarchyFunctions.getFlattenedHierarchy,
|
||||
filter(
|
||||
n =>
|
||||
hierarchyFunctions.isAncestor(refIndex)(n) ||
|
||||
hierarchyFunctions.isAncestor(refIndex)(n.parent())
|
||||
),
|
||||
map(n => n.indexes),
|
||||
flatten,
|
||||
filter(hierarchyFunctions.isReferenceIndex),
|
||||
])
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
export const getPotentialReferenceIndexes = (hierarchy, model) =>
|
||||
pipe(hierarchy, [
|
||||
hierarchyFunctions.getFlattenedHierarchy,
|
||||
filter(hierarchyFunctions.isAncestorIndex),
|
||||
filter(
|
||||
i =>
|
||||
hierarchyFunctions.isAncestor(model)(i.parent()) ||
|
||||
i.parent().nodeId === model.parent().nodeId ||
|
||||
hierarchyFunctions.isRoot(i.parent())
|
||||
),
|
||||
])
|
||||
|
||||
export const isIndex = hierarchyFunctions.isIndex
|
||||
export const isModel = hierarchyFunctions.isModel
|
||||
export const nodeNameFromNodeKey = hierarchyFunctions.nodeNameFromNodeKey
|
||||
|
||||
export const getDefaultTypeOptions = type =>
|
||||
!type ? {} : allTypes[type].getDefaultOptions()
|
||||
|
||||
export const getNewAction = () => templateApi({}).createAction()
|
||||
export const getNewTrigger = () => templateApi({}).createTrigger()
|
||||
|
||||
export const validateActions = actions =>
|
||||
templateApi({}).validateActions(actions)
|
||||
export const validateTriggers = (triggers, actions) =>
|
||||
templateApi({}).validateTriggers(triggers, actions)
|
||||
|
||||
export const generateFullPermissions = (hierarchy, actions) =>
|
||||
authApi(hierarchy, actions).generateFullPermissions()
|
||||
|
||||
export const getNewAccessLevel = () => authApi().getNewAccessLevel()
|
||||
|
||||
export const validateAccessLevels = (hierarchy, actions, accessLevels) =>
|
||||
authApi(hierarchy, actions).validateAccessLevels(accessLevels)
|
||||
|
||||
export const getIndexNodes = hierarchy =>
|
||||
pipe(hierarchy, [
|
||||
hierarchyFunctions.getFlattenedHierarchy,
|
||||
filter(hierarchyFunctions.isIndex),
|
||||
])
|
||||
|
||||
export const getRecordNodes = hierarchy =>
|
||||
pipe(hierarchy, [
|
||||
hierarchyFunctions.getFlattenedHierarchy,
|
||||
filter(hierarchyFunctions.isModel),
|
||||
])
|
||||
|
||||
export const getIndexSchema = hierarchy => index =>
|
||||
generateSchema(hierarchy, index)
|
||||
|
||||
export const getNewRecord = _getNew
|
||||
|
||||
export const getNewInstance = (appId, name) => {
|
||||
const id = `2-${generate()}`
|
||||
return {
|
||||
key: `/applications/${appId}/instances/${id}`,
|
||||
active: true,
|
||||
version: { key: "" },
|
||||
isNew: true,
|
||||
type: "instance",
|
||||
datastoreconfig: "",
|
||||
id,
|
||||
name,
|
||||
}
|
||||
}
|
||||
export const events = common.eventsList
|
|
@ -13,7 +13,6 @@
|
|||
import {
|
||||
allTypes,
|
||||
validate,
|
||||
getDefaultTypeOptions,
|
||||
} from "components/common/core"
|
||||
|
||||
const FIELD_TYPES = ["string", "number", "boolean"]
|
||||
|
|
|
@ -61,10 +61,6 @@
|
|||
|
||||
</div>
|
||||
{/if}
|
||||
<NavItem
|
||||
name="ACCESS_LEVELS"
|
||||
label="User Access Levels"
|
||||
href="./accesslevels" />
|
||||
</div>
|
||||
|
||||
<style>
|
||||
|
|
|
@ -13,12 +13,7 @@
|
|||
flatten,
|
||||
} from "lodash/fp"
|
||||
|
||||
import {
|
||||
getRecordNodes,
|
||||
getIndexNodes,
|
||||
getIndexSchema,
|
||||
pipe,
|
||||
} from "components/common/core"
|
||||
import { pipe } from "components/common/core"
|
||||
|
||||
import Tab from "./ItemTab/Tab.svelte"
|
||||
import { store } from "builderStore"
|
||||
|
@ -34,26 +29,26 @@
|
|||
const categories = components.categories
|
||||
let selectedCategory = categories[0]
|
||||
|
||||
const onTemplateChosen = template => {
|
||||
selectedComponent = null
|
||||
const { componentName, libName } = splitName(template.name)
|
||||
const templateOptions = {
|
||||
records: getRecordNodes(hierarchy),
|
||||
indexes: getIndexNodes(hierarchy),
|
||||
helpers: {
|
||||
indexSchema: getIndexSchema(hierarchy),
|
||||
},
|
||||
}
|
||||
// const onTemplateChosen = template => {
|
||||
// selectedComponent = null
|
||||
// const { componentName, libName } = splitName(template.name)
|
||||
// const templateOptions = {
|
||||
// records: getRecordNodes(hierarchy),
|
||||
// indexes: getIndexNodes(hierarchy),
|
||||
// helpers: {
|
||||
// indexSchema: getIndexSchema(hierarchy),
|
||||
// },
|
||||
// }
|
||||
|
||||
templateInstances = libraryModules[libName][componentName](templateOptions)
|
||||
if (!templateInstances || templateInstances.length === 0) return
|
||||
selectedTemplateInstance = templateInstances[0].name
|
||||
selectTemplateDialog.show()
|
||||
}
|
||||
// templateInstances = libraryModules[libName][componentName](templateOptions)
|
||||
// if (!templateInstances || templateInstances.length === 0) return
|
||||
// selectedTemplateInstance = templateInstances[0].name
|
||||
// selectTemplateDialog.show()
|
||||
// }
|
||||
|
||||
const onComponentChosen = component => {
|
||||
if (component.template) {
|
||||
onTemplateChosen(component.template)
|
||||
// onTemplateChosen(component.template)
|
||||
} else {
|
||||
store.addChildComponent(component._component)
|
||||
toggleTab()
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
<script>
|
||||
import { last } from "lodash/fp"
|
||||
import { pipe } from "../common/core"
|
||||
import { last, pipe } from "lodash/fp"
|
||||
import {
|
||||
XCircleIcon,
|
||||
ChevronUpIcon,
|
||||
|
|
|
@ -68,10 +68,6 @@
|
|||
appRootPath: `/_builder/instance/${$store.appname}/${$backendUiStore.selectedDatabase.id}/`,
|
||||
}
|
||||
|
||||
$: backendDefinition = {
|
||||
hierarchy: $store.hierarchy,
|
||||
}
|
||||
|
||||
$: selectedComponentId = $store.currentComponentInfo ? $store.currentComponentInfo._id : ""
|
||||
</script>
|
||||
|
||||
|
@ -112,7 +108,6 @@
|
|||
<\/style>
|
||||
<\script>
|
||||
window["##BUDIBASE_FRONTEND_DEFINITION##"] = ${JSON.stringify(frontendDefinition)};
|
||||
window["##BUDIBASE_BACKEND_DEFINITION##"] = ${JSON.stringify(backendDefinition)};
|
||||
window["##BUDIBASE_FRONTEND_FUNCTIONS##"] = ${$store.currentPageFunctions};
|
||||
|
||||
import('/_builder/budibase-client.esm.mjs')
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
import StateBindingCascader from "./StateBindingCascader.svelte"
|
||||
import StateBindingControl from "../StateBindingControl.svelte"
|
||||
import { find, map, keys, reduce, keyBy } from "lodash/fp"
|
||||
import { pipe, userWithFullAccess } from "components/common/core"
|
||||
import { pipe } from "components/common/core"
|
||||
import {
|
||||
EVENT_TYPE_MEMBER_NAME,
|
||||
allHandlers,
|
||||
|
@ -26,10 +26,11 @@
|
|||
|
||||
$: eventOptions = allHandlers(
|
||||
{ hierarchy: $store.hierarchy },
|
||||
userWithFullAccess({
|
||||
hierarchy: $store.hierarchy,
|
||||
actions: keyBy("name")($store.actions),
|
||||
})
|
||||
{}
|
||||
// userWithFullAccess({
|
||||
// hierarchy: $store.hierarchy,
|
||||
// actions: keyBy("name")($store.actions),
|
||||
// })
|
||||
)
|
||||
|
||||
$: {
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
import Input from "components/common/Input.svelte"
|
||||
import StateBindingControl from "../StateBindingControl.svelte"
|
||||
import { find, map, keys, reduce, keyBy } from "lodash/fp"
|
||||
import { pipe, userWithFullAccess } from "components/common/core"
|
||||
import { pipe } from "components/common/core"
|
||||
import {
|
||||
EVENT_TYPE_MEMBER_NAME,
|
||||
allHandlers,
|
||||
|
|
|
@ -1,335 +0,0 @@
|
|||
<script>
|
||||
import { splitName } from "./pagesParsing/splitRootComponentName.js"
|
||||
import { store } from "builderStore"
|
||||
import {
|
||||
find,
|
||||
sortBy,
|
||||
groupBy,
|
||||
values,
|
||||
filter,
|
||||
map,
|
||||
uniqBy,
|
||||
flatten,
|
||||
} from "lodash/fp"
|
||||
import { ImageIcon, InputIcon, LayoutIcon } from "components/common/Icons/"
|
||||
import Select from "components/common/Select.svelte"
|
||||
import Button from "components/common/PlusButton.svelte"
|
||||
import ConfirmDialog from "components/common/ConfirmDialog.svelte"
|
||||
import {
|
||||
getRecordNodes,
|
||||
getIndexNodes,
|
||||
getIndexSchema,
|
||||
pipe,
|
||||
} from "components/common/core"
|
||||
|
||||
export let toggleTab
|
||||
|
||||
let componentLibraries = []
|
||||
let current_view = "text"
|
||||
let selectedComponent = null
|
||||
let selectedLib
|
||||
let selectTemplateDialog
|
||||
let templateInstances = []
|
||||
let selectedTemplateInstance
|
||||
|
||||
//Info: Components seem to be generated from individual templates. Will this be the same going forward
|
||||
$: templatesByComponent = groupBy(t => t.component)($store.templates)
|
||||
$: hierarchy = $store.hierarchy
|
||||
$: libraryModules = $store.libraries
|
||||
$: standaloneTemplates = pipe(
|
||||
templatesByComponent,
|
||||
[
|
||||
values,
|
||||
flatten,
|
||||
filter(t => !$store.components.some(c => c.name === t.component)),
|
||||
map(t => ({ name: splitName(t.component).componentName, template: t })),
|
||||
uniqBy(t => t.name),
|
||||
]
|
||||
)
|
||||
|
||||
const addRootComponent = (component, allComponents) => {
|
||||
const { libName } = splitName(component.name)
|
||||
let group = find(r => r.libName === libName)(allComponents)
|
||||
|
||||
if (!group) {
|
||||
group = {
|
||||
libName,
|
||||
components: [],
|
||||
}
|
||||
|
||||
allComponents.push(group)
|
||||
}
|
||||
|
||||
group.components.push(component)
|
||||
}
|
||||
|
||||
const onComponentChosen = component => {
|
||||
if (component.template) {
|
||||
onTemplateChosen(component.template)
|
||||
} else {
|
||||
store.addChildComponent(component.name)
|
||||
toggleTab()
|
||||
}
|
||||
}
|
||||
|
||||
//Info: Called from menu beside components with presets and templates
|
||||
const onTemplateChosen = template => {
|
||||
selectedComponent = null
|
||||
const { componentName, libName } = splitName(template.name)
|
||||
//Info: how will DB changes effect this?
|
||||
const templateOptions = {
|
||||
records: getRecordNodes(hierarchy),
|
||||
indexes: getIndexNodes(hierarchy),
|
||||
helpers: {
|
||||
indexSchema: getIndexSchema(hierarchy),
|
||||
},
|
||||
}
|
||||
//Info: go off and get template instances by library and component name
|
||||
//libraryModules and hierarchies (used above) come from builderStore
|
||||
templateInstances = libraryModules[libName][componentName](templateOptions)
|
||||
if (!templateInstances || templateInstances.length === 0) return
|
||||
selectedTemplateInstance = templateInstances[0].name
|
||||
selectTemplateDialog.show()
|
||||
}
|
||||
|
||||
const onTemplateInstanceChosen = () => {
|
||||
selectedComponent = null
|
||||
const instance = templateInstances.find(
|
||||
i => i.name === selectedTemplateInstance
|
||||
)
|
||||
debugger
|
||||
store.addTemplatedComponent(instance.props)
|
||||
toggleTab()
|
||||
}
|
||||
|
||||
function generate_components_list(components) {
|
||||
debugger
|
||||
return ($store.currentFrontEndType === "page"
|
||||
? $store.builtins.concat(components)
|
||||
: components
|
||||
).concat(standaloneTemplates)
|
||||
}
|
||||
|
||||
$: {
|
||||
const newComponentLibraries = []
|
||||
|
||||
for (let comp of sortBy(["name"])($store.components)) {
|
||||
addRootComponent(comp, newComponentLibraries)
|
||||
}
|
||||
|
||||
componentLibraries = newComponentLibraries
|
||||
if (!selectedLib) selectedLib = newComponentLibraries[0].libName
|
||||
}
|
||||
|
||||
$: componentLibrary = componentLibraries.find(l => l.libName === selectedLib)
|
||||
</script>
|
||||
|
||||
<div class="root">
|
||||
<Select on:change={e => (selectedLib = e.target.value)}>
|
||||
{#each componentLibraries as lib}
|
||||
<option value={lib.libName}>{lib.libName}</option>
|
||||
{/each}
|
||||
</Select>
|
||||
|
||||
<div class="library-container">
|
||||
<!-- <ul>
|
||||
<li>
|
||||
<button
|
||||
class:selected={current_view === 'text'}
|
||||
on:click={() => (current_view = 'text')}>
|
||||
<InputIcon />
|
||||
</button>
|
||||
</li>
|
||||
<li>
|
||||
<button
|
||||
class:selected={current_view === 'layout'}
|
||||
on:click={() => (current_view = 'layout')}>
|
||||
<LayoutIcon />
|
||||
</button>
|
||||
</li>
|
||||
<li>
|
||||
<button
|
||||
class:selected={current_view === 'media'}
|
||||
on:click={() => (current_view = 'media')}>
|
||||
<ImageIcon />
|
||||
</button>
|
||||
</li>
|
||||
</ul> -->
|
||||
|
||||
{#if componentLibrary}
|
||||
{#each generate_components_list(componentLibrary.components) as component}
|
||||
<div class="component-container">
|
||||
<div class="component" on:click={() => onComponentChosen(component)}>
|
||||
<div class="name">{splitName(component.name).componentName}</div>
|
||||
{#if (component.presets || templatesByComponent[component.name]) && component.name === selectedComponent}
|
||||
<ul class="preset-menu">
|
||||
{#if component.presets}
|
||||
<span>{splitName(component.name).componentName} Presets</span>
|
||||
{#each Object.keys(component.presets) as preset}
|
||||
<li
|
||||
on:click|stopPropagation={() => onComponentChosen(component, preset)}>
|
||||
{preset}
|
||||
</li>
|
||||
{/each}
|
||||
{/if}
|
||||
{#if templatesByComponent[component.name]}
|
||||
<span>
|
||||
{splitName(component.name).componentName} Templates
|
||||
</span>
|
||||
{#each templatesByComponent[component.name] as template}
|
||||
<li
|
||||
on:click|stopPropagation={() => onTemplateChosen(template)}>
|
||||
{template.description}
|
||||
</li>
|
||||
{/each}
|
||||
{/if}
|
||||
</ul>
|
||||
{/if}
|
||||
</div>
|
||||
{#if component.presets || templatesByComponent[component.name]}
|
||||
<Button
|
||||
on:click={() => {
|
||||
selectedComponent = selectedComponent ? null : component.name
|
||||
}}>
|
||||
<span
|
||||
class="open-presets"
|
||||
class:open={selectedComponent === component.name}>
|
||||
...
|
||||
</span>
|
||||
</Button>
|
||||
{/if}
|
||||
</div>
|
||||
{/each}
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<ConfirmDialog
|
||||
bind:this={selectTemplateDialog}
|
||||
title="Choose Template"
|
||||
onCancel={() => (selectedComponent = null)}
|
||||
onOk={onTemplateInstanceChosen}>
|
||||
{#each templateInstances.map(i => i.name) as instance}
|
||||
<div class="uk-margin uk-grid-small uk-child-width-auto uk-grid">
|
||||
<label>
|
||||
<input
|
||||
class="uk-radio"
|
||||
type="radio"
|
||||
bind:group={selectedTemplateInstance}
|
||||
value={instance} />
|
||||
<span class="template-instance-label">{instance}</span>
|
||||
</label>
|
||||
</div>
|
||||
{/each}
|
||||
</ConfirmDialog>
|
||||
|
||||
<style>
|
||||
.root {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.library-container {
|
||||
padding: 0 0 10px 0;
|
||||
flex: 1 1 auto;
|
||||
min-height: 0px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.component-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.component {
|
||||
position: relative;
|
||||
padding: 0 15px;
|
||||
cursor: pointer;
|
||||
border: 1px solid #d8d8d8;
|
||||
border-radius: 2px;
|
||||
margin: 5px 0;
|
||||
height: 40px;
|
||||
box-sizing: border-box;
|
||||
color: #000333;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex: 1;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.component:hover {
|
||||
background-color: var(--lightslate);
|
||||
}
|
||||
|
||||
.component > .name {
|
||||
color: #000333;
|
||||
display: inline-block;
|
||||
font-size: 13px;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style: none;
|
||||
display: flex;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.preset-menu {
|
||||
flex-direction: column;
|
||||
position: absolute;
|
||||
top: 25px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 1;
|
||||
background: #fafafa;
|
||||
padding: 10px;
|
||||
border-radius: 2px;
|
||||
color: var(--secondary80);
|
||||
}
|
||||
|
||||
.preset-menu > span {
|
||||
font-size: 13px;
|
||||
text-transform: uppercase;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.preset-menu li {
|
||||
font-size: 14px;
|
||||
margin-top: 13px;
|
||||
}
|
||||
|
||||
.preset-menu li:hover {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
li {
|
||||
margin-right: 20px;
|
||||
background: none;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
/* li button {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: none;
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
padding: 13px;
|
||||
outline: none;
|
||||
cursor: pointer;
|
||||
} */
|
||||
|
||||
/* .selected {
|
||||
color: var(--button-text);
|
||||
background: var(--background-button) !important;
|
||||
} */
|
||||
|
||||
.open {
|
||||
color: rgba(0, 85, 255, 1);
|
||||
}
|
||||
|
||||
.template-instance-label {
|
||||
margin-left: 20px;
|
||||
}
|
||||
</style>
|
|
@ -1,134 +0,0 @@
|
|||
<script>
|
||||
import { store } from "builderStore"
|
||||
import Textbox from "components/common/Textbox.svelte"
|
||||
import Button from "components/common/Button.svelte"
|
||||
import IconButton from "components/common/IconButton.svelte"
|
||||
import { libraryDependencies } from "./pagesParsing/findDependencies"
|
||||
import UIkit from "uikit"
|
||||
import { libsFromPages } from "builderStore/loadComponentLibraries"
|
||||
let addNewLib = ""
|
||||
let addNewStylesheet = ""
|
||||
let modalElement
|
||||
|
||||
$: components = $store.components
|
||||
|
||||
const removeLibrary = lib => {
|
||||
const dependencies = libraryDependencies(components, lib)
|
||||
if (dependencies.length > 0) return
|
||||
store.removeComponentLibrary(lib)
|
||||
}
|
||||
|
||||
const addLib = () => {
|
||||
store.addComponentLibrary(addNewLib).then(() => {
|
||||
addNewLib = ""
|
||||
})
|
||||
}
|
||||
|
||||
const removeStylesheet = stylesheet => {
|
||||
store.removeStylesheet(stylesheet)
|
||||
}
|
||||
|
||||
const addStylesheet = () => {
|
||||
if (addNewStylesheet) store.addStylesheet(addNewStylesheet)
|
||||
}
|
||||
|
||||
export const close = () => {
|
||||
UIkit.modal(modalElement).hide()
|
||||
}
|
||||
|
||||
export const show = () => {
|
||||
UIkit.modal(modalElement).show()
|
||||
}
|
||||
</script>
|
||||
|
||||
<div bind:this={modalElement} id="new-component-modal" uk-modal>
|
||||
<div class="uk-modal-dialog">
|
||||
|
||||
<div class="uk-modal-header header">
|
||||
<div>Settings</div>
|
||||
<div>
|
||||
<IconButton icon="x" on:click={close} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="uk-modal-body uk-form-horizontal">
|
||||
|
||||
<div class="section-container">
|
||||
<p>
|
||||
Component Libraries
|
||||
<span>
|
||||
<input bind:value={addNewLib} />
|
||||
<Button color="primary-outline" on:click={addLib}>Add</Button>
|
||||
</span>
|
||||
</p>
|
||||
{#each $store.pages[$store.currentPageName].componentLibraries as lib}
|
||||
<div>
|
||||
<span class="row-text">{lib}</span>
|
||||
<IconButton icon="x" on:click={() => removeLibrary(lib)} />
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
<div class="section-container">
|
||||
<p>
|
||||
Stylesheets
|
||||
<span>
|
||||
<input bind:value={addNewStylesheet} />
|
||||
<Button color="primary-outline" on:click={addStylesheet}>
|
||||
Add
|
||||
</Button>
|
||||
</span>
|
||||
</p>
|
||||
{#each $store.pages[$store.currentPageName].stylesheets as stylesheet}
|
||||
<div>
|
||||
<span class="row-text">{stylesheet}</span>
|
||||
<IconButton
|
||||
icon="x"
|
||||
on:click={() => removeStylesheet(stylesheet)} />
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.section-container {
|
||||
padding: 15px;
|
||||
border-style: dotted;
|
||||
border-width: 1px;
|
||||
border-color: var(--lightslate);
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.section-container:nth-child(1) {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.row-text {
|
||||
margin-right: 15px;
|
||||
color: var(--primary100);
|
||||
}
|
||||
|
||||
input {
|
||||
margin-right: 15px;
|
||||
}
|
||||
|
||||
p > span {
|
||||
margin-left: 30px;
|
||||
}
|
||||
|
||||
.header {
|
||||
display: grid;
|
||||
grid-template-columns: [title] 1fr [icon] auto;
|
||||
}
|
||||
|
||||
.header > div:nth-child(1) {
|
||||
grid-column-start: title;
|
||||
}
|
||||
|
||||
.header > div:nth-child(2) {
|
||||
grid-column-start: icon;
|
||||
}
|
||||
</style>
|
|
@ -7,7 +7,6 @@
|
|||
import IconButton from "components/common/IconButton.svelte"
|
||||
import NewScreen from "./NewScreen.svelte"
|
||||
import CurrentItemPreview from "./CurrentItemPreview.svelte"
|
||||
import SettingsView from "./SettingsView.svelte"
|
||||
import PageView from "./PageView.svelte"
|
||||
import ComponentsPaneSwitcher from "./ComponentsPaneSwitcher.svelte"
|
||||
import ConfirmDialog from "components/common/ConfirmDialog.svelte"
|
||||
|
@ -22,11 +21,6 @@
|
|||
newScreenPicker.show()
|
||||
}
|
||||
|
||||
let settingsView
|
||||
const settings = () => {
|
||||
settingsView.show()
|
||||
}
|
||||
|
||||
const confirmDeleteComponent = component => {
|
||||
componentToDelete = component
|
||||
confirmDeleteDialog.show()
|
||||
|
@ -89,7 +83,6 @@
|
|||
</div>
|
||||
|
||||
<NewScreen bind:this={newScreenPicker} />
|
||||
<SettingsView bind:this={settingsView} />
|
||||
|
||||
<ConfirmDialog
|
||||
bind:this={confirmDeleteDialog}
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
import { pipe } from "../../common/core"
|
||||
|
||||
import { find, isUndefined, filter, some, includes } from "lodash/fp"
|
||||
import { find, isUndefined, filter, some, includes, pipe } from "lodash/fp"
|
||||
|
||||
const normalString = s => (s || "").trim().toLowerCase()
|
||||
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
import { split, last } from "lodash/fp"
|
||||
|
||||
import { pipe } from "../../common/core"
|
||||
import { split, last, pipe } from "lodash/fp"
|
||||
|
||||
export const splitName = fullname => {
|
||||
const componentName = pipe(fullname, [split("/"), last])
|
||||
|
|
|
@ -1,100 +0,0 @@
|
|||
<script>
|
||||
import { getContext } from "svelte"
|
||||
const { open, close } = getContext("simple-modal")
|
||||
|
||||
import ButtonGroup from "components/common/ButtonGroup.svelte"
|
||||
import Button from "components/common/Button.svelte"
|
||||
import ActionButton from "components/common/ActionButton.svelte"
|
||||
import { store, backendUiStore } from "builderStore"
|
||||
import {
|
||||
generateFullPermissions,
|
||||
getNewAccessLevel,
|
||||
} from "components/common/core"
|
||||
import getIcon from "components/common/icon"
|
||||
import AccessLevelView from "components/accessLevels/AccessLevelView.svelte"
|
||||
|
||||
let editingLevel = null
|
||||
let editingLevelIsNew = false
|
||||
let allPermissions = []
|
||||
store.subscribe(db => {
|
||||
allPermissions = generateFullPermissions(db.hierarchy, db.actions)
|
||||
})
|
||||
|
||||
const openModal = (level, newLevel) => {
|
||||
editingLevel = level
|
||||
editingLevelIsNew = newLevel
|
||||
open(AccessLevelView, {
|
||||
level: editingLevel,
|
||||
allPermissions,
|
||||
onFinished: onEditingFinished,
|
||||
isNew: editingLevelIsNew,
|
||||
allLevels: $store.accessLevels.levels,
|
||||
hierarchy: $store.hierarchy,
|
||||
actions: $store.actions,
|
||||
close: close,
|
||||
title: "Access Level",
|
||||
})
|
||||
}
|
||||
|
||||
let cancel = () => {
|
||||
editingAction = null
|
||||
close()
|
||||
}
|
||||
|
||||
let onEditingFinished = level => {
|
||||
if (level) {
|
||||
store.saveLevel(level, editingLevelIsNew, editingLevel)
|
||||
}
|
||||
editingLevel = null
|
||||
close()
|
||||
}
|
||||
|
||||
const getPermissionsString = perms => {
|
||||
return `${perms.length} / ${allPermissions.length}`
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="root">
|
||||
<ButtonGroup>
|
||||
<ActionButton primary on:click={() => openModal(getNewAccessLevel(), true)}>
|
||||
Create New Access Level
|
||||
</ActionButton>
|
||||
</ButtonGroup>
|
||||
|
||||
{#if $store.accessLevels}
|
||||
<table class="fields-table uk-table uk-table-small">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Permissions</th>
|
||||
<th />
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each $store.accessLevels.levels as level}
|
||||
<tr>
|
||||
<td>{level.name}</td>
|
||||
<td>{getPermissionsString(level.permissions)}</td>
|
||||
<td class="edit-button">
|
||||
<span on:click={() => openModal(level, false)}>
|
||||
{@html getIcon('edit')}
|
||||
</span>
|
||||
<span on:click={() => store.deleteLevel(level)}>
|
||||
{@html getIcon('trash')}
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
{:else}(no actions added){/if}
|
||||
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.root {
|
||||
height: 100%;
|
||||
position: relative;
|
||||
padding: 1.5rem;
|
||||
}
|
||||
</style>
|
|
@ -29,18 +29,6 @@
|
|||
{:catch err}
|
||||
<h1 style="color:red">{err}</h1>
|
||||
{/await}
|
||||
|
||||
<!--
|
||||
<div class="settings">
|
||||
<IconButton icon="settings"
|
||||
on:click={store.showSettings}/>
|
||||
</div>
|
||||
|
||||
|
||||
{#if $store.useAnalytics}
|
||||
<iframe src="https://marblekirby.github.io/bb-analytics.html" width="0" height="0" style="visibility:hidden;display:none"/>
|
||||
{/if}
|
||||
-->
|
||||
</main>
|
||||
|
||||
<style>
|
||||
|
@ -50,12 +38,6 @@
|
|||
font-family: "Roboto", Helvetica, Arial, sans-serif;
|
||||
}
|
||||
|
||||
.settings {
|
||||
position: absolute;
|
||||
bottom: 25px;
|
||||
right: 25px;
|
||||
}
|
||||
|
||||
.spinner-container {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
"chalk": "^2.4.2",
|
||||
"dotenv": "^8.2.0",
|
||||
"fs-extra": "^8.1.0",
|
||||
"glob": "^7.1.6",
|
||||
"inquirer": "^7.0.0",
|
||||
"lodash": "^4.17.15",
|
||||
"squirrelly": "7",
|
||||
|
|
|
@ -8,7 +8,6 @@ module.exports = () => {
|
|||
.command(require("./commands/init"))
|
||||
.command(require("./commands/new"))
|
||||
.command(require("./commands/run"))
|
||||
.command(require("./commands/instance"))
|
||||
.fail((msg, err) => {
|
||||
if (err) {
|
||||
console.log(chalk.red(err.message))
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
const handler = require("./instanceHandler")
|
||||
|
||||
module.exports = {
|
||||
command: "instance <appname> [config]",
|
||||
desc: "Create a new instance for an app",
|
||||
builder: yargs => {
|
||||
yargs.positional("appname", {
|
||||
type: "string",
|
||||
describe: "the name of the app to create an instance",
|
||||
alias: "a",
|
||||
})
|
||||
|
||||
yargs.positional("config", {
|
||||
type: "string",
|
||||
describe:
|
||||
"config file to use. optional, defaults to config.js. Use 'dev' as shorthand for 'config.dev.js' ",
|
||||
alias: "c",
|
||||
default: "config.js",
|
||||
})
|
||||
},
|
||||
handler,
|
||||
}
|
|
@ -1,116 +0,0 @@
|
|||
const inquirer = require("inquirer")
|
||||
const { readJSON } = require("fs-extra")
|
||||
const { join } = require("path")
|
||||
const chalk = require("chalk")
|
||||
const fp = require("lodash/fp")
|
||||
const { getAppContext } = require("../../common")
|
||||
const passwordQuestion = require("@inquirer/password")
|
||||
|
||||
module.exports = opts => {
|
||||
run(opts)
|
||||
}
|
||||
|
||||
const run = async opts => {
|
||||
try {
|
||||
const appContext = await getAppContext({
|
||||
configName: opts.config,
|
||||
masterIsCreated: true,
|
||||
})
|
||||
opts.appContext = appContext
|
||||
opts.datapath = "./.data"
|
||||
await fetchUserLevels(opts)
|
||||
await prompts(opts)
|
||||
await createInstance(opts)
|
||||
console.log(
|
||||
chalk.green(`Budibase instance created for app ${opts.appname}.`)
|
||||
)
|
||||
} catch (error) {
|
||||
console.error(
|
||||
chalk.red(
|
||||
`Error creating instance of app ${opts.appname}: ${error.message}`
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const fetchUserLevels = async opts => {
|
||||
const accessLevels = await readJSON(
|
||||
join(
|
||||
opts.appContext.config.latestPackagesFolder || ".",
|
||||
opts.appname,
|
||||
"access_levels.json"
|
||||
)
|
||||
)
|
||||
|
||||
if (accessLevels.levels.length === 0)
|
||||
throw new Error("No access levels. Use the builder to create one")
|
||||
|
||||
opts.accessLevels = accessLevels.levels
|
||||
}
|
||||
|
||||
const prompts = async opts => {
|
||||
const questions = [
|
||||
{
|
||||
type: "input",
|
||||
name: "username",
|
||||
message: "Username: ",
|
||||
validate: function(value) {
|
||||
return !!value || "Please enter a username"
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
if (opts.accessLevels.length === 1) {
|
||||
opts.userAccessLevel = opts.accessLevels[0].name
|
||||
} else {
|
||||
questions.push({
|
||||
type: "input",
|
||||
name: "userAccessLevel",
|
||||
message: `Access Level [${fp.join(", ")(
|
||||
opts.accessLevels.map(l => l.name)
|
||||
)}]: `,
|
||||
choices: opts.accessLevels.map(l => l.name),
|
||||
})
|
||||
}
|
||||
|
||||
const answers = await inquirer.prompt(questions)
|
||||
const password = await passwordQuestion({
|
||||
message: "Password for Admin: ",
|
||||
mask: "*",
|
||||
})
|
||||
const passwordConfirm = await passwordQuestion({
|
||||
message: "Confirm Password: ",
|
||||
mask: "*",
|
||||
})
|
||||
|
||||
if (password !== passwordConfirm) throw new Error("Passwords do not match!")
|
||||
|
||||
opts.username = answers.username
|
||||
opts.password = password
|
||||
if (opts.accessLevels.length > 1) {
|
||||
opts.userAccessLevel = answers.userAccessLevel
|
||||
}
|
||||
}
|
||||
|
||||
const createInstance = async opts => {
|
||||
const bb = opts.appContext.master.bbMaster
|
||||
|
||||
const app = await opts.appContext.master.getApplication(opts.appname)
|
||||
const instance = bb.recordApi.getNew(`${app.key}/instances`, "instance")
|
||||
instance.name = "dev instance"
|
||||
instance.active = true
|
||||
instance.version = { key: "" }
|
||||
|
||||
const user = bb.authApi.getNewUser()
|
||||
user.accessLevels.push(opts.userAccessLevel)
|
||||
user.name = opts.username
|
||||
|
||||
await bb.recordApi.save(instance)
|
||||
const savedInstance = await bb.recordApi.load(instance.key)
|
||||
await opts.appContext.master.createAppUser(
|
||||
opts.appname,
|
||||
savedInstance,
|
||||
user,
|
||||
opts.password
|
||||
)
|
||||
}
|
|
@ -1,11 +1,12 @@
|
|||
const { xPlatHomeDir } = require("../../common")
|
||||
const dotenv = require("dotenv")
|
||||
const createInstance = require("@budibase/server/middleware/controllers/instance").create
|
||||
const createApplication = require("@budibase/server/middleware/controllers/application").create
|
||||
const createInstance = require("@budibase/server/api/controllers/instance").create
|
||||
const createApplication = require("@budibase/server/api/controllers/application").create
|
||||
const { copy, readJSON, writeJSON, remove, exists } = require("fs-extra")
|
||||
const { resolve, join } = require("path")
|
||||
const chalk = require("chalk")
|
||||
const { exec } = require("child_process")
|
||||
const glob = require("glob");
|
||||
|
||||
module.exports = opts => {
|
||||
run(opts)
|
||||
|
@ -13,15 +14,20 @@ module.exports = opts => {
|
|||
}
|
||||
|
||||
const run = async opts => {
|
||||
opts.dir = xPlatHomeDir(opts.dir)
|
||||
process.chdir(opts.dir)
|
||||
dotenv.config()
|
||||
await createRecords(opts)
|
||||
await createEmptyAppPackage(opts)
|
||||
exec(`cd ${join(opts.dir, opts.name)} && npm install`)
|
||||
console.log(opts);
|
||||
try {
|
||||
opts.dir = xPlatHomeDir(opts.dir)
|
||||
process.chdir(opts.dir)
|
||||
dotenv.config()
|
||||
await createAppInstance(opts)
|
||||
await createEmptyAppPackage(opts)
|
||||
exec(`cd ${join(opts.dir, opts.applicationId)} && npm install`)
|
||||
} catch (error) {
|
||||
console.error(chalk.red("Error creating new app", error));
|
||||
}
|
||||
}
|
||||
|
||||
const createRecords = async opts => {
|
||||
const createAppInstance = async opts => {
|
||||
const createAppCtx = {
|
||||
params: { clientId: process.env.CLIENT_ID },
|
||||
request: {
|
||||
|
@ -47,14 +53,14 @@ const createEmptyAppPackage = async opts => {
|
|||
const templateFolder = resolve(__dirname, "appDirectoryTemplate")
|
||||
|
||||
const appsFolder = opts.dir
|
||||
const destinationFolder = resolve(appsFolder, opts.applicationId)
|
||||
const newAppFolder = resolve(appsFolder, opts.applicationId)
|
||||
|
||||
if (await exists(destinationFolder)) {
|
||||
if (await exists(newAppFolder)) {
|
||||
console.log(chalk.red(`App ${opts.name} already exists.`))
|
||||
return
|
||||
}
|
||||
|
||||
await copy(templateFolder, destinationFolder)
|
||||
await copy(templateFolder, newAppFolder)
|
||||
|
||||
const packageJsonPath = join(appsFolder, opts.applicationId, "package.json")
|
||||
const packageJson = await readJSON(packageJsonPath)
|
||||
|
@ -64,7 +70,7 @@ const createEmptyAppPackage = async opts => {
|
|||
await writeJSON(packageJsonPath, packageJson)
|
||||
|
||||
const removePlaceholder = async (...args) => {
|
||||
await remove(join(destinationFolder, ...args, "placeholder"))
|
||||
await remove(join(newAppFolder, ...args, "placeholder"))
|
||||
}
|
||||
|
||||
await removePlaceholder("pages", "main", "screens")
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -34,6 +34,8 @@
|
|||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"@budibase/materialdesign-components": "^0.0.32",
|
||||
"@budibase/standard-components": "^0.0.32",
|
||||
"@nx-js/compiler-util": "^2.0.0",
|
||||
"bcryptjs": "^2.4.3",
|
||||
"deep-equal": "^2.0.1",
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
const { readdir, stat, copyFile, ensureDir } = require("fs-extra")
|
||||
const { constants } = require("fs")
|
||||
const { join, basename } = require("path")
|
||||
const serverConfig = require("../../server/config")()
|
||||
|
||||
const packagesFolder = ".."
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import { createApp } from "./createApp"
|
||||
import { trimSlash } from "./common/trimSlash"
|
||||
import { builtins, builtinLibName } from "./render/builtinComponents"
|
||||
import * as standardComponents from "@budibase/standard-components";
|
||||
import * as materialDesignComponents from "@budibase/materialdesign-components";
|
||||
|
||||
/**
|
||||
* create a web application from static budibase definition files.
|
||||
|
@ -11,7 +13,6 @@ export const loadBudibase = async opts => {
|
|||
const _window = (opts && opts.window) || window
|
||||
const _localStorage = (opts && opts.localStorage) || localStorage
|
||||
|
||||
const backendDefinition = _window["##BUDIBASE_BACKEND_DEFINITION##"]
|
||||
const frontendDefinition = _window["##BUDIBASE_FRONTEND_DEFINITION##"]
|
||||
const uiFunctions = _window["##BUDIBASE_FRONTEND_FUNCTIONS##"]
|
||||
|
||||
|
@ -26,22 +27,25 @@ export const loadBudibase = async opts => {
|
|||
temp: false,
|
||||
}
|
||||
|
||||
frontendDefinition.appRootPath =
|
||||
frontendDefinition.appRootPath === ""
|
||||
? ""
|
||||
: "/" + trimSlash(frontendDefinition.appRootPath)
|
||||
const { appRootPath } = frontendDefinition;
|
||||
appRootPath = appRootPath === "" ? "" : "/" + trimSlash(appRootPath)
|
||||
|
||||
if (!componentLibraries) {
|
||||
const componentLibraryUrl = lib =>
|
||||
frontendDefinition.appRootPath + "/" + trimSlash(lib)
|
||||
componentLibraries = {}
|
||||
// if (!componentLibraries) componentLibraries = {};
|
||||
|
||||
for (let lib of frontendDefinition.componentLibraries) {
|
||||
componentLibraries[lib.libName] = await import(
|
||||
componentLibraryUrl(lib.importPath)
|
||||
)
|
||||
}
|
||||
}
|
||||
componentLibraries = {
|
||||
"@budibase/standard-components": standardComponents,
|
||||
"@budibase/materialdesign-components": materialDesignComponents
|
||||
};
|
||||
|
||||
// if (!componentLibraries) {
|
||||
// componentLibraries = {}
|
||||
|
||||
// for (let lib of frontendDefinition.componentLibraries) {
|
||||
// componentLibraries[lib.libName] = await import(
|
||||
// `${frontendDefinition.appRootPath}/${trimSlash(lib.importPath)}`
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
|
||||
componentLibraries[builtinLibName] = builtins(_window)
|
||||
|
||||
|
|
|
@ -32,10 +32,8 @@ const addWindowGlobals = (
|
|||
page,
|
||||
screens,
|
||||
appRootPath,
|
||||
uiFunctions,
|
||||
appDefinition
|
||||
uiFunctions
|
||||
) => {
|
||||
window["##BUDIBASE_BACKEND_DEFINITION##"] = appDefinition
|
||||
window["##BUDIBASE_FRONTEND_DEFINITION##"] = {
|
||||
page,
|
||||
screens,
|
||||
|
@ -99,10 +97,6 @@ const setAppDef = (window, page, screens) => {
|
|||
screens,
|
||||
appRootPath: "",
|
||||
}
|
||||
|
||||
window["##BUDIBASE_BACKEND_DEFINITION##"] = {
|
||||
hierarchy: {},
|
||||
}
|
||||
}
|
||||
|
||||
const allLibs = window => ({
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
"use strict";var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");Object.defineProperty(exports, "__esModule", { value: true });Object.defineProperty(exports, "validateRecord", { enumerable: true, get: function get() {return _validateRecord.validateRecord;} });Object.defineProperty(exports, "events", { enumerable: true, get: function get() {return _events.events;} });Object.defineProperty(exports, "safeParseField", { enumerable: true, get: function get() {return _types.safeParseField;} });Object.defineProperty(exports, "schemaValidator", { enumerable: true, get: function get() {return _schemaValidation["default"];} });var _validateRecord = require("./records/validateRecord");
|
||||
var _events = require("./common/events");
|
||||
"use strict";var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");Object.defineProperty(exports, "__esModule", { value: true });Object.defineProperty(exports, "events", { enumerable: true, get: function get() {return _events.events;} });Object.defineProperty(exports, "safeParseField", { enumerable: true, get: function get() {return _types.safeParseField;} });Object.defineProperty(exports, "schemaValidator", { enumerable: true, get: function get() {return _schemaValidation["default"];} });var _events = require("./common/events");
|
||||
var _types = require("./schema/types");
|
||||
var _schemaValidation = _interopRequireDefault(require("./schemaValidation"));
|
||||
//# sourceMappingURL=index.js.map
|
|
@ -1 +1 @@
|
|||
{"version":3,"sources":["../src/index.js"],"names":[],"mappings":"kpBAAA;AACA;AACA;AACA","sourcesContent":["export { validateRecord } from \"./records/validateRecord\";\nexport { events } from \"./common/events\";\nexport { safeParseField } from \"./schema/types\";\nexport { default as schemaValidator } from \"./schemaValidation\";"],"file":"index.js"}
|
||||
{"version":3,"sources":["../src/index.js"],"names":[],"mappings":"6gBAAA;AACA;AACA","sourcesContent":["export { events } from \"./common/events\";\nexport { safeParseField } from \"./schema/types\";\nexport { default as schemaValidator } from \"./schemaValidation\";"],"file":"index.js"}
|
|
@ -1,17 +0,0 @@
|
|||
"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.getNewRecord = void 0;var _shortid = require("shortid");
|
||||
|
||||
var getNewRecord = function getNewRecord(schema, modelName) {
|
||||
var model = schema.findModel(modelName);
|
||||
|
||||
var record = {
|
||||
_id: (0, _shortid.generate)(),
|
||||
modelId: model._id };
|
||||
|
||||
|
||||
for (var field in model.schema.properties) {
|
||||
record[field] = field["default"];
|
||||
}
|
||||
|
||||
return record;
|
||||
};exports.getNewRecord = getNewRecord;
|
||||
//# sourceMappingURL=getNewRecord.js.map
|
|
@ -1 +0,0 @@
|
|||
{"version":3,"sources":["../../src/records/getNewRecord.js"],"names":["getNewRecord","schema","modelName","model","findModel","record","_id","modelId","field","properties"],"mappings":"yGAAA;;AAEO,IAAMA,YAAY,GAAG,SAAfA,YAAe,CAACC,MAAD,EAASC,SAAT,EAAuB;AACjD,MAAMC,KAAK,GAAGF,MAAM,CAACG,SAAP,CAAiBF,SAAjB,CAAd;;AAEA,MAAMG,MAAM,GAAG;AACbC,IAAAA,GAAG,EAAE,wBADQ;AAEbC,IAAAA,OAAO,EAAEJ,KAAK,CAACG,GAFF,EAAf;;;AAKA,OAAK,IAAIE,KAAT,IAAkBL,KAAK,CAACF,MAAN,CAAaQ,UAA/B,EAA2C;AACzCJ,IAAAA,MAAM,CAACG,KAAD,CAAN,GAAgBA,KAAK,WAArB;AACD;;AAED,SAAOH,MAAP;AACD,CAbM,C","sourcesContent":["import { generate } from \"shortid\"\n\nexport const getNewRecord = (schema, modelName) => {\n const model = schema.findModel(modelName)\n\n const record = {\n _id: generate(),\n modelId: model._id,\n }\n\n for (let field in model.schema.properties) {\n record[field] = field.default\n }\n\n return record\n}\n"],"file":"getNewRecord.js"}
|
|
@ -1,31 +0,0 @@
|
|||
"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.commonRecordValidationRules = exports.getNewRecordValidationRule = void 0;var getNewRecordValidationRule = function getNewRecordValidationRule(
|
||||
invalidField,
|
||||
messageWhenInvalid,
|
||||
expressionWhenValid) {return (
|
||||
{
|
||||
invalidField: invalidField,
|
||||
messageWhenInvalid: messageWhenInvalid,
|
||||
expressionWhenValid: expressionWhenValid });};exports.getNewRecordValidationRule = getNewRecordValidationRule;
|
||||
|
||||
|
||||
var commonRecordValidationRules = {
|
||||
fieldNotEmpty: function fieldNotEmpty(fieldName) {return (
|
||||
getNewRecordValidationRule(
|
||||
fieldName, "".concat(
|
||||
fieldName, " is empty"), "record['".concat(
|
||||
fieldName, "'] && record['").concat(fieldName, "'].length > 0")));},
|
||||
|
||||
|
||||
fieldBetween: function fieldBetween(fieldName, min, max) {return (
|
||||
getNewRecordValidationRule(
|
||||
fieldName, "".concat(
|
||||
fieldName, " must be between ").concat(min.toString(), " and ").concat(max.toString()), "record['".concat(
|
||||
fieldName, "'] >= ").concat(min, " && record['").concat(fieldName, "'] <= ").concat(max, " ")));},
|
||||
|
||||
|
||||
fieldGreaterThan: function fieldGreaterThan(fieldName, min, max) {return (
|
||||
getNewRecordValidationRule(
|
||||
fieldName, "".concat(
|
||||
fieldName, " must be greater than ").concat(min.toString(), " and ").concat(max.toString()), "record['".concat(
|
||||
fieldName, "'] >= ").concat(min, " ")));} };exports.commonRecordValidationRules = commonRecordValidationRules;
|
||||
//# sourceMappingURL=recordValidationRules.js.map
|
|
@ -1 +0,0 @@
|
|||
{"version":3,"sources":["../../src/records/recordValidationRules.js"],"names":["getNewRecordValidationRule","invalidField","messageWhenInvalid","expressionWhenValid","commonRecordValidationRules","fieldNotEmpty","fieldName","fieldBetween","min","max","toString","fieldGreaterThan"],"mappings":"6JAAO,IAAMA,0BAA0B,GAAG,SAA7BA,0BAA6B;AACxCC,YADwC;AAExCC,kBAFwC;AAGxCC,mBAHwC;AAIpC;AACJF,MAAAA,YAAY,EAAZA,YADI;AAEJC,MAAAA,kBAAkB,EAAlBA,kBAFI;AAGJC,MAAAA,mBAAmB,EAAnBA,mBAHI,EAJoC,GAAnC,C;;;AAUA,IAAMC,2BAA2B,GAAG;AACzCC,EAAAA,aAAa,EAAE,uBAAAC,SAAS;AACtBN,MAAAA,0BAA0B;AACxBM,MAAAA,SADwB;AAErBA,MAAAA,SAFqB;AAGbA,MAAAA,SAHa,2BAGaA,SAHb,mBADJ,GADiB;;;AAQzCC,EAAAA,YAAY,EAAE,sBAACD,SAAD,EAAYE,GAAZ,EAAiBC,GAAjB;AACZT,MAAAA,0BAA0B;AACxBM,MAAAA,SADwB;AAErBA,MAAAA,SAFqB,8BAEQE,GAAG,CAACE,QAAJ,EAFR,kBAE8BD,GAAG,CAACC,QAAJ,EAF9B;AAGbJ,MAAAA,SAHa,mBAGKE,GAHL,0BAGwBF,SAHxB,mBAG0CG,GAH1C,OADd,GAR2B;;;AAezCE,EAAAA,gBAAgB,EAAE,0BAACL,SAAD,EAAYE,GAAZ,EAAiBC,GAAjB;AAChBT,MAAAA,0BAA0B;AACxBM,MAAAA,SADwB;AAErBA,MAAAA,SAFqB,mCAEaE,GAAG,CAACE,QAAJ,EAFb,kBAEmCD,GAAG,CAACC,QAAJ,EAFnC;AAGbJ,MAAAA,SAHa,mBAGKE,GAHL,QADV,GAfuB,EAApC,C","sourcesContent":["export const getNewRecordValidationRule = (\n invalidField,\n messageWhenInvalid,\n expressionWhenValid\n) => ({\n invalidField,\n messageWhenInvalid,\n expressionWhenValid,\n})\n\nexport const commonRecordValidationRules = {\n fieldNotEmpty: fieldName =>\n getNewRecordValidationRule(\n fieldName,\n `${fieldName} is empty`,\n `record['${fieldName}'] && record['${fieldName}'].length > 0`\n ),\n\n fieldBetween: (fieldName, min, max) =>\n getNewRecordValidationRule(\n fieldName,\n `${fieldName} must be between ${min.toString()} and ${max.toString()}`,\n `record['${fieldName}'] >= ${min} && record['${fieldName}'] <= ${max} `\n ),\n\n fieldGreaterThan: (fieldName, min, max) =>\n getNewRecordValidationRule(\n fieldName,\n `${fieldName} must be greater than ${min.toString()} and ${max.toString()}`,\n `record['${fieldName}'] >= ${min} `\n ),\n}\n"],"file":"recordValidationRules.js"}
|
|
@ -1,86 +0,0 @@
|
|||
"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.validateRecord = void 0;var _fp = require("lodash/fp");
|
||||
var _compileCode = require("../common/compileCode");
|
||||
var _index = require("../schema/types/index.js");
|
||||
|
||||
|
||||
|
||||
var _index2 = require("../common/index.js");function _createForOfIteratorHelper(o) {if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) {if (Array.isArray(o) || (o = _unsupportedIterableToArray(o))) {var i = 0;var F = function F() {};return { s: F, n: function n() {if (i >= o.length) return { done: true };return { done: false, value: o[i++] };}, e: function e(_e) {throw _e;}, f: F };}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");}var it,normalCompletion = true,didErr = false,err;return { s: function s() {it = o[Symbol.iterator]();}, n: function n() {var step = it.next();normalCompletion = step.done;return step;}, e: function e(_e2) {didErr = true;err = _e2;}, f: function f() {try {if (!normalCompletion && it["return"] != null) it["return"]();} finally {if (didErr) throw err;}} };}function _unsupportedIterableToArray(o, minLen) {if (!o) return;if (typeof o === "string") return _arrayLikeToArray(o, minLen);var n = Object.prototype.toString.call(o).slice(8, -1);if (n === "Object" && o.constructor) n = o.constructor.name;if (n === "Map" || n === "Set") return Array.from(n);if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);}function _arrayLikeToArray(arr, len) {if (len == null || len > arr.length) len = arr.length;for (var i = 0, arr2 = new Array(len); i < len; i++) {arr2[i] = arr[i];}return arr2;}
|
||||
|
||||
var fieldParseError = function fieldParseError(fieldName, value) {return {
|
||||
fields: [fieldName],
|
||||
message: "Could not parse field ".concat(fieldName, ":").concat(value) };};
|
||||
|
||||
|
||||
var validateAllFieldParse = function validateAllFieldParse(record, model) {return (
|
||||
(0, _index2.$)(model.fields, [
|
||||
(0, _fp.map)(function (f) {return { name: f.name, parseResult: (0, _index.validateFieldParse)(f, record) };}),
|
||||
(0, _fp.reduce)(function (errors, f) {
|
||||
if (f.parseResult.success) return errors;
|
||||
errors.push(fieldParseError(f.name, f.parseResult.value));
|
||||
return errors;
|
||||
}, [])]));};
|
||||
|
||||
|
||||
var validateAllTypeConstraints = function validateAllTypeConstraints(record, model) {
|
||||
var errors = [];var _iterator = _createForOfIteratorHelper(
|
||||
model.fields),_step;try {var _loop = function _loop() {var field = _step.value;
|
||||
(0, _index2.$)((0, _index.validateTypeConstraints)(field, record), [
|
||||
(0, _fp.filter)(_index2.isNonEmptyString),
|
||||
(0, _fp.map)(function (m) {return { message: m, fields: [field.name] };}),
|
||||
(0, _fp.each)(function (e) {return errors.push(e);})]);};for (_iterator.s(); !(_step = _iterator.n()).done;) {_loop();
|
||||
|
||||
}} catch (err) {_iterator.e(err);} finally {_iterator.f();}
|
||||
return errors;
|
||||
};
|
||||
|
||||
var runRecordValidationRules = function runRecordValidationRules(record, model) {
|
||||
var runValidationRule = function runValidationRule(rule) {
|
||||
var isValid = (0, _compileCode.compileCode)(rule.expressionWhenValid);
|
||||
var expressionContext = { record: record };
|
||||
return isValid(expressionContext) ?
|
||||
{ valid: true } :
|
||||
{
|
||||
valid: false,
|
||||
fields: rule.invalidFields,
|
||||
message: rule.messageWhenInvalid };
|
||||
|
||||
};
|
||||
|
||||
return (0, _index2.$)(model.validationRules, [
|
||||
(0, _fp.map)(runValidationRule),
|
||||
_fp.flatten,
|
||||
(0, _fp.filter)(function (r) {return r.valid === false;}),
|
||||
(0, _fp.map)(function (r) {return { fields: r.fields, message: r.message };})]);
|
||||
|
||||
};
|
||||
|
||||
var validateRecord = function validateRecord(schema, record) {
|
||||
var model = schema.findModel(record._modelId);
|
||||
var fieldParseFails = validateAllFieldParse(record, model);
|
||||
|
||||
// non parsing would cause further issues - exit here
|
||||
if (!(0, _fp.isEmpty)(fieldParseFails)) {
|
||||
return { isValid: false, errors: fieldParseFails };
|
||||
}
|
||||
|
||||
var recordValidationRuleFails = runRecordValidationRules(record, model);
|
||||
var typeContraintFails = validateAllTypeConstraints(record, model);
|
||||
|
||||
if (
|
||||
(0, _fp.isEmpty)(fieldParseFails) &&
|
||||
(0, _fp.isEmpty)(recordValidationRuleFails) &&
|
||||
(0, _fp.isEmpty)(typeContraintFails))
|
||||
{
|
||||
return { isValid: true, errors: [] };
|
||||
}
|
||||
|
||||
return {
|
||||
isValid: false,
|
||||
errors: (0, _fp.union)(
|
||||
fieldParseFails,
|
||||
typeContraintFails,
|
||||
recordValidationRuleFails) };
|
||||
|
||||
|
||||
};exports.validateRecord = validateRecord;
|
||||
//# sourceMappingURL=validateRecord.js.map
|
File diff suppressed because one or more lines are too long
|
@ -1,68 +0,0 @@
|
|||
"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports["default"] = void 0;var _fp = require("lodash/fp");
|
||||
var _typeHelpers = require("./typeHelpers");
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
var _index = require("../../common/index.js");
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
var arrayFunctions = function arrayFunctions() {return (
|
||||
(0, _typeHelpers.typeFunctions)({
|
||||
"default": (0, _fp.constant)([]) }));};
|
||||
|
||||
|
||||
var mapToParsedArrary = function mapToParsedArrary(type) {return (
|
||||
(0, _index.$$)(
|
||||
(0, _fp.map)(function (i) {return type.safeParseValue(i);}),
|
||||
_typeHelpers.parsedSuccess));};
|
||||
|
||||
|
||||
var arrayTryParse = function arrayTryParse(type) {return (
|
||||
(0, _index.switchCase)([_fp.isArray, mapToParsedArrary(type)], [_index.defaultCase, _typeHelpers.parsedFailed]));};
|
||||
|
||||
var typeName = function typeName(type) {return "array<".concat(type, ">");};
|
||||
|
||||
var options = {
|
||||
maxLength: {
|
||||
defaultValue: 10000,
|
||||
isValid: _index.isSafeInteger,
|
||||
requirementDescription: "must be a positive integer",
|
||||
parse: _index.toNumberOrNull },
|
||||
|
||||
minLength: {
|
||||
defaultValue: 0,
|
||||
isValid: function isValid(n) {return (0, _index.isSafeInteger)(n) && n >= 0;},
|
||||
requirementDescription: "must be a positive integer",
|
||||
parse: _index.toNumberOrNull } };
|
||||
|
||||
|
||||
|
||||
var typeConstraints = [
|
||||
(0, _typeHelpers.makerule)(
|
||||
function (val, opts) {return val === null || val.length >= opts.minLength;},
|
||||
function (val, opts) {return "must choose ".concat(opts.minLength, " or more options");}),
|
||||
|
||||
(0, _typeHelpers.makerule)(
|
||||
function (val, opts) {return val === null || val.length <= opts.maxLength;},
|
||||
function (val, opts) {return "cannot choose more than ".concat(opts.maxLength, " options");})];var _default =
|
||||
|
||||
|
||||
|
||||
function _default(type) {return (
|
||||
(0, _typeHelpers.getDefaultExport)(
|
||||
typeName(type.name),
|
||||
arrayTryParse(type),
|
||||
arrayFunctions(type),
|
||||
options,
|
||||
typeConstraints,
|
||||
[type.sampleValue],
|
||||
JSON.stringify));};exports["default"] = _default;
|
||||
//# sourceMappingURL=array.js.map
|
|
@ -1 +0,0 @@
|
|||
{"version":3,"sources":["../../../src/schema/types/array.js"],"names":["arrayFunctions","mapToParsedArrary","type","i","safeParseValue","parsedSuccess","arrayTryParse","isArray","defaultCase","parsedFailed","typeName","options","maxLength","defaultValue","isValid","isSafeInteger","requirementDescription","parse","toNumberOrNull","minLength","n","typeConstraints","val","opts","length","name","sampleValue","JSON","stringify"],"mappings":"uGAAA;AACA;;;;;;;AAOA;;;;;;;;AAQA,IAAMA,cAAc,GAAG,SAAjBA,cAAiB;AACrB,oCAAc;AACZ,iBAAS,kBAAS,EAAT,CADG,EAAd,CADqB,GAAvB;;;AAKA,IAAMC,iBAAiB,GAAG,SAApBA,iBAAoB,CAAAC,IAAI;AAC5B;AACE,iBAAI,UAAAC,CAAC,UAAID,IAAI,CAACE,cAAL,CAAoBD,CAApB,CAAJ,EAAL,CADF;AAEEE,8BAFF,CAD4B,GAA9B;;;AAMA,IAAMC,aAAa,GAAG,SAAhBA,aAAgB,CAAAJ,IAAI;AACxB,2BAAW,CAACK,WAAD,EAAUN,iBAAiB,CAACC,IAAD,CAA3B,CAAX,EAA+C,CAACM,kBAAD,EAAcC,yBAAd,CAA/C,CADwB,GAA1B;;AAGA,IAAMC,QAAQ,GAAG,SAAXA,QAAW,CAAAR,IAAI,0BAAaA,IAAb,QAArB;;AAEA,IAAMS,OAAO,GAAG;AACdC,EAAAA,SAAS,EAAE;AACTC,IAAAA,YAAY,EAAE,KADL;AAETC,IAAAA,OAAO,EAAEC,oBAFA;AAGTC,IAAAA,sBAAsB,EAAE,4BAHf;AAITC,IAAAA,KAAK,EAAEC,qBAJE,EADG;;AAOdC,EAAAA,SAAS,EAAE;AACTN,IAAAA,YAAY,EAAE,CADL;AAETC,IAAAA,OAAO,EAAE,iBAAAM,CAAC,UAAI,0BAAcA,CAAd,KAAoBA,CAAC,IAAI,CAA7B,EAFD;AAGTJ,IAAAA,sBAAsB,EAAE,4BAHf;AAITC,IAAAA,KAAK,EAAEC,qBAJE,EAPG,EAAhB;;;;AAeA,IAAMG,eAAe,GAAG;AACtB;AACE,UAACC,GAAD,EAAMC,IAAN,UAAeD,GAAG,KAAK,IAAR,IAAgBA,GAAG,CAACE,MAAJ,IAAcD,IAAI,CAACJ,SAAlD,EADF;AAEE,UAACG,GAAD,EAAMC,IAAN,gCAA8BA,IAAI,CAACJ,SAAnC,uBAFF,CADsB;;AAKtB;AACE,UAACG,GAAD,EAAMC,IAAN,UAAeD,GAAG,KAAK,IAAR,IAAgBA,GAAG,CAACE,MAAJ,IAAcD,IAAI,CAACX,SAAlD,EADF;AAEE,UAACU,GAAD,EAAMC,IAAN,4CAA0CA,IAAI,CAACX,SAA/C,eAFF,CALsB,CAAxB,C;;;;AAWe,kBAAAV,IAAI;AACjB;AACEQ,IAAAA,QAAQ,CAACR,IAAI,CAACuB,IAAN,CADV;AAEEnB,IAAAA,aAAa,CAACJ,IAAD,CAFf;AAGEF,IAAAA,cAAc,CAACE,IAAD,CAHhB;AAIES,IAAAA,OAJF;AAKEU,IAAAA,eALF;AAME,KAACnB,IAAI,CAACwB,WAAN,CANF;AAOEC,IAAAA,IAAI,CAACC,SAPP,CADiB,G","sourcesContent":["import { map, constant, isArray } from \"lodash/fp\"\r\nimport {\r\n typeFunctions,\r\n makerule,\r\n parsedFailed,\r\n getDefaultExport,\r\n parsedSuccess,\r\n} from \"./typeHelpers\"\r\nimport {\r\n switchCase,\r\n defaultCase,\r\n toNumberOrNull,\r\n $$,\r\n isSafeInteger,\r\n} from \"../../common/index.js\"\r\n\r\nconst arrayFunctions = () =>\r\n typeFunctions({\r\n default: constant([]),\r\n })\r\n\r\nconst mapToParsedArrary = type =>\r\n $$(\r\n map(i => type.safeParseValue(i)),\r\n parsedSuccess\r\n )\r\n\r\nconst arrayTryParse = type =>\r\n switchCase([isArray, mapToParsedArrary(type)], [defaultCase, parsedFailed])\r\n\r\nconst typeName = type => `array<${type}>`\r\n\r\nconst options = {\r\n maxLength: {\r\n defaultValue: 10000,\r\n isValid: isSafeInteger,\r\n requirementDescription: \"must be a positive integer\",\r\n parse: toNumberOrNull,\r\n },\r\n minLength: {\r\n defaultValue: 0,\r\n isValid: n => isSafeInteger(n) && n >= 0,\r\n requirementDescription: \"must be a positive integer\",\r\n parse: toNumberOrNull,\r\n },\r\n}\r\n\r\nconst typeConstraints = [\r\n makerule(\r\n (val, opts) => val === null || val.length >= opts.minLength,\r\n (val, opts) => `must choose ${opts.minLength} or more options`\r\n ),\r\n makerule(\r\n (val, opts) => val === null || val.length <= opts.maxLength,\r\n (val, opts) => `cannot choose more than ${opts.maxLength} options`\r\n ),\r\n]\r\n\r\nexport default type =>\r\n getDefaultExport(\r\n typeName(type.name),\r\n arrayTryParse(type),\r\n arrayFunctions(type),\r\n options,\r\n typeConstraints,\r\n [type.sampleValue],\r\n JSON.stringify\r\n )\r\n"],"file":"array.js"}
|
|
@ -1,52 +0,0 @@
|
|||
"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports["default"] = void 0;var _fp = require("lodash/fp");
|
||||
var _typeHelpers = require("./typeHelpers");
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
var _index = require("../../common/index.js");
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
var boolFunctions = (0, _typeHelpers.typeFunctions)({
|
||||
"default": (0, _fp.constant)(null) });
|
||||
|
||||
|
||||
var boolTryParse = (0, _index.switchCase)(
|
||||
[_fp.isBoolean, _typeHelpers.parsedSuccess],
|
||||
[_fp.isNull, _typeHelpers.parsedSuccess],
|
||||
[(0, _index.isOneOf)("true", "1", "yes", "on"), function () {return (0, _typeHelpers.parsedSuccess)(true);}],
|
||||
[(0, _index.isOneOf)("false", "0", "no", "off"), function () {return (0, _typeHelpers.parsedSuccess)(false);}],
|
||||
[_index.defaultCase, _typeHelpers.parsedFailed]);
|
||||
|
||||
|
||||
var options = {
|
||||
allowNulls: {
|
||||
defaultValue: true,
|
||||
isValid: _fp.isBoolean,
|
||||
requirementDescription: "must be a true or false",
|
||||
parse: _index.toBoolOrNull } };
|
||||
|
||||
|
||||
|
||||
var typeConstraints = [
|
||||
(0, _typeHelpers.makerule)(
|
||||
function (val, opts) {return opts.allowNulls === true || val !== null;},
|
||||
function () {return "field cannot be null";})];var _default =
|
||||
|
||||
|
||||
|
||||
(0, _typeHelpers.getDefaultExport)(
|
||||
"bool",
|
||||
boolTryParse,
|
||||
boolFunctions,
|
||||
options,
|
||||
typeConstraints,
|
||||
true,
|
||||
JSON.stringify);exports["default"] = _default;
|
||||
//# sourceMappingURL=bool.js.map
|
|
@ -1 +0,0 @@
|
|||
{"version":3,"sources":["../../../src/schema/types/bool.js"],"names":["boolFunctions","boolTryParse","isBoolean","parsedSuccess","isNull","defaultCase","parsedFailed","options","allowNulls","defaultValue","isValid","requirementDescription","parse","toBoolOrNull","typeConstraints","val","opts","JSON","stringify"],"mappings":"uGAAA;AACA;;;;;;;AAOA;;;;;;;AAOA,IAAMA,aAAa,GAAG,gCAAc;AAClC,aAAS,kBAAS,IAAT,CADyB,EAAd,CAAtB;;;AAIA,IAAMC,YAAY,GAAG;AACnB,CAACC,aAAD,EAAYC,0BAAZ,CADmB;AAEnB,CAACC,UAAD,EAASD,0BAAT,CAFmB;AAGnB,CAAC,oBAAQ,MAAR,EAAgB,GAAhB,EAAqB,KAArB,EAA4B,IAA5B,CAAD,EAAoC,oBAAM,gCAAc,IAAd,CAAN,EAApC,CAHmB;AAInB,CAAC,oBAAQ,OAAR,EAAiB,GAAjB,EAAsB,IAAtB,EAA4B,KAA5B,CAAD,EAAqC,oBAAM,gCAAc,KAAd,CAAN,EAArC,CAJmB;AAKnB,CAACE,kBAAD,EAAcC,yBAAd,CALmB,CAArB;;;AAQA,IAAMC,OAAO,GAAG;AACdC,EAAAA,UAAU,EAAE;AACVC,IAAAA,YAAY,EAAE,IADJ;AAEVC,IAAAA,OAAO,EAAER,aAFC;AAGVS,IAAAA,sBAAsB,EAAE,yBAHd;AAIVC,IAAAA,KAAK,EAAEC,mBAJG,EADE,EAAhB;;;;AASA,IAAMC,eAAe,GAAG;AACtB;AACE,UAACC,GAAD,EAAMC,IAAN,UAAeA,IAAI,CAACR,UAAL,KAAoB,IAApB,IAA4BO,GAAG,KAAK,IAAnD,EADF;AAEE,oBAAM,sBAAN,EAFF,CADsB,CAAxB,C;;;;AAOe;AACb,MADa;AAEbd,YAFa;AAGbD,aAHa;AAIbO,OAJa;AAKbO,eALa;AAMb,IANa;AAObG,IAAI,CAACC,SAPQ,C","sourcesContent":["import { constant, isBoolean, isNull } from \"lodash/fp\"\r\nimport {\r\n typeFunctions,\r\n makerule,\r\n parsedFailed,\r\n parsedSuccess,\r\n getDefaultExport,\r\n} from \"./typeHelpers\"\r\nimport {\r\n switchCase,\r\n defaultCase,\r\n isOneOf,\r\n toBoolOrNull,\r\n} from \"../../common/index.js\"\r\n\r\nconst boolFunctions = typeFunctions({\r\n default: constant(null),\r\n})\r\n\r\nconst boolTryParse = switchCase(\r\n [isBoolean, parsedSuccess],\r\n [isNull, parsedSuccess],\r\n [isOneOf(\"true\", \"1\", \"yes\", \"on\"), () => parsedSuccess(true)],\r\n [isOneOf(\"false\", \"0\", \"no\", \"off\"), () => parsedSuccess(false)],\r\n [defaultCase, parsedFailed]\r\n)\r\n\r\nconst options = {\r\n allowNulls: {\r\n defaultValue: true,\r\n isValid: isBoolean,\r\n requirementDescription: \"must be a true or false\",\r\n parse: toBoolOrNull,\r\n },\r\n}\r\n\r\nconst typeConstraints = [\r\n makerule(\r\n (val, opts) => opts.allowNulls === true || val !== null,\r\n () => \"field cannot be null\"\r\n ),\r\n]\r\n\r\nexport default getDefaultExport(\r\n \"bool\",\r\n boolTryParse,\r\n boolFunctions,\r\n options,\r\n typeConstraints,\r\n true,\r\n JSON.stringify\r\n)\r\n"],"file":"bool.js"}
|
|
@ -1,62 +0,0 @@
|
|||
"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports["default"] = exports.isLegalFilename = void 0;var _fp = require("lodash/fp");
|
||||
var _typeHelpers = require("./typeHelpers");
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
var _index = require("../../common/index.js");
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
var illegalCharacters = "*?\\/:<>|\0\b\f\v";
|
||||
|
||||
var isLegalFilename = function isLegalFilename(filePath) {
|
||||
var fn = fileName(filePath);
|
||||
return (
|
||||
fn.length <= 255 &&
|
||||
(0, _fp.intersection)(fn.split(""))(illegalCharacters.split("")).length === 0 &&
|
||||
(0, _index.none)(function (f) {return f === "..";})((0, _index.splitKey)(filePath)));
|
||||
|
||||
};exports.isLegalFilename = isLegalFilename;
|
||||
|
||||
var fileNothing = function fileNothing() {return { relativePath: "", size: 0 };};
|
||||
|
||||
var fileFunctions = (0, _typeHelpers.typeFunctions)({
|
||||
"default": fileNothing });
|
||||
|
||||
|
||||
var fileTryParse = function fileTryParse(v) {return (
|
||||
(0, _index.switchCase)(
|
||||
[isValidFile, _typeHelpers.parsedSuccess],
|
||||
[_fp.isNull, function () {return (0, _typeHelpers.parsedSuccess)(fileNothing());}],
|
||||
[_index.defaultCase, _typeHelpers.parsedFailed])(
|
||||
v));};
|
||||
|
||||
var fileName = function fileName(filePath) {return (0, _index.$)(filePath, [_index.splitKey, _fp.last]);};
|
||||
|
||||
var isValidFile = function isValidFile(f) {return (
|
||||
!(0, _fp.isNull)(f) &&
|
||||
(0, _fp.has)("relativePath")(f) &&
|
||||
(0, _fp.has)("size")(f) &&
|
||||
(0, _fp.isNumber)(f.size) &&
|
||||
(0, _fp.isString)(f.relativePath) &&
|
||||
isLegalFilename(f.relativePath));};
|
||||
|
||||
var options = {};
|
||||
|
||||
var typeConstraints = [];var _default =
|
||||
|
||||
(0, _typeHelpers.getDefaultExport)(
|
||||
"file",
|
||||
fileTryParse,
|
||||
fileFunctions,
|
||||
options,
|
||||
typeConstraints,
|
||||
{ relativePath: "some_file.jpg", size: 1000 },
|
||||
JSON.stringify);exports["default"] = _default;
|
||||
//# sourceMappingURL=file.js.map
|
|
@ -1 +0,0 @@
|
|||
{"version":3,"sources":["../../../src/schema/types/file.js"],"names":["illegalCharacters","isLegalFilename","filePath","fn","fileName","length","split","f","fileNothing","relativePath","size","fileFunctions","fileTryParse","v","isValidFile","parsedSuccess","isNull","defaultCase","parsedFailed","splitKey","last","options","typeConstraints","JSON","stringify"],"mappings":"iIAAA;AACA;;;;;;AAMA;;;;;;;;AAQA,IAAMA,iBAAiB,GAAG,mBAA1B;;AAEO,IAAMC,eAAe,GAAG,SAAlBA,eAAkB,CAAAC,QAAQ,EAAI;AACzC,MAAMC,EAAE,GAAGC,QAAQ,CAACF,QAAD,CAAnB;AACA;AACEC,IAAAA,EAAE,CAACE,MAAH,IAAa,GAAb;AACA,0BAAaF,EAAE,CAACG,KAAH,CAAS,EAAT,CAAb,EAA2BN,iBAAiB,CAACM,KAAlB,CAAwB,EAAxB,CAA3B,EAAwDD,MAAxD,KAAmE,CADnE;AAEA,qBAAK,UAAAE,CAAC,UAAIA,CAAC,KAAK,IAAV,EAAN,EAAsB,qBAASL,QAAT,CAAtB,CAHF;;AAKD,CAPM,C;;AASP,IAAMM,WAAW,GAAG,SAAdA,WAAc,WAAO,EAAEC,YAAY,EAAE,EAAhB,EAAoBC,IAAI,EAAE,CAA1B,EAAP,EAApB;;AAEA,IAAMC,aAAa,GAAG,gCAAc;AAClC,aAASH,WADyB,EAAd,CAAtB;;;AAIA,IAAMI,YAAY,GAAG,SAAfA,YAAe,CAAAC,CAAC;AACpB;AACE,KAACC,WAAD,EAAcC,0BAAd,CADF;AAEE,KAACC,UAAD,EAAS,oBAAM,gCAAcR,WAAW,EAAzB,CAAN,EAAT,CAFF;AAGE,KAACS,kBAAD,EAAcC,yBAAd,CAHF;AAIEL,IAAAA,CAJF,CADoB,GAAtB;;AAOA,IAAMT,QAAQ,GAAG,SAAXA,QAAW,CAAAF,QAAQ,UAAI,cAAEA,QAAF,EAAY,CAACiB,eAAD,EAAWC,QAAX,CAAZ,CAAJ,EAAzB;;AAEA,IAAMN,WAAW,GAAG,SAAdA,WAAc,CAAAP,CAAC;AACnB,KAAC,gBAAOA,CAAP,CAAD;AACA,iBAAI,cAAJ,EAAoBA,CAApB,CADA;AAEA,iBAAI,MAAJ,EAAYA,CAAZ,CAFA;AAGA,sBAASA,CAAC,CAACG,IAAX,CAHA;AAIA,sBAASH,CAAC,CAACE,YAAX,CAJA;AAKAR,IAAAA,eAAe,CAACM,CAAC,CAACE,YAAH,CANI,GAArB;;AAQA,IAAMY,OAAO,GAAG,EAAhB;;AAEA,IAAMC,eAAe,GAAG,EAAxB,C;;AAEe;AACb,MADa;AAEbV,YAFa;AAGbD,aAHa;AAIbU,OAJa;AAKbC,eALa;AAMb,EAAEb,YAAY,EAAE,eAAhB,EAAiCC,IAAI,EAAE,IAAvC,EANa;AAOba,IAAI,CAACC,SAPQ,C","sourcesContent":["import { last, has, isString, intersection, isNull, isNumber } from \"lodash/fp\"\r\nimport {\r\n typeFunctions,\r\n parsedFailed,\r\n parsedSuccess,\r\n getDefaultExport,\r\n} from \"./typeHelpers\"\r\nimport {\r\n switchCase,\r\n defaultCase,\r\n none,\r\n $,\r\n splitKey,\r\n} from \"../../common/index.js\"\r\n\r\nconst illegalCharacters = \"*?\\\\/:<>|\\0\\b\\f\\v\"\r\n\r\nexport const isLegalFilename = filePath => {\r\n const fn = fileName(filePath)\r\n return (\r\n fn.length <= 255 &&\r\n intersection(fn.split(\"\"))(illegalCharacters.split(\"\")).length === 0 &&\r\n none(f => f === \"..\")(splitKey(filePath))\r\n )\r\n}\r\n\r\nconst fileNothing = () => ({ relativePath: \"\", size: 0 })\r\n\r\nconst fileFunctions = typeFunctions({\r\n default: fileNothing,\r\n})\r\n\r\nconst fileTryParse = v =>\r\n switchCase(\r\n [isValidFile, parsedSuccess],\r\n [isNull, () => parsedSuccess(fileNothing())],\r\n [defaultCase, parsedFailed]\r\n )(v)\r\n\r\nconst fileName = filePath => $(filePath, [splitKey, last])\r\n\r\nconst isValidFile = f =>\r\n !isNull(f) &&\r\n has(\"relativePath\")(f) &&\r\n has(\"size\")(f) &&\r\n isNumber(f.size) &&\r\n isString(f.relativePath) &&\r\n isLegalFilename(f.relativePath)\r\n\r\nconst options = {}\r\n\r\nconst typeConstraints = []\r\n\r\nexport default getDefaultExport(\r\n \"file\",\r\n fileTryParse,\r\n fileFunctions,\r\n options,\r\n typeConstraints,\r\n { relativePath: \"some_file.jpg\", size: 1000 },\r\n JSON.stringify\r\n)\r\n"],"file":"file.js"}
|
|
@ -1,59 +0,0 @@
|
|||
"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports["default"] = void 0;var _lodash = require("lodash");
|
||||
var _typeHelpers = require("./typeHelpers");
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
var _index = require("../../common/index.js");
|
||||
|
||||
var objectFunctions = function objectFunctions(definition, allTypes) {return (
|
||||
(0, _typeHelpers.typeFunctions)({
|
||||
"default": (0, _lodash.constant)(null),
|
||||
initialise: function initialise() {return (
|
||||
(0, _index.$)((0, _lodash.keys)(definition), [
|
||||
(0, _lodash.map)(function () {
|
||||
var defClone = (0, _lodash.clone)(definition);
|
||||
for (var k in defClone) {
|
||||
defClone[k] = allTypes[k].getNew();
|
||||
}
|
||||
return defClone;
|
||||
})]));} }));};
|
||||
|
||||
|
||||
|
||||
var parseObject = function parseObject(definition, allTypes) {return function (record) {
|
||||
var defClone = (0, _lodash.clone)(definition);
|
||||
for (var k in defClone) {
|
||||
var type = allTypes[defClone[k]];
|
||||
defClone[k] = (0, _lodash.has)(record, k) ?
|
||||
type.safeParseValue(record[k]) :
|
||||
type.getNew();
|
||||
}
|
||||
return (0, _typeHelpers.parsedSuccess)(defClone);
|
||||
};};
|
||||
|
||||
var objectTryParse = function objectTryParse(definition, allTypes) {return (
|
||||
(0, _index.switchCase)(
|
||||
[_lodash.isNull, _typeHelpers.parsedSuccess],
|
||||
[_lodash.isObject, parseObject(definition, allTypes)],
|
||||
[_index.defaultCase, _typeHelpers.parsedFailed]));};var _default =
|
||||
|
||||
|
||||
function _default(
|
||||
typeName,
|
||||
definition,
|
||||
allTypes,
|
||||
defaultOptions,
|
||||
typeConstraints,
|
||||
sampleValue) {return (
|
||||
|
||||
(0, _typeHelpers.getDefaultExport)(
|
||||
typeName,
|
||||
objectTryParse(definition, allTypes),
|
||||
objectFunctions(definition, allTypes),
|
||||
defaultOptions,
|
||||
typeConstraints,
|
||||
sampleValue,
|
||||
JSON.stringify));};exports["default"] = _default;
|
||||
//# sourceMappingURL=object.js.map
|
|
@ -1 +0,0 @@
|
|||
{"version":3,"sources":["../../../src/schema/types/object.js"],"names":["objectFunctions","definition","allTypes","initialise","defClone","k","getNew","parseObject","record","type","safeParseValue","objectTryParse","isNull","parsedSuccess","isObject","defaultCase","parsedFailed","typeName","defaultOptions","typeConstraints","sampleValue","JSON","stringify"],"mappings":"uGAAA;AACA;;;;;;AAMA;;AAEA,IAAMA,eAAe,GAAG,SAAlBA,eAAkB,CAACC,UAAD,EAAaC,QAAb;AACtB,oCAAc;AACZ,iBAAS,sBAAS,IAAT,CADG;AAEZC,MAAAA,UAAU,EAAE;AACV,wBAAE,kBAAKF,UAAL,CAAF,EAAoB;AAClB,2BAAI,YAAM;AACR,gBAAMG,QAAQ,GAAG,mBAAMH,UAAN,CAAjB;AACA,iBAAK,IAAMI,CAAX,IAAgBD,QAAhB,EAA0B;AACxBA,cAAAA,QAAQ,CAACC,CAAD,CAAR,GAAcH,QAAQ,CAACG,CAAD,CAAR,CAAYC,MAAZ,EAAd;AACD;AACD,mBAAOF,QAAP;AACD,WAND,CADkB,CAApB,CADU,GAFA,EAAd,CADsB,GAAxB;;;;AAeA,IAAMG,WAAW,GAAG,SAAdA,WAAc,CAACN,UAAD,EAAaC,QAAb,UAA0B,UAAAM,MAAM,EAAI;AACtD,QAAMJ,QAAQ,GAAG,mBAAMH,UAAN,CAAjB;AACA,SAAK,IAAMI,CAAX,IAAgBD,QAAhB,EAA0B;AACxB,UAAMK,IAAI,GAAGP,QAAQ,CAACE,QAAQ,CAACC,CAAD,CAAT,CAArB;AACAD,MAAAA,QAAQ,CAACC,CAAD,CAAR,GAAc,iBAAIG,MAAJ,EAAYH,CAAZ;AACVI,MAAAA,IAAI,CAACC,cAAL,CAAoBF,MAAM,CAACH,CAAD,CAA1B,CADU;AAEVI,MAAAA,IAAI,CAACH,MAAL,EAFJ;AAGD;AACD,WAAO,gCAAcF,QAAd,CAAP;AACD,GATmB,EAApB;;AAWA,IAAMO,cAAc,GAAG,SAAjBA,cAAiB,CAACV,UAAD,EAAaC,QAAb;AACrB;AACE,KAACU,cAAD,EAASC,0BAAT,CADF;AAEE,KAACC,gBAAD,EAAWP,WAAW,CAACN,UAAD,EAAaC,QAAb,CAAtB,CAFF;AAGE,KAACa,kBAAD,EAAcC,yBAAd,CAHF,CADqB,GAAvB,C;;;AAOe;AACbC,QADa;AAEbhB,UAFa;AAGbC,QAHa;AAIbgB,cAJa;AAKbC,eALa;AAMbC,WANa;;AAQb;AACEH,IAAAA,QADF;AAEEN,IAAAA,cAAc,CAACV,UAAD,EAAaC,QAAb,CAFhB;AAGEF,IAAAA,eAAe,CAACC,UAAD,EAAaC,QAAb,CAHjB;AAIEgB,IAAAA,cAJF;AAKEC,IAAAA,eALF;AAMEC,IAAAA,WANF;AAOEC,IAAAA,IAAI,CAACC,SAPP,CARa,G","sourcesContent":["import { keys, isObject, has, clone, map, isNull, constant } from \"lodash\"\r\nimport {\r\n typeFunctions,\r\n parsedFailed,\r\n parsedSuccess,\r\n getDefaultExport,\r\n} from \"./typeHelpers\"\r\nimport { switchCase, defaultCase, $ } from \"../../common/index.js\"\r\n\r\nconst objectFunctions = (definition, allTypes) =>\r\n typeFunctions({\r\n default: constant(null),\r\n initialise: () =>\r\n $(keys(definition), [\r\n map(() => {\r\n const defClone = clone(definition)\r\n for (const k in defClone) {\r\n defClone[k] = allTypes[k].getNew()\r\n }\r\n return defClone\r\n }),\r\n ]),\r\n })\r\n\r\nconst parseObject = (definition, allTypes) => record => {\r\n const defClone = clone(definition)\r\n for (const k in defClone) {\r\n const type = allTypes[defClone[k]]\r\n defClone[k] = has(record, k)\r\n ? type.safeParseValue(record[k])\r\n : type.getNew()\r\n }\r\n return parsedSuccess(defClone)\r\n}\r\n\r\nconst objectTryParse = (definition, allTypes) =>\r\n switchCase(\r\n [isNull, parsedSuccess],\r\n [isObject, parseObject(definition, allTypes)],\r\n [defaultCase, parsedFailed]\r\n )\r\n\r\nexport default (\r\n typeName,\r\n definition,\r\n allTypes,\r\n defaultOptions,\r\n typeConstraints,\r\n sampleValue\r\n) =>\r\n getDefaultExport(\r\n typeName,\r\n objectTryParse(definition, allTypes),\r\n objectFunctions(definition, allTypes),\r\n defaultOptions,\r\n typeConstraints,\r\n sampleValue,\r\n JSON.stringify\r\n )\r\n"],"file":"object.js"}
|
|
@ -1,74 +0,0 @@
|
|||
"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports["default"] = void 0;var _fp = require("lodash/fp");
|
||||
var _typeHelpers = require("./typeHelpers");
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
var _index = require("../../common/index.js");
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
var stringFunctions = (0, _typeHelpers.typeFunctions)({
|
||||
"default": (0, _fp.constant)(null) });
|
||||
|
||||
|
||||
var stringTryParse = (0, _index.switchCase)(
|
||||
[_fp.isString, _typeHelpers.parsedSuccess],
|
||||
[_fp.isNull, _typeHelpers.parsedSuccess],
|
||||
[_index.defaultCase, function (v) {return (0, _typeHelpers.parsedSuccess)(v.toString());}]);
|
||||
|
||||
|
||||
var options = {
|
||||
maxLength: {
|
||||
defaultValue: null,
|
||||
isValid: function isValid(n) {return n === null || (0, _index.isSafeInteger)(n) && n > 0;},
|
||||
requirementDescription:
|
||||
"max length must be null (no limit) or a greater than zero integer",
|
||||
parse: _index.toNumberOrNull },
|
||||
|
||||
values: {
|
||||
defaultValue: null,
|
||||
isValid: function isValid(v) {return (
|
||||
v === null || (0, _index.isArrayOfString)(v) && v.length > 0 && v.length < 10000);},
|
||||
requirementDescription:
|
||||
"'values' must be null (no values) or an array of at least one string",
|
||||
parse: function parse(s) {return s;} },
|
||||
|
||||
allowDeclaredValuesOnly: {
|
||||
defaultValue: false,
|
||||
isValid: _fp.isBoolean,
|
||||
requirementDescription: "allowDeclaredValuesOnly must be true or false",
|
||||
parse: _index.toBoolOrNull } };
|
||||
|
||||
|
||||
|
||||
var typeConstraints = [
|
||||
(0, _typeHelpers.makerule)(
|
||||
function (val, opts) {return (
|
||||
val === null || opts.maxLength === null || val.length <= opts.maxLength);},
|
||||
function (val, opts) {return "value exceeds maximum length of ".concat(opts.maxLength);}),
|
||||
|
||||
(0, _typeHelpers.makerule)(
|
||||
function (val, opts) {return (
|
||||
val === null ||
|
||||
opts.allowDeclaredValuesOnly === false ||
|
||||
(0, _fp.includes)(val)(opts.values));},
|
||||
function (val) {return "\"".concat(val, "\" does not exist in the list of allowed values");})];var _default =
|
||||
|
||||
|
||||
|
||||
(0, _typeHelpers.getDefaultExport)(
|
||||
"string",
|
||||
stringTryParse,
|
||||
stringFunctions,
|
||||
options,
|
||||
typeConstraints,
|
||||
"abcde",
|
||||
function (str) {return str;});exports["default"] = _default;
|
||||
//# sourceMappingURL=string.js.map
|
|
@ -1 +0,0 @@
|
|||
{"version":3,"sources":["../../../src/schema/types/string.js"],"names":["stringFunctions","stringTryParse","isString","parsedSuccess","isNull","defaultCase","v","toString","options","maxLength","defaultValue","isValid","n","requirementDescription","parse","toNumberOrNull","values","length","s","allowDeclaredValuesOnly","isBoolean","toBoolOrNull","typeConstraints","val","opts","str"],"mappings":"uGAAA;AACA;;;;;;AAMA;;;;;;;;;AASA,IAAMA,eAAe,GAAG,gCAAc;AACpC,aAAS,kBAAS,IAAT,CAD2B,EAAd,CAAxB;;;AAIA,IAAMC,cAAc,GAAG;AACrB,CAACC,YAAD,EAAWC,0BAAX,CADqB;AAErB,CAACC,UAAD,EAASD,0BAAT,CAFqB;AAGrB,CAACE,kBAAD,EAAc,UAAAC,CAAC,UAAI,gCAAcA,CAAC,CAACC,QAAF,EAAd,CAAJ,EAAf,CAHqB,CAAvB;;;AAMA,IAAMC,OAAO,GAAG;AACdC,EAAAA,SAAS,EAAE;AACTC,IAAAA,YAAY,EAAE,IADL;AAETC,IAAAA,OAAO,EAAE,iBAAAC,CAAC,UAAIA,CAAC,KAAK,IAAN,IAAe,0BAAcA,CAAd,KAAoBA,CAAC,GAAG,CAA3C,EAFD;AAGTC,IAAAA,sBAAsB;AACpB,uEAJO;AAKTC,IAAAA,KAAK,EAAEC,qBALE,EADG;;AAQdC,EAAAA,MAAM,EAAE;AACNN,IAAAA,YAAY,EAAE,IADR;AAENC,IAAAA,OAAO,EAAE,iBAAAL,CAAC;AACRA,QAAAA,CAAC,KAAK,IAAN,IAAe,4BAAgBA,CAAhB,KAAsBA,CAAC,CAACW,MAAF,GAAW,CAAjC,IAAsCX,CAAC,CAACW,MAAF,GAAW,KADxD,GAFJ;AAINJ,IAAAA,sBAAsB;AACpB,0EALI;AAMNC,IAAAA,KAAK,EAAE,eAAAI,CAAC,UAAIA,CAAJ,EANF,EARM;;AAgBdC,EAAAA,uBAAuB,EAAE;AACvBT,IAAAA,YAAY,EAAE,KADS;AAEvBC,IAAAA,OAAO,EAAES,aAFc;AAGvBP,IAAAA,sBAAsB,EAAE,+CAHD;AAIvBC,IAAAA,KAAK,EAAEO,mBAJgB,EAhBX,EAAhB;;;;AAwBA,IAAMC,eAAe,GAAG;AACtB;AACE,UAACC,GAAD,EAAMC,IAAN;AACED,IAAAA,GAAG,KAAK,IAAR,IAAgBC,IAAI,CAACf,SAAL,KAAmB,IAAnC,IAA2Cc,GAAG,CAACN,MAAJ,IAAcO,IAAI,CAACf,SADhE,GADF;AAGE,UAACc,GAAD,EAAMC,IAAN,oDAAkDA,IAAI,CAACf,SAAvD,GAHF,CADsB;;AAMtB;AACE,UAACc,GAAD,EAAMC,IAAN;AACED,IAAAA,GAAG,KAAK,IAAR;AACAC,IAAAA,IAAI,CAACL,uBAAL,KAAiC,KADjC;AAEA,sBAASI,GAAT,EAAcC,IAAI,CAACR,MAAnB,CAHF,GADF;AAKE,UAAAO,GAAG,sBAAQA,GAAR,sDALL,CANsB,CAAxB,C;;;;AAee;AACb,QADa;AAEbtB,cAFa;AAGbD,eAHa;AAIbQ,OAJa;AAKbc,eALa;AAMb,OANa;AAOb,UAAAG,GAAG,UAAIA,GAAJ,EAPU,C","sourcesContent":["import { constant, isString, isNull, includes, isBoolean } from \"lodash/fp\"\r\nimport {\r\n typeFunctions,\r\n makerule,\r\n parsedSuccess,\r\n getDefaultExport,\r\n} from \"./typeHelpers\"\r\nimport {\r\n switchCase,\r\n defaultCase,\r\n toBoolOrNull,\r\n toNumberOrNull,\r\n isSafeInteger,\r\n isArrayOfString,\r\n} from \"../../common/index.js\"\r\n\r\nconst stringFunctions = typeFunctions({\r\n default: constant(null),\r\n})\r\n\r\nconst stringTryParse = switchCase(\r\n [isString, parsedSuccess],\r\n [isNull, parsedSuccess],\r\n [defaultCase, v => parsedSuccess(v.toString())]\r\n)\r\n\r\nconst options = {\r\n maxLength: {\r\n defaultValue: null,\r\n isValid: n => n === null || (isSafeInteger(n) && n > 0),\r\n requirementDescription:\r\n \"max length must be null (no limit) or a greater than zero integer\",\r\n parse: toNumberOrNull,\r\n },\r\n values: {\r\n defaultValue: null,\r\n isValid: v =>\r\n v === null || (isArrayOfString(v) && v.length > 0 && v.length < 10000),\r\n requirementDescription:\r\n \"'values' must be null (no values) or an array of at least one string\",\r\n parse: s => s,\r\n },\r\n allowDeclaredValuesOnly: {\r\n defaultValue: false,\r\n isValid: isBoolean,\r\n requirementDescription: \"allowDeclaredValuesOnly must be true or false\",\r\n parse: toBoolOrNull,\r\n },\r\n}\r\n\r\nconst typeConstraints = [\r\n makerule(\r\n (val, opts) =>\r\n val === null || opts.maxLength === null || val.length <= opts.maxLength,\r\n (val, opts) => `value exceeds maximum length of ${opts.maxLength}`\r\n ),\r\n makerule(\r\n (val, opts) =>\r\n val === null ||\r\n opts.allowDeclaredValuesOnly === false ||\r\n includes(val)(opts.values),\r\n val => `\"${val}\" does not exist in the list of allowed values`\r\n ),\r\n]\r\n\r\nexport default getDefaultExport(\r\n \"string\",\r\n stringTryParse,\r\n stringFunctions,\r\n options,\r\n typeConstraints,\r\n \"abcde\",\r\n str => str\r\n)\r\n"],"file":"string.js"}
|
|
@ -1,90 +0,0 @@
|
|||
"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.getDefaultExport = exports.parsedSuccess = exports.parsedFailed = exports.makerule = exports.validateTypeConstraints = exports.typeFunctions = exports.getNewValue = exports.getSafeValueParser = exports.getSafeFieldParser = void 0;var _lodash = require("lodash");
|
||||
var _fp = require("lodash/fp");
|
||||
var _index = require("../../common/index.js");function _createForOfIteratorHelper(o) {if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) {if (Array.isArray(o) || (o = _unsupportedIterableToArray(o))) {var i = 0;var F = function F() {};return { s: F, n: function n() {if (i >= o.length) return { done: true };return { done: false, value: o[i++] };}, e: function e(_e) {throw _e;}, f: F };}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");}var it,normalCompletion = true,didErr = false,err;return { s: function s() {it = o[Symbol.iterator]();}, n: function n() {var step = it.next();normalCompletion = step.done;return step;}, e: function e(_e2) {didErr = true;err = _e2;}, f: function f() {try {if (!normalCompletion && it["return"] != null) it["return"]();} finally {if (didErr) throw err;}} };}function _unsupportedIterableToArray(o, minLen) {if (!o) return;if (typeof o === "string") return _arrayLikeToArray(o, minLen);var n = Object.prototype.toString.call(o).slice(8, -1);if (n === "Object" && o.constructor) n = o.constructor.name;if (n === "Map" || n === "Set") return Array.from(n);if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);}function _arrayLikeToArray(arr, len) {if (len == null || len > arr.length) len = arr.length;for (var i = 0, arr2 = new Array(len); i < len; i++) {arr2[i] = arr[i];}return arr2;}
|
||||
|
||||
var getSafeFieldParser = function getSafeFieldParser(tryParse, defaultValueFunctions) {return function (
|
||||
field,
|
||||
record)
|
||||
{
|
||||
if ((0, _fp.has)(field.name)(record)) {
|
||||
return getSafeValueParser(
|
||||
tryParse,
|
||||
defaultValueFunctions)(
|
||||
record[field.name]);
|
||||
}
|
||||
return defaultValueFunctions[field.getUndefinedValue]();
|
||||
};};exports.getSafeFieldParser = getSafeFieldParser;
|
||||
|
||||
var getSafeValueParser = function getSafeValueParser(
|
||||
tryParse,
|
||||
defaultValueFunctions) {return (
|
||||
function (value) {
|
||||
var parsed = tryParse(value);
|
||||
if (parsed.success) {
|
||||
return parsed.value;
|
||||
}
|
||||
return defaultValueFunctions["default"]();
|
||||
});};exports.getSafeValueParser = getSafeValueParser;
|
||||
|
||||
var getNewValue = function getNewValue(tryParse, defaultValueFunctions) {return function (field) {
|
||||
var getInitialValue =
|
||||
(0, _fp.isUndefined)(field) || (0, _fp.isUndefined)(field.getInitialValue) ?
|
||||
"default" :
|
||||
field.getInitialValue;
|
||||
|
||||
return (0, _fp.has)(getInitialValue)(defaultValueFunctions) ?
|
||||
defaultValueFunctions[getInitialValue]() :
|
||||
getSafeValueParser(tryParse, defaultValueFunctions)(getInitialValue);
|
||||
};};exports.getNewValue = getNewValue;
|
||||
|
||||
var typeFunctions = function typeFunctions(specificFunctions) {return (
|
||||
(0, _lodash.merge)(
|
||||
{
|
||||
value: _fp.constant,
|
||||
"null": (0, _fp.constant)(null) },
|
||||
|
||||
specificFunctions));};exports.typeFunctions = typeFunctions;
|
||||
|
||||
|
||||
var validateTypeConstraints = function validateTypeConstraints(validationRules) {return function (field, record) {
|
||||
var fieldValue = record[field.name];
|
||||
var validateRule = function validateRule(r) {return (
|
||||
!r.isValid(fieldValue, field.typeOptions) ?
|
||||
r.getMessage(fieldValue, field.typeOptions) :
|
||||
"");};
|
||||
|
||||
var errors = [];var _iterator = _createForOfIteratorHelper(
|
||||
validationRules),_step;try {for (_iterator.s(); !(_step = _iterator.n()).done;) {var r = _step.value;
|
||||
var err = validateRule(r);
|
||||
if ((0, _index.isNotEmpty)(err)) errors.push(err);
|
||||
}} catch (err) {_iterator.e(err);} finally {_iterator.f();}
|
||||
|
||||
return errors;
|
||||
};};exports.validateTypeConstraints = validateTypeConstraints;
|
||||
|
||||
var _getDefaultOptions = (0, _fp.mapValues)(function (v) {return v.defaultValue;});
|
||||
|
||||
var makerule = function makerule(isValid, getMessage) {return { isValid: isValid, getMessage: getMessage };};exports.makerule = makerule;
|
||||
var parsedFailed = function parsedFailed(val) {return { success: false, value: val };};exports.parsedFailed = parsedFailed;
|
||||
var parsedSuccess = function parsedSuccess(val) {return { success: true, value: val };};exports.parsedSuccess = parsedSuccess;
|
||||
var getDefaultExport = function getDefaultExport(
|
||||
name,
|
||||
tryParse,
|
||||
functions,
|
||||
options,
|
||||
validationRules,
|
||||
sampleValue,
|
||||
_stringify) {return (
|
||||
{
|
||||
getNew: getNewValue(tryParse, functions),
|
||||
safeParseField: getSafeFieldParser(tryParse, functions),
|
||||
safeParseValue: getSafeValueParser(tryParse, functions),
|
||||
tryParse: tryParse,
|
||||
name: name,
|
||||
getDefaultOptions: function getDefaultOptions() {return _getDefaultOptions((0, _fp.cloneDeep)(options));},
|
||||
optionDefinitions: options,
|
||||
validateTypeConstraints: validateTypeConstraints(validationRules),
|
||||
sampleValue: sampleValue,
|
||||
stringify: function stringify(val) {return val === null || val === undefined ? "" : _stringify(val);},
|
||||
getDefaultValue: functions["default"] });};exports.getDefaultExport = getDefaultExport;
|
||||
//# sourceMappingURL=typeHelpers.js.map
|
File diff suppressed because one or more lines are too long
|
@ -1,4 +1,3 @@
|
|||
export { validateRecord } from "./records/validateRecord";
|
||||
export { events } from "./common/events";
|
||||
export { safeParseField } from "./schema/types";
|
||||
export { default as schemaValidator } from "./schemaValidation";
|
|
@ -1,16 +0,0 @@
|
|||
import { generate } from "shortid"
|
||||
|
||||
export const getNewRecord = (schema, modelName) => {
|
||||
const model = schema.findModel(modelName)
|
||||
|
||||
const record = {
|
||||
_id: generate(),
|
||||
modelId: model._id,
|
||||
}
|
||||
|
||||
for (let field in model.schema.properties) {
|
||||
record[field] = field.default
|
||||
}
|
||||
|
||||
return record
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
export const getNewRecordValidationRule = (
|
||||
invalidField,
|
||||
messageWhenInvalid,
|
||||
expressionWhenValid
|
||||
) => ({
|
||||
invalidField,
|
||||
messageWhenInvalid,
|
||||
expressionWhenValid,
|
||||
})
|
||||
|
||||
export const commonRecordValidationRules = {
|
||||
fieldNotEmpty: fieldName =>
|
||||
getNewRecordValidationRule(
|
||||
fieldName,
|
||||
`${fieldName} is empty`,
|
||||
`record['${fieldName}'] && record['${fieldName}'].length > 0`
|
||||
),
|
||||
|
||||
fieldBetween: (fieldName, min, max) =>
|
||||
getNewRecordValidationRule(
|
||||
fieldName,
|
||||
`${fieldName} must be between ${min.toString()} and ${max.toString()}`,
|
||||
`record['${fieldName}'] >= ${min} && record['${fieldName}'] <= ${max} `
|
||||
),
|
||||
|
||||
fieldGreaterThan: (fieldName, min, max) =>
|
||||
getNewRecordValidationRule(
|
||||
fieldName,
|
||||
`${fieldName} must be greater than ${min.toString()} and ${max.toString()}`,
|
||||
`record['${fieldName}'] >= ${min} `
|
||||
),
|
||||
}
|
|
@ -1,85 +0,0 @@
|
|||
import { map, reduce, filter, isEmpty, flatten, each, union } from "lodash/fp";
|
||||
import { compileCode } from "../common/compileCode";
|
||||
import {
|
||||
validateFieldParse,
|
||||
validateTypeConstraints,
|
||||
} from "../schema/types/index.js"
|
||||
import { $, isNonEmptyString } from "../common/index.js"
|
||||
|
||||
const fieldParseError = (fieldName, value) => ({
|
||||
fields: [fieldName],
|
||||
message: `Could not parse field ${fieldName}:${value}`,
|
||||
})
|
||||
|
||||
const validateAllFieldParse = (record, model) =>
|
||||
$(model.fields, [
|
||||
map(f => ({ name: f.name, parseResult: validateFieldParse(f, record) })),
|
||||
reduce((errors, f) => {
|
||||
if (f.parseResult.success) return errors
|
||||
errors.push(fieldParseError(f.name, f.parseResult.value))
|
||||
return errors
|
||||
}, []),
|
||||
])
|
||||
|
||||
const validateAllTypeConstraints = (record, model) => {
|
||||
const errors = []
|
||||
for (const field of model.fields) {
|
||||
$(validateTypeConstraints(field, record), [
|
||||
filter(isNonEmptyString),
|
||||
map(m => ({ message: m, fields: [field.name] })),
|
||||
each(e => errors.push(e)),
|
||||
])
|
||||
}
|
||||
return errors
|
||||
}
|
||||
|
||||
const runRecordValidationRules = (record, model) => {
|
||||
const runValidationRule = rule => {
|
||||
const isValid = compileCode(rule.expressionWhenValid)
|
||||
const expressionContext = { record }
|
||||
return isValid(expressionContext)
|
||||
? { valid: true }
|
||||
: {
|
||||
valid: false,
|
||||
fields: rule.invalidFields,
|
||||
message: rule.messageWhenInvalid,
|
||||
}
|
||||
}
|
||||
|
||||
return $(model.validationRules, [
|
||||
map(runValidationRule),
|
||||
flatten,
|
||||
filter(r => r.valid === false),
|
||||
map(r => ({ fields: r.fields, message: r.message })),
|
||||
])
|
||||
}
|
||||
|
||||
export const validateRecord = (schema, record) => {
|
||||
const model = schema.findModel(record._modelId)
|
||||
const fieldParseFails = validateAllFieldParse(record, model)
|
||||
|
||||
// non parsing would cause further issues - exit here
|
||||
if (!isEmpty(fieldParseFails)) {
|
||||
return { isValid: false, errors: fieldParseFails }
|
||||
}
|
||||
|
||||
const recordValidationRuleFails = runRecordValidationRules(record, model)
|
||||
const typeContraintFails = validateAllTypeConstraints(record, model)
|
||||
|
||||
if (
|
||||
isEmpty(fieldParseFails) &&
|
||||
isEmpty(recordValidationRuleFails) &&
|
||||
isEmpty(typeContraintFails)
|
||||
) {
|
||||
return { isValid: true, errors: [] }
|
||||
}
|
||||
|
||||
return {
|
||||
isValid: false,
|
||||
errors: union(
|
||||
fieldParseFails,
|
||||
typeContraintFails,
|
||||
recordValidationRuleFails
|
||||
),
|
||||
}
|
||||
}
|
|
@ -10,7 +10,6 @@ exports.setPassword = async ctx => { };
|
|||
exports.changePassword = async ctx => {
|
||||
};
|
||||
|
||||
|
||||
exports.authenticate = async ctx => {
|
||||
const { username, password } = ctx.request.body;
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
const CouchDB = require("../../db");
|
||||
const { schemaValidator } = require("../../../common");
|
||||
const { schemaValidator } = require("../../../common/lib");
|
||||
|
||||
exports.save = async function(ctx) {
|
||||
const db = new CouchDB(ctx.params.instanceId);
|
|
@ -1,10 +1,10 @@
|
|||
const Router = require("@koa/router")
|
||||
const session = require("./session")
|
||||
const session = require("../middleware/session")
|
||||
const StatusCodes = require("../utilities/statusCodes")
|
||||
const { resolve } = require("path")
|
||||
const { homedir } = require("os")
|
||||
const send = require("koa-send")
|
||||
const routeHandlers = require("./routeHandlers")
|
||||
const routeHandlers = require("../middleware/routeHandlers")
|
||||
const {
|
||||
componentLibraryInfo,
|
||||
} = require("../utilities/builder")
|
||||
|
@ -147,8 +147,8 @@ module.exports = app => {
|
|||
// Legacy Routes
|
||||
router.use(userRoutes.routes());
|
||||
router.use(userRoutes.allowedMethods());
|
||||
router.use(appsRoutes.routes())
|
||||
router.use(appsRoutes.allowedMethods());
|
||||
// router.use(appsRoutes.routes())
|
||||
// router.use(appsRoutes.allowedMethods());
|
||||
router.use(componentRoutes.routes());
|
||||
router.use(componentRoutes.allowedMethods());
|
||||
router.use(pageRoutes.routes());
|
|
@ -0,0 +1,132 @@
|
|||
const Router = require("@koa/router");
|
||||
const StatusCodes = require("../../utilities/statusCodes")
|
||||
const routeHandlers = require("../../middleware/routeHandlers")
|
||||
|
||||
const router = Router();
|
||||
|
||||
// async function isAuthenticated(ctx, next) {
|
||||
// if (ctx.isAuthenticated) {
|
||||
// await next()
|
||||
// } else {
|
||||
// ctx.response.status = StatusCodes.UNAUTHORIZED
|
||||
// }
|
||||
// }
|
||||
|
||||
// router.use(isAuthenticated)
|
||||
|
||||
// router.post(
|
||||
// "/_builder/instance/:appname/:instanceid/api/upgradeData",
|
||||
// routeHandlers.upgradeData
|
||||
// )
|
||||
|
||||
// router.post("/:appname/api/changeMyPassword", routeHandlers.changeMyPassword)
|
||||
|
||||
// router.post(
|
||||
// "/_builder/instance/:appname/:instanceid/api/changeMyPassword",
|
||||
// routeHandlers.changeMyPassword
|
||||
// )
|
||||
|
||||
router.post(
|
||||
"/:appname/api/executeAction/:actionname",
|
||||
routeHandlers.executeAction
|
||||
)
|
||||
|
||||
router.post(
|
||||
"/_builder/instance/:appname/:instanceid/api/executeAction/:actionname",
|
||||
routeHandlers.executeAction
|
||||
)
|
||||
|
||||
// router.post("/:appname/api/createUser", routeHandlers.createUser)
|
||||
|
||||
// router.post(
|
||||
// "/_builder/instance/:appname/:instanceid/api/createUser",
|
||||
// routeHandlers.createUser
|
||||
// )
|
||||
|
||||
// router.post("/:appname/api/enableUser", routeHandlers.enableUser)
|
||||
|
||||
// router.post(
|
||||
// "/_builder/instance/:appname/:instanceid/api/enableUser",
|
||||
// routeHandlers.enableUser
|
||||
// )
|
||||
|
||||
// router.post("/:appname/api/disableUser", routeHandlers.disableUser)
|
||||
|
||||
// router.post(
|
||||
// "/_builder/instance/:appname/:instanceid/api/disableUser",
|
||||
// routeHandlers.disableUser
|
||||
// )
|
||||
|
||||
// router.get("/:appname/api/users", routeHandlers.getUsers)
|
||||
|
||||
// router.get(
|
||||
// "/_builder/instance/:appname/:instanceid/api/users",
|
||||
// routeHandlers.getUsers
|
||||
// )
|
||||
|
||||
// router.get("/:appname/api/accessLevels", routeHandlers.getAccessLevels)
|
||||
|
||||
// router.get(
|
||||
// "/_builder/instance/:appname/:instanceid/api/accessLevels",
|
||||
// routeHandlers.getAccessLevels
|
||||
// )
|
||||
|
||||
// router.get("/:appname/api/listRecords/*", routeHandlers.listRecordsGet)
|
||||
|
||||
// router.get(
|
||||
// "/_builder/instance/:appname/:instanceid/api/listRecords/*",
|
||||
// routeHandlers.listRecordsGet
|
||||
// )
|
||||
|
||||
// router.post("/:appname/api/listRecords/*", routeHandlers.listRecordsPost)
|
||||
|
||||
// router.post(
|
||||
// "/_builder/instance/:appname/:instanceid/api/listRecords/*",
|
||||
// routeHandlers.listRecordsPost
|
||||
// )
|
||||
|
||||
// router.post("/:appname/api/aggregates/*", routeHandlers.aggregatesPost)
|
||||
|
||||
// router.post(
|
||||
// "/_builder/instance/:appname/:instanceid/api/aggregates/*",
|
||||
// routeHandlers.aggregatesPost
|
||||
// )
|
||||
|
||||
// router.post("/:appname/api/files/*", routeHandlers.postFiles)
|
||||
|
||||
// router.post(
|
||||
// "/_builder/instance/:appname/:instanceid/api/files/*",
|
||||
// routeHandlers.postFiles
|
||||
// )
|
||||
|
||||
// router.post("/:appname/api/record/*", routeHandlers.saveRecord)
|
||||
|
||||
// router.post(
|
||||
// "/_builder/instance/:appname/:instanceid/api/record/*",
|
||||
// routeHandlers.saveRecord
|
||||
// )
|
||||
|
||||
// router.get("/:appname/api/lookup_field/*", routeHandlers.lookupField)
|
||||
|
||||
// router.get(
|
||||
// "/_builder/instance/:appname/:instanceid/api/lookup_field/*",
|
||||
// routeHandlers.lookupField
|
||||
// )
|
||||
|
||||
// router.get("/:appname/api/record/*", routeHandlers.getRecord)
|
||||
|
||||
// router.get(
|
||||
// "/_builder/instance/:appname/:instanceid/api/record/*",
|
||||
// routeHandlers.getRecord
|
||||
// )
|
||||
|
||||
// router.del("/:appname/api/record/*", routeHandlers.deleteRecord)
|
||||
|
||||
// router.del(
|
||||
// "/_builder/instance/:appname/:instanceid/api/record/*",
|
||||
// routeHandlers.deleteRecord
|
||||
// )
|
||||
|
||||
// router.post("/:appname/api/apphierarchy", routeHandlers.saveAppHierarchy)
|
||||
|
||||
module.exports = router
|
|
@ -18,22 +18,22 @@ router.get("/_builder/:appname/componentlibrary", async ctx => {
|
|||
await send(ctx, info.components._lib || "index.js", { root: info.libDir })
|
||||
})
|
||||
|
||||
router.get("/_builder/api/:appname/components", async ctx => {
|
||||
try {
|
||||
ctx.body = getComponentDefinitions(
|
||||
ctx.config,
|
||||
ctx.params.appname,
|
||||
ctx.query.lib
|
||||
)
|
||||
ctx.response.status = StatusCodes.OK
|
||||
} catch (e) {
|
||||
if (e.status) {
|
||||
ctx.response.status = e.status
|
||||
} else {
|
||||
throw e
|
||||
}
|
||||
}
|
||||
})
|
||||
// router.get("/_builder/api/:appname/components", async ctx => {
|
||||
// try {
|
||||
// ctx.body = getComponentDefinitions(
|
||||
// ctx.config,
|
||||
// ctx.params.appname,
|
||||
// ctx.query.lib
|
||||
// )
|
||||
// ctx.response.status = StatusCodes.OK
|
||||
// } catch (e) {
|
||||
// if (e.status) {
|
||||
// ctx.response.status = e.status
|
||||
// } else {
|
||||
// throw e
|
||||
// }
|
||||
// }
|
||||
// })
|
||||
|
||||
router.get("/_builder/api/:appname/componentlibrary", async ctx => {
|
||||
const info = await componentLibraryInfo(
|
|
@ -1,13 +1,11 @@
|
|||
const pageRoutes = require("./pages");
|
||||
const componentRoutes = require("./components");
|
||||
const userRoutes = require("./user");
|
||||
const appsRoutes = require("./apps");
|
||||
const authenticatedRoutes = require("./authenticated");
|
||||
|
||||
module.exports = {
|
||||
pageRoutes,
|
||||
componentRoutes,
|
||||
appsRoutes,
|
||||
userRoutes,
|
||||
authenticatedRoutes
|
||||
};
|
|
@ -0,0 +1,12 @@
|
|||
const Router = require("@koa/router");
|
||||
const controller = require("../../controllers/page");
|
||||
|
||||
const router = Router();
|
||||
|
||||
router
|
||||
.get("/api/:instanceId/pages", controller.fetch)
|
||||
.post("/api/:instanceId/pages", controller.save)
|
||||
.delete("/api/:instanceId/:pageId/:revId", controller.destroy);
|
||||
|
||||
|
||||
module.exports = router;
|
|
@ -0,0 +1,12 @@
|
|||
const Router = require("@koa/router");
|
||||
const controller = require("../../controllers/screen");
|
||||
|
||||
const router = Router();
|
||||
|
||||
router
|
||||
.get("/api/:instanceId/screens", controller.fetch)
|
||||
.post("/api/:instanceId/screens", controller.save)
|
||||
.delete("/api/:instanceId/:screenId/:revId", controller.destroy);
|
||||
|
||||
|
||||
module.exports = router;
|
|
@ -0,0 +1,32 @@
|
|||
const Router = require("@koa/router")
|
||||
|
||||
const router = new Router()
|
||||
|
||||
// router.post("/:appname/api/authenticate", routeHandlers.authenticate)
|
||||
|
||||
// router.post(
|
||||
// "/_builder/instance/:appname/:instanceid/api/authenticate",
|
||||
// routeHandlers.authenticate
|
||||
// )
|
||||
|
||||
// router.post(
|
||||
// "/_builder/instance/:appname/:instanceid/api/setPasswordFromTemporaryCode",
|
||||
// routeHandlers.setPasswordFromTemporaryCode
|
||||
// )
|
||||
|
||||
// router.post(
|
||||
// "/_builder/instance/:appname/:instanceid/api/createTemporaryAccess",
|
||||
// routeHandlers.createTemporaryAccess
|
||||
// )
|
||||
|
||||
// router.post(
|
||||
// "/:appname/api/createTemporaryAccess",
|
||||
// routeHandlers.createTemporaryAccess
|
||||
// )
|
||||
|
||||
// router.post(
|
||||
// "/:appname/api/setPasswordFromTemporaryCode",
|
||||
// routeHandlers.setPasswordFromTemporaryCode
|
||||
// )
|
||||
|
||||
module.exports = router
|
|
@ -1,6 +1,6 @@
|
|||
const Koa = require("koa")
|
||||
const logger = require("koa-logger");
|
||||
const router = require("./middleware/routers")
|
||||
const router = require("./api")
|
||||
const koaBody = require("koa-body")
|
||||
const app = new Koa()
|
||||
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
dist/
|
|
@ -1,175 +0,0 @@
|
|||
{
|
||||
"version":0,
|
||||
"levels":[
|
||||
{
|
||||
"name": "owner",
|
||||
"permissions": [
|
||||
{
|
||||
"type": "create record",
|
||||
"nodeKey": "/applications/1-{id}"
|
||||
},
|
||||
{
|
||||
"type": "update record",
|
||||
"nodeKey": "/applications/1-{id}"
|
||||
},
|
||||
{
|
||||
"type": "delete record",
|
||||
"nodeKey": "/applications/1-{id}"
|
||||
},
|
||||
{
|
||||
"type": "read record",
|
||||
"nodeKey": "/applications/1-{id}"
|
||||
},
|
||||
{
|
||||
"type": "create record",
|
||||
"nodeKey": "/applications/1-{id}/users/8-{id}"
|
||||
},
|
||||
{
|
||||
"type": "update record",
|
||||
"nodeKey": "/applications/1-{id}/users/8-{id}"
|
||||
},
|
||||
{
|
||||
"type": "delete record",
|
||||
"nodeKey": "/applications/1-{id}/users/8-{id}"
|
||||
},
|
||||
{
|
||||
"type": "read record",
|
||||
"nodeKey": "/applications/1-{id}/users/8-{id}"
|
||||
},
|
||||
{
|
||||
"type": "create record",
|
||||
"nodeKey": "/applications/1-{id}/instances/2-{id}"
|
||||
},
|
||||
{
|
||||
"type": "update record",
|
||||
"nodeKey": "/applications/1-{id}/instances/2-{id}"
|
||||
},
|
||||
{
|
||||
"type": "delete record",
|
||||
"nodeKey": "/applications/1-{id}/instances/2-{id}"
|
||||
},
|
||||
{
|
||||
"type": "read record",
|
||||
"nodeKey": "/applications/1-{id}/instances/2-{id}"
|
||||
},
|
||||
{
|
||||
"type": "create record",
|
||||
"nodeKey": "/applications/1-{id}/versions/3-{id}"
|
||||
},
|
||||
{
|
||||
"type": "update record",
|
||||
"nodeKey": "/applications/1-{id}/versions/3-{id}"
|
||||
},
|
||||
{
|
||||
"type": "delete record",
|
||||
"nodeKey": "/applications/1-{id}/versions/3-{id}"
|
||||
},
|
||||
{
|
||||
"type": "read record",
|
||||
"nodeKey": "/applications/1-{id}/versions/3-{id}"
|
||||
},
|
||||
{
|
||||
"type": "create record",
|
||||
"nodeKey": "/applications/1-{id}/sessions/16-{id}"
|
||||
},
|
||||
{
|
||||
"type": "update record",
|
||||
"nodeKey": "/applications/1-{id}/sessions/16-{id}"
|
||||
},
|
||||
{
|
||||
"type": "delete record",
|
||||
"nodeKey": "/applications/1-{id}/sessions/16-{id}"
|
||||
},
|
||||
{
|
||||
"type": "read record",
|
||||
"nodeKey": "/applications/1-{id}/sessions/16-{id}"
|
||||
},
|
||||
{
|
||||
"type": "create record",
|
||||
"nodeKey": "/sessions/17-{id}"
|
||||
},
|
||||
{
|
||||
"type": "update record",
|
||||
"nodeKey": "/sessions/17-{id}"
|
||||
},
|
||||
{
|
||||
"type": "delete record",
|
||||
"nodeKey": "/sessions/17-{id}"
|
||||
},
|
||||
{
|
||||
"type": "read record",
|
||||
"nodeKey": "/sessions/17-{id}"
|
||||
},
|
||||
{
|
||||
"type": "read index",
|
||||
"nodeKey": "/mastersessions_by_user"
|
||||
},
|
||||
{
|
||||
"type": "read index",
|
||||
"nodeKey": "/all_applications"
|
||||
},
|
||||
{
|
||||
"type": "read index",
|
||||
"nodeKey": "/applications/1-{id}/allinstances"
|
||||
},
|
||||
{
|
||||
"type": "read index",
|
||||
"nodeKey": "/applications/1-{id}/sessions_by_user"
|
||||
},
|
||||
{
|
||||
"type": "read index",
|
||||
"nodeKey": "/applications/1-{id}/user_name_lookup"
|
||||
},
|
||||
{
|
||||
"type": "read index",
|
||||
"nodeKey": "/applications/1-{id}/all_versions"
|
||||
},
|
||||
{
|
||||
"type": "read index",
|
||||
"nodeKey": "/applications/1-{id}/instances/2-{id}/users_on_this_instance"
|
||||
},
|
||||
{
|
||||
"type": "read index",
|
||||
"nodeKey": "/applications/1-{id}/versions/3-{id}/instances_for_this_version"
|
||||
},
|
||||
{
|
||||
"type": "read index",
|
||||
"nodeKey": "/applications/1-{id}/versions/3-{id}/instances_on_this_version"
|
||||
},
|
||||
{
|
||||
"type": "write templates"
|
||||
},
|
||||
{
|
||||
"type": "create user"
|
||||
},
|
||||
{
|
||||
"type": "set password"
|
||||
},
|
||||
{
|
||||
"type": "create temporary access"
|
||||
},
|
||||
{
|
||||
"type": "enable or disable user"
|
||||
},
|
||||
{
|
||||
"type": "write access levels"
|
||||
},
|
||||
{
|
||||
"type": "list users"
|
||||
},
|
||||
{
|
||||
"type": "list access levels"
|
||||
},
|
||||
{
|
||||
"type": "manage index"
|
||||
},
|
||||
{
|
||||
"type": "manage collection"
|
||||
},
|
||||
{
|
||||
"type": "set user access levels"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,527 +0,0 @@
|
|||
{
|
||||
"hierarchy": {
|
||||
"name": "root",
|
||||
"type": "root",
|
||||
"children": [
|
||||
{
|
||||
"name": "application",
|
||||
"type": "record",
|
||||
"fields": [
|
||||
{
|
||||
"name": "name",
|
||||
"type": "string",
|
||||
"typeOptions": {
|
||||
"maxLength": 500,
|
||||
"values": null,
|
||||
"allowDeclaredValuesOnly": false
|
||||
},
|
||||
"label": "Name",
|
||||
"getInitialValue": "default",
|
||||
"getUndefinedValue": "default"
|
||||
},
|
||||
{
|
||||
"name": "domain",
|
||||
"type": "string",
|
||||
"typeOptions": {
|
||||
"maxLength": 500,
|
||||
"values": null,
|
||||
"allowDeclaredValuesOnly": false
|
||||
},
|
||||
"label": "domain",
|
||||
"getInitialValue": "default",
|
||||
"getUndefinedValue": "default"
|
||||
},
|
||||
{
|
||||
"name": "application_resolve_strategy",
|
||||
"type": "string",
|
||||
"typeOptions": {
|
||||
"maxLength": 100,
|
||||
"values": [
|
||||
"domain",
|
||||
"path"
|
||||
],
|
||||
"allowDeclaredValuesOnly": true
|
||||
},
|
||||
"label": "Resolve Application By",
|
||||
"getInitialValue": "default",
|
||||
"getUndefinedValue": "default"
|
||||
},
|
||||
{
|
||||
"name": "defaultVersion",
|
||||
"type": "reference",
|
||||
"typeOptions": {
|
||||
"indexNodeKey": "/applications/1-{id}/all_versions",
|
||||
"reverseIndexNodeKeys": [
|
||||
"/applications/1-{id}/versions/3-{id}/isdefault"
|
||||
],
|
||||
"displayValue": "name"
|
||||
},
|
||||
"label": "Default Version",
|
||||
"getInitialValue": "default",
|
||||
"getUndefinedValue": "default"
|
||||
}
|
||||
],
|
||||
"children": [
|
||||
{
|
||||
"name": "user",
|
||||
"type": "record",
|
||||
"fields": [
|
||||
{
|
||||
"name": "name",
|
||||
"type": "string",
|
||||
"typeOptions": {
|
||||
"maxLength": 200,
|
||||
"values": null,
|
||||
"allowDeclaredValuesOnly": false
|
||||
},
|
||||
"label": "Name (unique)",
|
||||
"getInitialValue": "default",
|
||||
"getUndefinedValue": "default"
|
||||
},
|
||||
{
|
||||
"name": "active",
|
||||
"type": "bool",
|
||||
"typeOptions": {
|
||||
"allowNulls": false
|
||||
},
|
||||
"label": "Is Active",
|
||||
"getInitialValue": "default",
|
||||
"getUndefinedValue": "default"
|
||||
},
|
||||
{
|
||||
"name": "createdByMaster",
|
||||
"type": "bool",
|
||||
"typeOptions": {
|
||||
"allowNulls": false
|
||||
},
|
||||
"label": "Created by Master",
|
||||
"getInitialValue": "default",
|
||||
"getUndefinedValue": "default"
|
||||
},
|
||||
{
|
||||
"name": "instance",
|
||||
"type": "reference",
|
||||
"typeOptions": {
|
||||
"indexNodeKey": "/applications/1-{id}/allinstances",
|
||||
"reverseIndexNodeKeys": [
|
||||
"/applications/1-{id}/instances/2-{id}/users_on_this_instance"
|
||||
],
|
||||
"displayValue": "name"
|
||||
},
|
||||
"label": "Instance",
|
||||
"getInitialValue": "default",
|
||||
"getUndefinedValue": "default"
|
||||
}
|
||||
],
|
||||
"children": [],
|
||||
"validationRules": [],
|
||||
"nodeId": 8,
|
||||
"indexes": [],
|
||||
"allidsShardFactor": "64",
|
||||
"collectionName": "users",
|
||||
"isSingle": false
|
||||
},
|
||||
{
|
||||
"name": "instance",
|
||||
"type": "record",
|
||||
"fields": [
|
||||
{
|
||||
"name": "name",
|
||||
"type": "string",
|
||||
"typeOptions": {
|
||||
"maxLength": 1000,
|
||||
"values": null,
|
||||
"allowDeclaredValuesOnly": false
|
||||
},
|
||||
"label": "Name",
|
||||
"getInitialValue": "default",
|
||||
"getUndefinedValue": "default"
|
||||
},
|
||||
{
|
||||
"name": "active",
|
||||
"type": "bool",
|
||||
"typeOptions": {
|
||||
"allowNulls": false
|
||||
},
|
||||
"label": "Is Active",
|
||||
"getInitialValue": "default",
|
||||
"getUndefinedValue": "default"
|
||||
},
|
||||
{
|
||||
"name": "version",
|
||||
"type": "reference",
|
||||
"typeOptions": {
|
||||
"indexNodeKey": "/applications/1-{id}/all_versions",
|
||||
"reverseIndexNodeKeys": [
|
||||
"/applications/1-{id}/versions/3-{id}/instances_on_this_version"
|
||||
],
|
||||
"displayValue": "name"
|
||||
},
|
||||
"label": "Version",
|
||||
"getInitialValue": "default",
|
||||
"getUndefinedValue": "default"
|
||||
},
|
||||
{
|
||||
"name": "datastoreconfig",
|
||||
"type": "string",
|
||||
"typeOptions": {
|
||||
"maxLength": 1000,
|
||||
"values": null,
|
||||
"allowDeclaredValuesOnly": false
|
||||
},
|
||||
"label": "Datastore Config",
|
||||
"getInitialValue": "default",
|
||||
"getUndefinedValue": "default"
|
||||
}
|
||||
],
|
||||
"children": [],
|
||||
"validationRules": [],
|
||||
"nodeId": 2,
|
||||
"indexes": [
|
||||
{
|
||||
"name": "users_on_this_instance",
|
||||
"type": "index",
|
||||
"map": "return {...record};",
|
||||
"filter": "",
|
||||
"indexType": "reference",
|
||||
"getShardName": "",
|
||||
"getSortKey": "record.id",
|
||||
"aggregateGroups": [],
|
||||
"allowedModelNodeIds": [],
|
||||
"nodeId": 15
|
||||
}
|
||||
],
|
||||
"allidsShardFactor": 1,
|
||||
"collectionName": "instances",
|
||||
"isSingle": false
|
||||
},
|
||||
{
|
||||
"name": "version",
|
||||
"type": "record",
|
||||
"fields": [
|
||||
{
|
||||
"name": "name",
|
||||
"type": "string",
|
||||
"typeOptions": {
|
||||
"maxLength": 200,
|
||||
"values": null,
|
||||
"allowDeclaredValuesOnly": false
|
||||
},
|
||||
"label": "Name",
|
||||
"getInitialValue": "default",
|
||||
"getUndefinedValue": "default"
|
||||
},
|
||||
{
|
||||
"name": "defaultAccessLevel",
|
||||
"type": "string",
|
||||
"typeOptions": {
|
||||
"maxLength": 200,
|
||||
"values": null,
|
||||
"allowDeclaredValuesOnly": false
|
||||
},
|
||||
"label": "Default Access Level",
|
||||
"getInitialValue": "default",
|
||||
"getUndefinedValue": "default"
|
||||
}
|
||||
],
|
||||
"children": [],
|
||||
"validationRules": [],
|
||||
"nodeId": 3,
|
||||
"indexes": [
|
||||
{
|
||||
"name": "instances_for_this_version",
|
||||
"type": "index",
|
||||
"map": "return {name:record.name};",
|
||||
"filter": "",
|
||||
"indexType": "ancestor",
|
||||
"getShardName": "",
|
||||
"getSortKey": "record.id",
|
||||
"aggregateGroups": [],
|
||||
"allowedModelNodeIds": [],
|
||||
"nodeId": 9
|
||||
},
|
||||
{
|
||||
"name": "instances_on_this_version",
|
||||
"type": "index",
|
||||
"map": "return {...record};",
|
||||
"filter": "",
|
||||
"indexType": "reference",
|
||||
"getShardName": "",
|
||||
"getSortKey": "record.id",
|
||||
"aggregateGroups": [],
|
||||
"allowedModelNodeIds": [],
|
||||
"nodeId": 10
|
||||
},
|
||||
{
|
||||
"name": "isdefault",
|
||||
"type": "index",
|
||||
"map": "return {};",
|
||||
"filter": "",
|
||||
"indexType": "reference",
|
||||
"getShardName": "",
|
||||
"getSortKey": "record.id",
|
||||
"aggregateGroups": [],
|
||||
"allowedModelNodeIds": [],
|
||||
"nodeId": 28
|
||||
}
|
||||
],
|
||||
"allidsShardFactor": 1,
|
||||
"collectionName": "versions",
|
||||
"isSingle": false
|
||||
},
|
||||
{
|
||||
"name": "session",
|
||||
"type": "record",
|
||||
"fields": [
|
||||
{
|
||||
"name": "created",
|
||||
"type": "number",
|
||||
"typeOptions": {
|
||||
"minValue": 0,
|
||||
"maxValue": 99999999999999,
|
||||
"decimalPlaces": 0
|
||||
},
|
||||
"label": "Created",
|
||||
"getInitialValue": "default",
|
||||
"getUndefinedValue": "default"
|
||||
},
|
||||
{
|
||||
"name": "user_json",
|
||||
"type": "string",
|
||||
"typeOptions": {
|
||||
"maxLength": null,
|
||||
"values": null,
|
||||
"allowDeclaredValuesOnly": false
|
||||
},
|
||||
"label": "User Json",
|
||||
"getInitialValue": "default",
|
||||
"getUndefinedValue": "default"
|
||||
},
|
||||
{
|
||||
"name": "instanceDatastoreConfig",
|
||||
"type": "string",
|
||||
"typeOptions": {
|
||||
"maxLength": null,
|
||||
"values": null,
|
||||
"allowDeclaredValuesOnly": false
|
||||
},
|
||||
"label": "Instance Datastore Config",
|
||||
"getInitialValue": "default",
|
||||
"getUndefinedValue": "default"
|
||||
},
|
||||
{
|
||||
"name": "instanceKey",
|
||||
"type": "string",
|
||||
"typeOptions": {
|
||||
"maxLength": null,
|
||||
"values": null,
|
||||
"allowDeclaredValuesOnly": false
|
||||
},
|
||||
"label": "Instance Key",
|
||||
"getInitialValue": "default",
|
||||
"getUndefinedValue": "default"
|
||||
},
|
||||
{
|
||||
"name": "instanceVersion",
|
||||
"type": "string",
|
||||
"typeOptions": {
|
||||
"maxLength": null,
|
||||
"values": null,
|
||||
"allowDeclaredValuesOnly": false
|
||||
},
|
||||
"label": "Instance Version",
|
||||
"getInitialValue": "default",
|
||||
"getUndefinedValue": "default"
|
||||
},
|
||||
{
|
||||
"name": "username",
|
||||
"type": "string",
|
||||
"typeOptions": {
|
||||
"maxLength": null,
|
||||
"values": null,
|
||||
"allowDeclaredValuesOnly": false
|
||||
},
|
||||
"label": "User",
|
||||
"getInitialValue": "default",
|
||||
"getUndefinedValue": "default"
|
||||
}
|
||||
],
|
||||
"children": [],
|
||||
"validationRules": [],
|
||||
"nodeId": 16,
|
||||
"indexes": [],
|
||||
"allidsShardFactor": 1,
|
||||
"collectionName": "sessions",
|
||||
"isSingle": false
|
||||
}
|
||||
],
|
||||
"validationRules": [],
|
||||
"nodeId": 1,
|
||||
"indexes": [
|
||||
{
|
||||
"name": "allinstances",
|
||||
"type": "index",
|
||||
"map": "return {...record};",
|
||||
"filter": "",
|
||||
"indexType": "ancestor",
|
||||
"getShardName": "",
|
||||
"getSortKey": "record.id",
|
||||
"aggregateGroups": [],
|
||||
"allowedModelNodeIds": [
|
||||
2
|
||||
],
|
||||
"nodeId": 23
|
||||
},
|
||||
{
|
||||
"name": "sessions_by_user",
|
||||
"type": "index",
|
||||
"map": "return {username:record.username};",
|
||||
"filter": "",
|
||||
"indexType": "ancestor",
|
||||
"getShardName": "return record.username.substring(0,2)",
|
||||
"getSortKey": "record.id",
|
||||
"aggregateGroups": [],
|
||||
"allowedModelNodeIds": [
|
||||
16
|
||||
],
|
||||
"nodeId": 24
|
||||
},
|
||||
{
|
||||
"name": "user_name_lookup",
|
||||
"type": "index",
|
||||
"map": "return ({name:record.name, instanceKey:record.instance.key ? record.instance.key : '', instanceDatastoreConfig:record.instance.datastoreconfig ? record.instance.datastoreconfig : 'nothing'});",
|
||||
"filter": "",
|
||||
"indexType": "ancestor",
|
||||
"getShardName": "return record.name.substring(0,2)",
|
||||
"getSortKey": "record.id",
|
||||
"aggregateGroups": [],
|
||||
"allowedModelNodeIds": [
|
||||
8
|
||||
],
|
||||
"nodeId": 25
|
||||
},
|
||||
{
|
||||
"name": "all_versions",
|
||||
"type": "index",
|
||||
"map": "return {...record};",
|
||||
"filter": "",
|
||||
"indexType": "ancestor",
|
||||
"getShardName": "",
|
||||
"getSortKey": "record.id",
|
||||
"aggregateGroups": [],
|
||||
"allowedModelNodeIds": [
|
||||
3
|
||||
],
|
||||
"nodeId": 26
|
||||
}
|
||||
],
|
||||
"allidsShardFactor": 64,
|
||||
"collectionName": "applications",
|
||||
"isSingle": false
|
||||
},
|
||||
{
|
||||
"name": "mastersession",
|
||||
"type": "record",
|
||||
"fields": [
|
||||
{
|
||||
"name": "user_json",
|
||||
"type": "string",
|
||||
"typeOptions": {
|
||||
"maxLength": 10000,
|
||||
"values": null,
|
||||
"allowDeclaredValuesOnly": false
|
||||
},
|
||||
"label": "User Json",
|
||||
"getInitialValue": "default",
|
||||
"getUndefinedValue": "default"
|
||||
},
|
||||
{
|
||||
"name": "username",
|
||||
"type": "string",
|
||||
"typeOptions": {
|
||||
"maxLength": null,
|
||||
"values": null,
|
||||
"allowDeclaredValuesOnly": false
|
||||
},
|
||||
"label": "User",
|
||||
"getInitialValue": "default",
|
||||
"getUndefinedValue": "default"
|
||||
}
|
||||
],
|
||||
"children": [],
|
||||
"validationRules": [],
|
||||
"nodeId": 17,
|
||||
"indexes": [],
|
||||
"allidsShardFactor": 64,
|
||||
"collectionName": "sessions",
|
||||
"isSingle": false
|
||||
}
|
||||
],
|
||||
"pathMaps": [],
|
||||
"indexes": [
|
||||
{
|
||||
"name": "all_applications",
|
||||
"type": "index",
|
||||
"map": "return {...record};",
|
||||
"filter": "",
|
||||
"indexType": "ancestor",
|
||||
"getShardName": "",
|
||||
"getSortKey": "record.id",
|
||||
"aggregateGroups": [],
|
||||
"allowedModelNodeIds": [
|
||||
1
|
||||
],
|
||||
"nodeId": 22
|
||||
},
|
||||
{
|
||||
"name": "mastersessions_by_user",
|
||||
"type": "index",
|
||||
"map": "return {username:record.username};",
|
||||
"filter": "",
|
||||
"indexType": "ancestor",
|
||||
"getShardName": "return record.username.substring(0,2)",
|
||||
"getSortKey": "record.id",
|
||||
"aggregateGroups": [],
|
||||
"allowedModelNodeIds": [
|
||||
17
|
||||
],
|
||||
"nodeId": 27
|
||||
}
|
||||
],
|
||||
"nodeId": 0
|
||||
},
|
||||
"triggers": [
|
||||
{
|
||||
"actionName": "initialise_instance",
|
||||
"eventName": "recordApi:save:onRecordCreated",
|
||||
"optionsCreator": "return ({ instance:context.record, apis });",
|
||||
"condition": "context.record.type === \"instance\""
|
||||
},
|
||||
{
|
||||
"actionName": "create_user",
|
||||
"eventName": "recordApi:save:onRecordCreated",
|
||||
"optionsCreator": "return ({ user:context.record, apis });",
|
||||
"condition": "context.record.type === \"user\" && context.record.createdByMaster === true"
|
||||
}
|
||||
],
|
||||
"actions": [
|
||||
{
|
||||
"name": "initialise_instance",
|
||||
"behaviourSource": "main",
|
||||
"behaviourName": "initialiseInstance",
|
||||
"initialOptions": {}
|
||||
},
|
||||
{
|
||||
"name": "create_user",
|
||||
"behaviourSource": "main",
|
||||
"behaviourName": "createNewUser",
|
||||
"initialOptions": {}
|
||||
},
|
||||
{
|
||||
"name": "set_default_version",
|
||||
"behaviourSource": "main",
|
||||
"behaviourName": "setDefaultVersion",
|
||||
"initialOptions": {}
|
||||
}
|
||||
]
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue