@live-change/relations-plugin
Advanced tools
Comparing version 0.9.17 to 0.9.18
@@ -9,3 +9,4 @@ import { | ||
import { | ||
defineView, | ||
defineObjectView, | ||
defineRangeViews, | ||
defineSetAction, | ||
@@ -28,2 +29,3 @@ defineUpdateAction, | ||
context.reverseRelationWord = 'Bound' | ||
context.partialReverseRelationWord = 'Bound' | ||
@@ -33,8 +35,16 @@ defineProperties(context.model, context.others, context.otherPropertyNames) | ||
defineView({ ...config, access: config.readAccess }, context, | ||
defineObjectView({ ...config, access: config.readAccess }, context, | ||
config.readAccess || config.readAccessControl || config.writeAccessControl | ||
) | ||
defineRangeViews(config, context, | ||
config.listAccess || config.readAccess || config.listAccessControl | ||
) | ||
if(config.views) { | ||
for(const view of config.views) { | ||
defineView({ ...config, ...view }, context, !view.internal) | ||
if(view.type !== 'range') { | ||
defineObjectView({ ...config, ...view }, context, !view.internal) | ||
} else { | ||
defineRangeViews({ ...config, ...view }, context, !view.internal) | ||
} | ||
} | ||
@@ -41,0 +51,0 @@ } |
@@ -9,6 +9,6 @@ import { | ||
import { | ||
defineView, | ||
defineObjectView, defineRangeViews, | ||
defineSetAction, defineUpdateAction, defineResetAction, defineSetOrUpdateAction, | ||
defineSetTrigger, defineUpdateTrigger, defineSetOrUpdateTrigger, defineResetTrigger | ||
} from './singularRelationUtils.js' | ||
} from './singularRelationAnyUtils.js' | ||
import { defineDeleteAction, defineDeleteTrigger } from './singularRelationAnyUtils.js' | ||
@@ -21,2 +21,3 @@ | ||
context.reverseRelationWord = 'Bound' | ||
context.partialReverseRelationWord = 'Bound' | ||
@@ -26,7 +27,16 @@ defineAnyProperties(context.model, context.otherPropertyNames) | ||
defineView({ ...config, access: config.readAccess }, context, | ||
config.readAccess || config.readAccessControl || config.writeAccessControl) | ||
defineObjectView(config, context, | ||
config.singleAccess || config.readAccess || config.singleAccessControl || config.readAccessControl | ||
) | ||
defineRangeViews(config, context, | ||
config.listAccess || config.readAccess || config.listAccessControl || config.readAccessControl | ||
) | ||
if(config.views) { | ||
for(const view of config.views) { | ||
defineView({ ...config, ...view }, context, !view.internal) | ||
if(view.type !== 'range') { | ||
defineObjectView({ ...config, ...view }, context, !view.internal) | ||
} else { | ||
defineRangeViews({ ...config, ...view }, context, !view.internal) | ||
} | ||
} | ||
@@ -33,0 +43,0 @@ } |
{ | ||
"name": "@live-change/relations-plugin", | ||
"version": "0.9.17", | ||
"version": "0.9.18", | ||
"description": "", | ||
@@ -25,6 +25,6 @@ "main": "index.js", | ||
"dependencies": { | ||
"@live-change/framework": "^0.9.17", | ||
"@live-change/framework": "^0.9.18", | ||
"pluralize": "^8.0.0" | ||
}, | ||
"gitHead": "b3a9709d000e1a55a5c6e6bf2ad3f0ac5f5956dd" | ||
"gitHead": "d7fd7ad0a0ea331caea9dc8385439b9c637525ed" | ||
} |
@@ -10,3 +10,4 @@ import { | ||
import { | ||
defineView, | ||
defineObjectView, | ||
defineRangeViews, | ||
defineSetAction, | ||
@@ -29,2 +30,3 @@ defineUpdateAction, | ||
context.reverseRelationWord = 'Owned' | ||
context.partialReverseRelationWord = 'Owned' | ||
@@ -39,7 +41,15 @@ context.sameIdAsParent = true | ||
defineView({ ...config }, context, | ||
defineObjectView({ ...config }, context, | ||
config.readAccess || config.writeAccess || config.readAccessControl || config.writeAccessControl) | ||
defineRangeViews(config, context, | ||
config.listAccess || config.readAccess || config.listAccessControl | ||
) | ||
if(config.views) { | ||
for(const view of config.views) { | ||
defineView({ ...config, ...view }, context, !view.internal) | ||
if(view.type !== 'range') { | ||
defineObjectView({ ...config, ...view }, context, !view.internal) | ||
} else { | ||
defineRangeViews({ ...config, ...view }, context, !view.internal) | ||
} | ||
} | ||
@@ -46,0 +56,0 @@ } |
@@ -47,5 +47,10 @@ import { | ||
) | ||
if(config.views) { | ||
for(const view of config.views) { | ||
defineObjectView({ ...config, ...view }, context, !view.internal) | ||
if(view.type !== 'range') { | ||
defineObjectView({ ...config, ...view }, context, !view.internal) | ||
} else { | ||
defineRangeViews({ ...config, ...view }, context, !view.internal) | ||
} | ||
} | ||
@@ -52,0 +57,0 @@ } |
@@ -18,10 +18,10 @@ import App from '@live-change/framework' | ||
function createIdentifiersProperties(keys) { | ||
export function createIdentifiersProperties(keys) { | ||
const identifiers = {} | ||
if(keys) for(const key of keys) { | ||
identifiers[key] = { | ||
identifiers[key + 'Type'] = { | ||
type: String, | ||
validation: ['nonEmpty'] | ||
} | ||
identifiers[key + 'Type'] = { | ||
identifiers[key] = { | ||
type: String, | ||
@@ -37,13 +37,3 @@ validation: ['nonEmpty'] | ||
modelName, others, model } = context | ||
const viewProperties = {} | ||
for (let i = 0; i < others.length; i++) { | ||
viewProperties[otherPropertyNames[i]] = new PropertyDefinition({ | ||
type: 'String', | ||
validation: ['nonEmpty'] | ||
}) | ||
viewProperties[otherPropertyNames[i] + 'Type'] = new PropertyDefinition({ | ||
type: 'String', | ||
validation: ['nonEmpty'] | ||
}) | ||
} | ||
const viewProperties = createIdentifiersProperties(otherPropertyNames) | ||
const sourceAccessControl = external | ||
@@ -50,0 +40,0 @@ && (config.singleAccessControl || config.readAccessControl || config.writeAccessControl) |
@@ -6,16 +6,31 @@ import App from '@live-change/framework' | ||
import { | ||
extractIdentifiers, extractObjectData, generateId, extractIdParts, prepareAccessControl, cloneAndPrepareAccessControl | ||
extractIdentifiers, | ||
extractObjectData, | ||
generateId, | ||
extractIdParts, | ||
prepareAccessControl, | ||
cloneAndPrepareAccessControl, | ||
defineIndex | ||
} from './utils.js' | ||
import { fireChangeTriggers } from "./changeTriggers.js" | ||
import { extractTypeAndIdParts } from './utilsAny.js' | ||
import { allCombinations } from './combinations.js' | ||
import pluralize from 'pluralize' | ||
function defineView(config, context, external = true) { | ||
export function createIdentifiersProperties(keys, types) { | ||
const identifiers = {} | ||
if(keys) for(let i = 0; i < keys.length; i++) { | ||
const key = keys[i] | ||
identifiers[key] = { | ||
type: types?.[i] || String, | ||
validation: ['nonEmpty'] | ||
} | ||
} | ||
return identifiers | ||
} | ||
export function defineObjectView(config, context, external = true) { | ||
const { service, modelRuntime, otherPropertyNames, joinedOthersPropertyName, joinedOthersClassName, | ||
modelName, others, model } = context | ||
const viewProperties = {} | ||
for (let i = 0; i < others.length; i++) { | ||
viewProperties[otherPropertyNames[i]] = new PropertyDefinition({ | ||
type: others[i], | ||
validation: ['nonEmpty'] | ||
}) | ||
} | ||
const viewProperties = createIdentifiersProperties(otherPropertyNames, others) | ||
const viewName = config.name | ||
@@ -47,3 +62,77 @@ || ((config.prefix ? config.prefix + modelName : modelName[0].toLowerCase() + modelName.slice(1)) + (config.suffix || '')) | ||
function getSetFunction( validators, validationContext, config, context) { | ||
export function defineRangeViews(config, context, external = true) { | ||
const { service, modelRuntime, otherPropertyNames, joinedOthersPropertyName, joinedOthersClassName, | ||
modelName, others, model } = context | ||
const identifierCombinations = allCombinations(Object.keys(otherPropertyNames)).slice(0, -1) | ||
const sourceAccessControl = external | ||
&& (config.listAccessControl || config.readAccessControl || config.writeAccessControl) | ||
for(const combination of identifierCombinations) { | ||
const combinationKeys = combination.map(prop => otherPropertyNames[prop]) | ||
const combinationTypes = combination.map(prop => others[prop]) | ||
const propsUpperCase = combinationKeys.map(prop => prop[0].toUpperCase() + prop.slice(1)) | ||
const indexName = 'by' + combinationKeys.map(prop => prop[0].toUpperCase() + prop.slice(1)).join('And') | ||
const viewName = combinationKeys[0][0].toLowerCase() + combinationKeys[0].slice(1) + | ||
propsUpperCase.slice(1).join('And') + context.partialReverseRelationWord + pluralize(modelName) | ||
model.crud['rangeBy_'+combinationTypes.join('And')] = viewName | ||
//console.log("DEFINE RANGE VIEW", viewName, combination) | ||
const identifiers = createIdentifiersProperties(combinationKeys, combinationTypes) | ||
const accessControl = cloneAndPrepareAccessControl(sourceAccessControl, combinationKeys, combinationTypes) | ||
service.view({ | ||
name: viewName, | ||
properties: { | ||
...identifiers, | ||
...App.rangeProperties, | ||
}, | ||
internal: !external, | ||
access: external && (config.listAccess || config.readAccess), | ||
accessControl, | ||
daoPath(params, { client, context }) { | ||
const owner = [] | ||
for (const key of combination) owner.push(params[ownerPropertyNames[key]]) | ||
return modelRuntime().sortedIndexRangePath(indexName, owner, App.extractRange(params) ) | ||
} | ||
}) | ||
} | ||
const propsByType = {} | ||
for(let i = 0; i < otherPropertyNames.length; i++) { | ||
const prop = otherPropertyNames[i] | ||
const type = others[i] | ||
if(!propsByType[type]) propsByType[type] = [] | ||
propsByType[type].push(prop) | ||
} | ||
const multiPropsTypes = Object.keys(propsByType).filter(type => propsByType[type].length > 1) | ||
const typeCombinations = allCombinations(multiPropsTypes) | ||
for(const typeCombination of typeCombinations) { | ||
const typeNames = typeCombination.map(t => { | ||
const type = t.split('_')[1] | ||
return type[0].toUpperCase() + type.slice(1) | ||
}) | ||
const parametersNames = typeCombination | ||
.map(t => t.split('_').pop()) | ||
.map(t => t[0].toLowerCase() + t.slice(1)) | ||
const accessControl = cloneAndPrepareAccessControl(sourceAccessControl, parametersNames, typeCombination) | ||
const indexName = 'by'+typeNames.join('And') | ||
const viewName = typeNames.join('And') + context.partialReverseRelationWord + pluralize(modelName) | ||
model.crud['rangeBy_'+typeCombination.join('And')] = viewName | ||
//console.log("DEFINE TYPE RANGE VIEW", viewName, typeCombination) | ||
const identifiers = createIdentifiersProperties(parametersNames, typeCombination) | ||
service.view({ | ||
name: viewName, | ||
properties: { | ||
...identifiers, | ||
...App.rangeProperties, | ||
}, | ||
internal: !external, | ||
access: external && (config.listAccess || config.readAccess), | ||
accessControl, | ||
daoPath(params, { client, context }) { | ||
const owner = [] | ||
for (const key of parametersNames) owner.push(params[key]) | ||
return modelRuntime().sortedIndexRangePath(indexName, owner, App.extractRange(params) ) | ||
} | ||
}) | ||
} | ||
} | ||
export function getSetFunction( validators, validationContext, config, context) { | ||
const { | ||
@@ -71,3 +160,3 @@ service, app, model, objectType, | ||
function defineSetAction(config, context) { | ||
export function defineSetAction(config, context) { | ||
const { | ||
@@ -98,3 +187,3 @@ service, app, model, objectType, | ||
function defineSetTrigger(config, context) { | ||
export function defineSetTrigger(config, context) { | ||
const { | ||
@@ -121,3 +210,3 @@ service, app, model, objectType, | ||
function getUpdateFunction( validators, validationContext, config, context) { | ||
export function getUpdateFunction( validators, validationContext, config, context) { | ||
const { | ||
@@ -149,3 +238,3 @@ service, app, model, modelRuntime, objectType, | ||
function defineUpdateAction(config, context) { | ||
export function defineUpdateAction(config, context) { | ||
const { | ||
@@ -178,3 +267,3 @@ service, app, model, modelRuntime, objectType, | ||
function defineUpdateTrigger(config, context) { | ||
export function defineUpdateTrigger(config, context) { | ||
const { | ||
@@ -203,3 +292,3 @@ service, app, model, modelRuntime, objectType, | ||
function getSetOrUpdateFunction( validators, validationContext, config, context) { | ||
export function getSetOrUpdateFunction( validators, validationContext, config, context) { | ||
const { | ||
@@ -229,3 +318,3 @@ service, app, model, modelRuntime, objectType, | ||
function defineSetOrUpdateAction(config, context) { | ||
export function defineSetOrUpdateAction(config, context) { | ||
const { | ||
@@ -258,3 +347,3 @@ service, app, model, modelRuntime, objectType, | ||
function defineSetOrUpdateTrigger(config, context) { | ||
export function defineSetOrUpdateTrigger(config, context) { | ||
const { | ||
@@ -283,3 +372,3 @@ service, app, model, modelRuntime, objectType, | ||
function getResetFunction( validators, validationContext, config, context) { | ||
export function getResetFunction( validators, validationContext, config, context) { | ||
const { | ||
@@ -307,3 +396,3 @@ service, modelRuntime, modelPropertyName, objectType, | ||
function defineDeleteAction(config, context) { | ||
export function defineDeleteAction(config, context) { | ||
const { | ||
@@ -315,3 +404,2 @@ service, modelRuntime, modelPropertyName, objectType, identifiers, | ||
const actionName = 'delete' + modelName | ||
model.crud.delete = actionName | ||
const sourceAccessControl = config.resetAccessControl || config.writeAccessControl | ||
@@ -342,3 +430,3 @@ const accessControl = cloneAndPrepareAccessControl( | ||
function defineDeleteTrigger(config, context) { | ||
export function defineDeleteTrigger(config, context) { | ||
const { | ||
@@ -370,3 +458,3 @@ service, modelRuntime, modelPropertyName, objectType, | ||
function defineResetAction(config, context) { | ||
export function defineResetAction(config, context) { | ||
const { | ||
@@ -378,2 +466,3 @@ service, modelRuntime, modelPropertyName, objectType, identifiers, | ||
const actionName = 'reset' + modelName | ||
model.crud.delete = actionName | ||
const properties = {} | ||
@@ -406,3 +495,3 @@ for (let i = 0; i < others.length; i++) { | ||
function defineResetTrigger(config, context) { | ||
export function defineResetTrigger(config, context) { | ||
const { | ||
@@ -435,9 +524,1 @@ service, modelRuntime, modelPropertyName, objectType, | ||
} | ||
export { | ||
defineView, | ||
defineSetAction, defineUpdateAction, defineSetOrUpdateAction, defineResetAction, defineDeleteAction, | ||
defineSetTrigger, defineUpdateTrigger, defineSetOrUpdateTrigger, defineDeleteTrigger, defineResetTrigger | ||
} |
21
utils.js
@@ -44,6 +44,7 @@ import App from "@live-change/framework" | ||
export function defineIndex(model, what, props) { | ||
export function defineIndex(model, what, props, multi = undefined) { | ||
console.log("DEFINE INDEX", model.name, what, props) | ||
model.indexes['by' + what] = new IndexDefinition({ | ||
property: props | ||
property: props, | ||
multi | ||
}) | ||
@@ -62,2 +63,18 @@ } | ||
} | ||
const propsByType = {} | ||
for(const prop in props) { | ||
const type = types[prop] | ||
if(!propsByType[type]) propsByType[type] = [] | ||
propsByType[type].push(prop) | ||
} | ||
const multiPropsTypes = Object.keys(propsByType).filter(type => propsByType[type].length > 1) | ||
const typeCombinations = allCombinations(multiPropsTypes) | ||
for(const typeCombination of typeCombinations) { | ||
const typeNames = typeCombination.map(t => { | ||
const type = t.split('_')[1] | ||
return type[0].toUpperCase() + type.slice(1) | ||
}) | ||
const typeProps = typeCombination.map(type => propsByType[type]) | ||
defineIndex(model, typeNames.join('And'), typeProps, true) | ||
} | ||
} | ||
@@ -64,0 +81,0 @@ |
@@ -44,7 +44,7 @@ import App from "@live-change/framework" | ||
for (let i = 0; i < names.length; i++) { | ||
identifiers[names[i]] = new PropertyDefinition({ | ||
identifiers[names[i]+'Type'] = new PropertyDefinition({ | ||
type: String, | ||
validation: ['nonEmpty'] | ||
}) | ||
identifiers[names[i]+'Type'] = new PropertyDefinition({ | ||
identifiers[names[i]] = new PropertyDefinition({ | ||
type: String, | ||
@@ -115,5 +115,15 @@ validation: ['nonEmpty'] | ||
const otherPropertyNames = (Array.isArray(config.to) ? config.to : [config.to ?? 'owner']) | ||
.map(other => other.name ? other.name : other) | ||
const to = (Array.isArray(config.to) ? config.to : [config.to ?? 'owner']) | ||
const otherPropertyNames = to.map(other => other.name ? other.name : other) | ||
const otherPossibleTypes = to.map(other => { | ||
const name = other.name ? other.name : other | ||
const typesConfig = config[name + 'Types'] || [] | ||
const otherTypes = other.types || [] | ||
return Array.from(new Set( | ||
typesConfig.concat(otherTypes).map(t => t.getTypeName ? t.getTypeName() : t) | ||
)) | ||
}) | ||
const writeableProperties = modelProperties || config.writeableProperties | ||
@@ -126,3 +136,6 @@ const others = otherPropertyNames.map(other => other.slice(0, 1).toUpperCase() + other.slice(1)) | ||
const { parentsTypes } = config | ||
const parentsTypes = Array.from(new Set( | ||
(config.parentsTypes || []) | ||
.concat(otherPossibleTypes.filter(x => !!x).flat() | ||
))) | ||
@@ -132,3 +145,3 @@ const context = { | ||
otherPropertyNames, joinedOthersPropertyName, modelName, writeableProperties, joinedOthersClassName, others, | ||
objectType, parentsTypes | ||
objectType, parentsTypes, otherPossibleTypes | ||
} | ||
@@ -135,0 +148,0 @@ |
144903
3658