@json-layout/core
Advanced tools
Comparing version 0.24.1 to 0.25.0
{ | ||
"name": "@json-layout/core", | ||
"version": "0.24.1", | ||
"version": "0.25.0", | ||
"description": "Compilation and state management utilities for JSON Layout.", | ||
@@ -5,0 +5,0 @@ "type": "module", |
@@ -63,3 +63,3 @@ // compileStatic is meant to produce a serializable result | ||
/** @type {import('ajv').Options} */ | ||
const ajvOpts = { allErrors: true, strict: false } | ||
const ajvOpts = { allErrors: true, strict: false, verbose: true } | ||
if (partialOptions.ajvOptions) Object.assign(ajvOpts, partialOptions.ajvOptions) | ||
@@ -130,2 +130,4 @@ if (partialOptions.code) ajvOpts.code = { source: true, esm: true, lines: true } | ||
const skeletonTrees = {} | ||
/** @type {Record<string, import('./types.js').SkeletonNode>} */ | ||
const skeletonNodes = {} | ||
@@ -142,2 +144,3 @@ // makeSkeletonTree also mutates the schema (adding some error messages) | ||
skeletonTrees, | ||
skeletonNodes, | ||
validatePointers, | ||
@@ -193,2 +196,3 @@ validationErrors, | ||
skeletonTrees, | ||
skeletonNodes, | ||
validates, | ||
@@ -195,0 +199,0 @@ validationErrors, |
@@ -84,2 +84,3 @@ // import Debug from 'debug' | ||
skeletonTrees: clone(compiledLayout.skeletonTrees), | ||
skeletonNodes: clone(compiledLayout.skeletonNodes), | ||
normalizedLayouts: clone(compiledLayout.normalizedLayouts), | ||
@@ -86,0 +87,0 @@ validates: {}, |
@@ -12,2 +12,3 @@ // import Debug from 'debug' | ||
* @param {Record<string, import('./types.js').SkeletonTree>} skeletonTrees | ||
* @param {Record<string, import('./types.js').SkeletonNode>} skeletonNodes | ||
* @param {string[]} validates | ||
@@ -18,4 +19,3 @@ * @param {Record<string, string[]>} validationErrors | ||
* @param {string | number} key | ||
* @param {string} currentPointer | ||
* @param {string | null} parentPointer | ||
* @param {string} pointer | ||
* @param {boolean} required | ||
@@ -33,2 +33,3 @@ * @param {string} [condition] | ||
skeletonTrees, | ||
skeletonNodes, | ||
validates, | ||
@@ -39,4 +40,3 @@ validationErrors, | ||
key, | ||
currentPointer, | ||
parentPointer, | ||
pointer, | ||
required, | ||
@@ -49,11 +49,13 @@ condition, | ||
let schema = rawSchema | ||
let pointer = currentPointer | ||
let refPointer = pointer | ||
let refFragment | ||
rawSchema.__pointer = pointer | ||
if (schema.$ref) { | ||
[refFragment, schemaId, pointer] = getJSONRef(sourceSchemaId, schema.$ref) | ||
schema = {...rawSchema, ...refFragment} | ||
[refFragment, schemaId, refPointer] = getJSONRef(sourceSchemaId, schema.$ref) | ||
refFragment.__pointer = refPointer | ||
schema = { ...rawSchema, ...refFragment } | ||
delete schema.$ref | ||
} | ||
schema = partialResolveRefs(schema, schemaId, getJSONRef) | ||
const { type, nullable } = knownType ? { type: knownType, nullable: false } : getSchemaFragmentType(schema) | ||
const resolvedSchema = partialResolveRefs(schema, schemaId, getJSONRef) | ||
const { type, nullable } = knownType ? { type: knownType, nullable: false } : getSchemaFragmentType(resolvedSchema) | ||
@@ -64,3 +66,3 @@ // improve on ajv error messages based on ajv-errors (https://ajv.js.org/packages/ajv-errors.html) | ||
const normalizationResult = normalizeLayoutFragment( | ||
/** @type {import('@json-layout/vocabulary').SchemaFragment} */(schema), | ||
/** @type {import('@json-layout/vocabulary').SchemaFragment} */(resolvedSchema), | ||
pointer, | ||
@@ -141,3 +143,3 @@ options.components, | ||
pointer, | ||
parentPointer, | ||
refPointer, | ||
pure, | ||
@@ -163,25 +165,63 @@ propertyKeys: [], | ||
const dependent = schema.dependentRequired && Object.values(schema.dependentRequired).some(dependentProperties => dependentProperties.includes(propertyKey)) | ||
node.children.push(makeSkeletonNode( | ||
schema.properties[propertyKey], | ||
schemaId, | ||
options, | ||
getJSONRef, | ||
skeletonTrees, | ||
validates, | ||
validationErrors, | ||
normalizedLayouts, | ||
expressions, | ||
propertyKey, | ||
`${pointer}/properties/${propertyKey}`, | ||
pointer, | ||
schema.required?.includes(propertyKey), | ||
undefined, | ||
dependent | ||
)) | ||
const childPointer = `${refPointer}/properties/${propertyKey}` | ||
if (!skeletonNodes[childPointer]) { | ||
// @ts-ignore | ||
skeletonNodes[childPointer] = 'recursing' | ||
skeletonNodes[childPointer] = makeSkeletonNode( | ||
schema.properties[propertyKey], | ||
schemaId, | ||
options, | ||
getJSONRef, | ||
skeletonTrees, | ||
skeletonNodes, | ||
validates, | ||
validationErrors, | ||
normalizedLayouts, | ||
expressions, | ||
propertyKey, | ||
childPointer, | ||
schema.required?.includes(propertyKey), | ||
undefined, | ||
dependent | ||
) | ||
} | ||
node.children.push(childPointer) | ||
if (schema.dependentSchemas?.[propertyKey] || (schema.dependencies?.[propertyKey] && !Array.isArray(schema.dependencies[propertyKey]))) { | ||
const dependentSchema = schema.dependentSchemas?.[propertyKey] ?? schema.dependencies[propertyKey] | ||
const dependentPointer = schema.dependentSchemas?.[propertyKey] ? `${pointer}/dependentSchemas/${propertyKey}` : `${pointer}/dependencies/${propertyKey}` | ||
node.children.push(makeSkeletonNode( | ||
dependentSchema, | ||
const dependentPointer = schema.dependentSchemas?.[propertyKey] ? `${refPointer}/dependentSchemas/${propertyKey}` : `${refPointer}/dependencies/${propertyKey}` | ||
if (!skeletonNodes[dependentPointer]) { | ||
// @ts-ignore | ||
skeletonNodes[dependentPointer] = 'recursing' | ||
skeletonNodes[dependentPointer] = makeSkeletonNode( | ||
dependentSchema, | ||
schemaId, | ||
options, | ||
getJSONRef, | ||
skeletonTrees, | ||
skeletonNodes, | ||
validates, | ||
validationErrors, | ||
normalizedLayouts, | ||
expressions, | ||
`$deps-${propertyKey}`, | ||
dependentPointer, | ||
false, | ||
`data["${propertyKey}"] !== undefined`, | ||
undefined, | ||
'object' | ||
) | ||
} | ||
node.children.push(dependentPointer) | ||
} | ||
} | ||
} | ||
if (schema.allOf) { | ||
for (let i = 0; i < schema.allOf.length; i++) { | ||
const childPointer = `${refPointer}/allOf/${i}` | ||
if (!skeletonNodes[childPointer]) { | ||
// @ts-ignore | ||
skeletonNodes[childPointer] = 'recursing' | ||
skeletonNodes[childPointer] = makeSkeletonNode( | ||
schema.allOf[i], | ||
schemaId, | ||
@@ -191,2 +231,3 @@ options, | ||
skeletonTrees, | ||
skeletonNodes, | ||
validates, | ||
@@ -196,39 +237,16 @@ validationErrors, | ||
expressions, | ||
`$deps-${propertyKey}`, | ||
dependentPointer, | ||
pointer, | ||
`$allOf-${i}`, | ||
childPointer, | ||
false, | ||
`data["${propertyKey}"] !== undefined`, | ||
undefined, | ||
undefined, | ||
'object' | ||
)) | ||
) | ||
} | ||
node.propertyKeys = node.propertyKeys.concat(skeletonNodes[childPointer].propertyKeys) | ||
node.roPropertyKeys = node.roPropertyKeys.concat(skeletonNodes[childPointer].roPropertyKeys) | ||
node.children = node.children ?? [] | ||
node.children.push(childPointer) | ||
} | ||
} | ||
if (schema.allOf) { | ||
node.children = node.children ?? [] | ||
for (let i = 0; i < schema.allOf.length; i++) { | ||
const allOfNode = makeSkeletonNode( | ||
schema.allOf[i], | ||
schemaId, | ||
options, | ||
getJSONRef, | ||
skeletonTrees, | ||
validates, | ||
validationErrors, | ||
normalizedLayouts, | ||
expressions, | ||
`$allOf-${i}`, | ||
`${pointer}/allOf/${i}`, | ||
pointer, | ||
false, | ||
undefined, | ||
undefined, | ||
'object' | ||
) | ||
node.propertyKeys = node.propertyKeys.concat(allOfNode.propertyKeys) | ||
node.roPropertyKeys = node.roPropertyKeys.concat(allOfNode.roPropertyKeys) | ||
node.children.push(allOfNode) | ||
} | ||
} | ||
if (schema.oneOf) { | ||
@@ -269,2 +287,3 @@ const oneOfPointer = `${pointer}/oneOf` | ||
skeletonTrees, | ||
skeletonNodes, | ||
validates, | ||
@@ -280,14 +299,17 @@ validationErrors, | ||
} | ||
if (!skeletonNodes[oneOfPointer]) { | ||
skeletonNodes[oneOfPointer] = { | ||
key: '$oneOf', | ||
pointer: oneOfPointer, | ||
refPointer: oneOfPointer, | ||
childrenTrees, | ||
pure: skeletonNodes[skeletonTrees[childrenTrees[0]]?.root].pure, | ||
propertyKeys: [], | ||
roPropertyKeys: [] | ||
} | ||
} | ||
node.children = node.children ?? [] | ||
node.children.push({ | ||
key: '$oneOf', | ||
pointer: `${pointer}/oneOf`, | ||
parentPointer: pointer, | ||
childrenTrees, | ||
pure: skeletonTrees[childrenTrees[0]]?.root.pure, | ||
propertyKeys: [], | ||
roPropertyKeys: [] | ||
}) | ||
node.children.push(oneOfPointer) | ||
schema.errorMessage.oneOf = options.messages.errorOneOf | ||
rawSchema.errorMessage.oneOf = options.messages.errorOneOf | ||
} | ||
@@ -297,42 +319,54 @@ if (schema.if) { | ||
if (schema.then) { | ||
const childPointer = `${refPointer}/then` | ||
if (!skeletonNodes[childPointer]) { | ||
// @ts-ignore | ||
skeletonNodes[childPointer] = 'recursing' | ||
skeletonNodes[childPointer] = makeSkeletonNode( | ||
schema.then, | ||
schemaId, | ||
options, | ||
getJSONRef, | ||
skeletonTrees, | ||
skeletonNodes, | ||
validates, | ||
validationErrors, | ||
normalizedLayouts, | ||
expressions, | ||
'$then', | ||
childPointer, | ||
false, | ||
`validates["${pointer}/if"](data)`, | ||
undefined, | ||
'object' | ||
) | ||
} | ||
node.children = node.children ?? [] | ||
node.children.push(makeSkeletonNode( | ||
schema.then, | ||
schemaId, | ||
options, | ||
getJSONRef, | ||
skeletonTrees, | ||
validates, | ||
validationErrors, | ||
normalizedLayouts, | ||
expressions, | ||
'$then', | ||
`${pointer}/then`, | ||
pointer, | ||
false, | ||
`validates["${pointer}/if"](data)`, | ||
undefined, | ||
'object' | ||
)) | ||
node.children.push(childPointer) | ||
} | ||
if (schema.else) { | ||
const childPointer = `${refPointer}/else` | ||
if (!skeletonNodes[childPointer]) { | ||
// @ts-ignore | ||
skeletonNodes[childPointer] = 'recursing' | ||
skeletonNodes[childPointer] = makeSkeletonNode( | ||
schema.else, | ||
schemaId, | ||
options, | ||
getJSONRef, | ||
skeletonTrees, | ||
skeletonNodes, | ||
validates, | ||
validationErrors, | ||
normalizedLayouts, | ||
expressions, | ||
'$else', | ||
childPointer, | ||
false, | ||
`!validates["${pointer}/if"](data)`, | ||
undefined, | ||
'object' | ||
) | ||
} | ||
node.children = node.children ?? [] | ||
node.children.push(makeSkeletonNode( | ||
schema.else, | ||
schemaId, | ||
options, | ||
getJSONRef, | ||
skeletonTrees, | ||
validates, | ||
validationErrors, | ||
normalizedLayouts, | ||
expressions, | ||
'$else', | ||
`${pointer}/else`, | ||
pointer, | ||
false, | ||
`!validates["${pointer}/if"](data)`, | ||
undefined, | ||
'object' | ||
)) | ||
node.children.push(childPointer) | ||
} | ||
@@ -343,7 +377,7 @@ } | ||
if (schema?.required?.includes(propertyKey)) { | ||
schema.errorMessage.required = schema.errorMessage.required ?? {} | ||
schema.errorMessage.required[propertyKey] = options.messages.errorRequired | ||
rawSchema.errorMessage.required = rawSchema.errorMessage.required ?? {} | ||
rawSchema.errorMessage.required[propertyKey] = options.messages.errorRequired | ||
} | ||
if (schema.dependentRequired && Object.keys(schema.dependentRequired).includes(propertyKey)) { | ||
schema.errorMessage.dependentRequired = options.messages.errorRequired | ||
rawSchema.errorMessage.dependentRequired = options.messages.errorRequired | ||
} | ||
@@ -355,19 +389,28 @@ } | ||
if (Array.isArray(schema.items)) { | ||
node.children = schema.items.map((/** @type {any} */ itemSchema, /** @type {number} */ i) => { | ||
return makeSkeletonNode( | ||
itemSchema, | ||
schemaId, | ||
options, | ||
getJSONRef, | ||
skeletonTrees, | ||
validates, | ||
validationErrors, | ||
normalizedLayouts, | ||
expressions, | ||
i, | ||
`${pointer}/items/${i}`, | ||
pointer, | ||
true | ||
) | ||
}) | ||
node.children = node.children ?? [] | ||
for (let i = 0; i < schema.items.length; i++) { | ||
/** @type {any} */ | ||
const itemSchema = schema.items[i] | ||
const childPointer = `${refPointer}/items/${i}` | ||
if (!skeletonNodes[childPointer]) { | ||
// @ts-ignore | ||
skeletonNodes[childPointer] = 'recursing' | ||
skeletonNodes[childPointer] = makeSkeletonNode( | ||
itemSchema, | ||
schemaId, | ||
options, | ||
getJSONRef, | ||
skeletonTrees, | ||
skeletonNodes, | ||
validates, | ||
validationErrors, | ||
normalizedLayouts, | ||
expressions, | ||
i, | ||
childPointer, | ||
true | ||
) | ||
} | ||
node.children.push(childPointer) | ||
} | ||
} else { | ||
@@ -384,2 +427,3 @@ const childTreePointer = `${pointer}/items` | ||
skeletonTrees, | ||
skeletonNodes, | ||
validates, | ||
@@ -397,7 +441,8 @@ validationErrors, | ||
for (const child of node.children || []) { | ||
for (const childPointer of node.children || []) { | ||
const child = skeletonNodes[childPointer] | ||
if (!child.pure) node.pure = false | ||
} | ||
for (const childTree of node.childrenTrees || []) { | ||
if (!skeletonTrees[childTree]?.root?.pure) node.pure = false | ||
if (!skeletonNodes[skeletonTrees[childTree]?.root]?.pure) node.pure = false | ||
} | ||
@@ -404,0 +449,0 @@ |
@@ -12,2 +12,3 @@ // import Debug from 'debug' | ||
* @param {Record<string, import('./types.js').SkeletonTree>} skeletonTrees | ||
* @param {Record<string, import('./types.js').SkeletonNode>} skeletonNodes | ||
* @param {string[]} validates | ||
@@ -27,2 +28,3 @@ * @param {Record<string, string[]>} validationErrors | ||
skeletonTrees, | ||
skeletonNodes, | ||
validates, | ||
@@ -35,19 +37,23 @@ validationErrors, | ||
) { | ||
const root = makeSkeletonNode( | ||
schema, | ||
schemaId, | ||
options, | ||
getJSONRef, | ||
skeletonTrees, | ||
validates, | ||
validationErrors, | ||
normalizedLayouts, | ||
expressions, | ||
'', | ||
pointer, | ||
null, | ||
true | ||
) | ||
validates.push(root.pointer) | ||
return { title, root } | ||
if (!skeletonNodes[pointer]) { | ||
// @ts-ignore | ||
skeletonNodes[pointer] = 'recursing' | ||
skeletonNodes[pointer] = makeSkeletonNode( | ||
schema, | ||
schemaId, | ||
options, | ||
getJSONRef, | ||
skeletonTrees, | ||
skeletonNodes, | ||
validates, | ||
validationErrors, | ||
normalizedLayouts, | ||
expressions, | ||
'', | ||
pointer, | ||
true | ||
) | ||
validates.push(pointer) | ||
} | ||
return { title, root: pointer } | ||
} |
@@ -44,4 +44,5 @@ import type ajvModule from 'ajv/dist/2019.js' | ||
schema?: SchemaObject | ||
mainTree: string, | ||
mainTree: string | ||
skeletonTrees: Record<string, SkeletonTree> | ||
skeletonNodes: Record<string, SkeletonNode> | ||
validates: Record<string, ValidateFunction> | ||
@@ -61,3 +62,3 @@ validationErrors: Record<string, string[]> | ||
title: string | ||
root: SkeletonNode | ||
root: string | ||
} | ||
@@ -70,3 +71,3 @@ | ||
pointer: string | ||
parentPointer: string | null | ||
refPointer: string | ||
pure: boolean | ||
@@ -76,3 +77,3 @@ propertyKeys: string[] | ||
condition?: Expression | ||
children?: SkeletonNode[] // optional children in the case of arrays and object nodes | ||
children?: string[] // optional children in the case of arrays and object nodes | ||
childrenTrees?: string[] // other trees that can be instantiated with separate validation (for example in the case of new array items of oneOfs, etc) | ||
@@ -79,0 +80,0 @@ required?: boolean |
@@ -141,2 +141,3 @@ import { isSwitchStruct, childIsCompObject, isCompositeLayout, isFocusableLayout, isItemsLayout, isGetItemsExpression, isGetItemsFetch } from '@json-layout/vocabulary' | ||
/** | ||
* should match if an error belongs to this exact node | ||
* @param {import('ajv').ErrorObject} error | ||
@@ -151,3 +152,3 @@ * @param {import('../index.js').SkeletonNode} skeleton | ||
if (parentDataPath === originalError.instancePath && originalError.params?.missingProperty === skeleton.key) return true | ||
if (originalError.instancePath === dataPath && originalError.schemaPath === skeleton.pointer) return true | ||
if (originalError.instancePath === dataPath && (originalError.schemaPath === skeleton.pointer || originalError.schemaPath === skeleton.refPointer)) return true | ||
return false | ||
@@ -157,2 +158,3 @@ } | ||
/** | ||
* should match if an error belongs to a child of the current node but the child was not displayed | ||
* @param {import('ajv').ErrorObject} error | ||
@@ -165,7 +167,11 @@ * @param {import('../index.js').SkeletonNode} skeleton | ||
const matchChildError = (error, skeleton, dataPath, parentDataPath) => { | ||
const originalError = error.params?.errors?.[0] ?? error | ||
if (!( | ||
error.schemaPath === skeleton.pointer || | ||
error.schemaPath.startsWith(skeleton.pointer + '/') | ||
originalError.schemaPath === skeleton.pointer || | ||
originalError.schemaPath.startsWith(skeleton.pointer + '/') | ||
) && !( | ||
originalError.schemaPath === skeleton.refPointer || | ||
originalError.schemaPath.startsWith(skeleton.refPointer + '/') | ||
)) return false | ||
if (error.instancePath.startsWith(dataPath)) return true | ||
if (originalError.instancePath.startsWith(dataPath)) return true | ||
return false | ||
@@ -310,3 +316,5 @@ } | ||
) continue | ||
const childSkeleton = skeleton.children?.find(c => c.key === childLayout.key) ?? skeleton | ||
let childSkeleton = skeleton | ||
const childSkeletonKey = skeleton.children?.find(c => compiledLayout.skeletonNodes[c].key === childLayout.key) | ||
if (childSkeletonKey !== undefined) childSkeleton = compiledLayout.skeletonNodes[childSkeletonKey] | ||
if (childSkeleton.condition) { | ||
@@ -345,12 +353,15 @@ if (!evalExpression(compiledLayout.expressions, childSkeleton.condition, objectData, parentOptions, display, layout, compiledLayout.validates, context.rootData, parentContext)) { | ||
/** @type {number} */ | ||
const activeChildTreeIndex = fullKey in context.activatedItems ? context.activatedItems[fullKey] : skeleton.childrenTrees?.findIndex((childTree) => compiledLayout.validates[compiledLayout.skeletonTrees[childTree].root.pointer](data)) | ||
const activeChildTreeIndex = fullKey in context.activatedItems ? context.activatedItems[fullKey] : skeleton.childrenTrees?.findIndex((childTree) => compiledLayout.validates[compiledLayout.skeletonTrees[childTree].root](data)) | ||
if (activeChildTreeIndex !== -1) { | ||
context.errors = context.errors?.filter(error => { | ||
const originalError = error.params?.errors?.[0] ?? error | ||
// console.log(originalError.schemaPath, skeleton.pointer, skeleton.refPointer) | ||
// if an item was selected, remove the oneOf error | ||
if (originalError.schemaPath === skeleton.pointer && originalError.keyword === 'oneOf') return false | ||
if ((originalError.schemaPath === skeleton.pointer || originalError.schemaPath === skeleton.refPointer) && originalError.keyword === 'oneOf') return false | ||
// also remove the errors from other children of the oneOf | ||
if (originalError.schemaPath.startsWith(skeleton.pointer) && !originalError.schemaPath.startsWith(skeleton.pointer + '/' + activeChildTreeIndex)) return false | ||
if (originalError.schemaPath.startsWith(skeleton.refPointer) && !originalError.schemaPath.startsWith(skeleton.refPointer + '/' + activeChildTreeIndex)) return false | ||
return true | ||
}) | ||
// console.log(context.errors?.map(error => error.params?.errors?.[0] ?? error)) | ||
const activeChildKey = `${fullKey}/${activeChildTreeIndex}` | ||
@@ -369,3 +380,3 @@ if (context.autofocusTarget === fullKey) context.autofocusTarget = activeChildKey | ||
dataPath, | ||
activeChildTree.root, | ||
compiledLayout.skeletonNodes[activeChildTree.root], | ||
null, | ||
@@ -384,3 +395,3 @@ display, | ||
const arrayData = /** @type {unknown[]} */(data ?? []) | ||
const childSkeleton = /** @type {import('../index.js').SkeletonNode} */(skeleton?.childrenTrees?.[0] && compiledLayout.skeletonTrees[skeleton?.childrenTrees?.[0]]?.root) | ||
const childSkeleton = /** @type {import('../index.js').SkeletonNode} */(skeleton?.childrenTrees?.[0] && compiledLayout.skeletonNodes[compiledLayout.skeletonTrees[skeleton?.childrenTrees?.[0]]?.root]) | ||
const listItemOptions = layout.listEditMode === 'inline' ? options : produceReadonlyArrayItemOptions(options) | ||
@@ -387,0 +398,0 @@ children = [] |
@@ -48,3 +48,3 @@ import { produce } from 'immer' | ||
) { | ||
const validate = compiledLayout.validates[skeleton.root.pointer] | ||
const validate = compiledLayout.validates[skeleton.root] | ||
const valid = validate(data) | ||
@@ -56,2 +56,12 @@ if (validate.errors) { | ||
context.errors = validate.errors | ||
if (context.errors.length) { | ||
for (const error of context.errors) { | ||
const originalError = error.params?.errors?.[0] ?? error | ||
// work around this issue https://github.com/ajv-validator/ajv/issues/512 | ||
if (originalError?.parentSchema.__pointer) { | ||
originalError.schemaPath = originalError?.parentSchema.__pointer | ||
if (originalError.keyword === 'oneOf') originalError.schemaPath += '/oneOf' | ||
} | ||
} | ||
} | ||
if ([true, 'error'].includes(options.removeAdditional)) { | ||
@@ -70,3 +80,3 @@ context.additionalPropertiesErrors = validate.errors.filter(error => error.keyword === 'additionalProperties' || error.keyword === 'unevaluatedProperties') | ||
null, | ||
skeleton.root, | ||
compiledLayout.skeletonNodes[skeleton.root], | ||
null, | ||
@@ -73,0 +83,0 @@ display, |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
107593
22
2753