Socket
Socket
Sign inDemoInstall

@json-layout/core

Package Overview
Dependencies
Maintainers
1
Versions
50
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@json-layout/core - npm Package Compare versions

Comparing version 0.1.0 to 0.2.0

7

package.json
{
"name": "@json-layout/core",
"version": "0.1.0",
"version": "0.2.0",
"description": "Compilation and state management utilities for JSON Layout.",

@@ -22,3 +22,4 @@ "type": "module",

"src",
"types"
"types",
"LICENSE"
],

@@ -50,3 +51,3 @@ "scripts": {

"dependencies": {
"@json-layout/vocabulary": "^0.1.0",
"@json-layout/vocabulary": "^0.2.0",
"@types/markdown-it": "^13.0.1",

@@ -53,0 +54,0 @@ "ajv": "^8.12.0",

@@ -30,3 +30,3 @@ // compileStatic is meant to produce a serializable result

const expressionsParams = ['data', 'options', 'display']
const expressionsParams = ['data', 'options', 'context', 'display']

@@ -91,4 +91,15 @@ const clone = rfdc()

const expressionsDefinitions = []
/** @type {Record<string, string[]>} */
const validationErrors = {}
const skeletonTree = makeSkeletonTree(schema, options, validatePointers, normalizedLayouts, expressionsDefinitions, `${schema.$id}#`, 'main')
const skeletonTree = makeSkeletonTree(
schema,
options,
validatePointers,
validationErrors,
normalizedLayouts,
expressionsDefinitions,
`${schema.$id}#`,
'main'
)

@@ -131,2 +142,3 @@ options.ajv.addSchema(schema)

validates,
validationErrors,
normalizedLayouts,

@@ -133,0 +145,0 @@ expressions,

@@ -29,3 +29,3 @@ // import Debug from 'debug'

// some internal imports to ajv are not translated to asm, we do it here
// some internal imports to ajv are not translated to esm, we do it here
// cf https://github.com/ajv-validator/ajv-formats/pull/73

@@ -41,3 +41,3 @@ if (code.includes('require("ajv-formats/dist/formats")')) {

// importe only the current locale from ajv-i18n
// import only the current locale from ajv-i18n
code = `import localizeErrors from "ajv-i18n/localize/${compiledLayout.locale}/index.js";

@@ -60,2 +60,3 @@ export const exportLocalizeErrors = localizeErrors;\n` + code

validates: {},
validationErrors: compiledLayout.validationErrors,
expressions: expressionsNodes,

@@ -62,0 +63,0 @@ locale: compiledLayout.locale,

// import Debug from 'debug'
import { normalizeLayoutFragment, isSwitchStruct, isGetItemsExpression, isSelectLayout, isGetItemsFetch } from '@json-layout/vocabulary'
import { normalizeLayoutFragment, isSwitchStruct, isGetItemsExpression, isGetItemsFetch, isItemsLayout } from '@json-layout/vocabulary'
import { makeSkeletonTree } from './skeleton-tree.js'

@@ -23,2 +23,3 @@

* @param {string[]} validates
* @param {Record<string, string[]>} validationErrors
* @param {Record<string, import('@json-layout/vocabulary').NormalizedLayout>} normalizedLayouts

@@ -36,2 +37,3 @@ * @param {import('@json-layout/vocabulary').Expression[]} expressions

validates,
validationErrors,
normalizedLayouts,

@@ -49,5 +51,10 @@ expressions,

schema.errorMessage = schema.errorMessage ?? {}
/** @type {import('@json-layout/vocabulary').NormalizedLayout} */
const normalizedLayout = normalizedLayouts[pointer] ?? normalizeLayoutFragment(/** @type {import('@json-layout/vocabulary').SchemaFragment} */(schema), pointer, options.markdown)
normalizedLayouts[pointer] = normalizedLayout
if (!normalizedLayouts[pointer]) {
const normalizationResult = normalizeLayoutFragment(/** @type {import('@json-layout/vocabulary').SchemaFragment} */(schema), pointer, options.markdown)
normalizedLayouts[pointer] = normalizationResult.layout
if (normalizationResult.errors.length) {
validationErrors[pointer.replace('_jl#', '/')] = normalizationResult.errors
}
}
const normalizedLayout = normalizedLayouts[pointer]

@@ -58,3 +65,3 @@ const compObjects = isSwitchStruct(normalizedLayout) ? normalizedLayout.switch : [normalizedLayout]

if (compObject.if) pushExpression(expressions, compObject.if)
if (isSelectLayout(compObject) && compObject.getItems) {
if (isItemsLayout(compObject) && compObject.getItems) {
if (isGetItemsExpression(compObject.getItems)) pushExpression(expressions, compObject.getItems)

@@ -65,2 +72,3 @@ if (isGetItemsFetch(compObject.getItems)) pushExpression(expressions, compObject.getItems.url)

if (compObject.getItems.itemValue) pushExpression(expressions, compObject.getItems.itemValue)
if (compObject.getItems.itemIcon) pushExpression(expressions, compObject.getItems.itemIcon)
if (compObject.getItems.itemsResults) pushExpression(expressions, compObject.getItems.itemsResults)

@@ -90,2 +98,3 @@ }

validates,
validationErrors,
normalizedLayouts,

@@ -111,2 +120,3 @@ expressions,

validates,
validationErrors,
normalizedLayouts,

@@ -123,3 +133,9 @@ expressions,

const oneOfPointer = `${pointer}/oneOf`
normalizedLayouts[oneOfPointer] = normalizedLayouts[oneOfPointer] ?? normalizeLayoutFragment(schema, oneOfPointer, options.markdown, 'oneOf')
if (!normalizedLayouts[oneOfPointer]) {
const normalizationResult = normalizeLayoutFragment(schema, oneOfPointer, options.markdown, 'oneOf')
normalizedLayouts[oneOfPointer] = normalizationResult.layout
if (normalizationResult.errors.length) {
validationErrors[oneOfPointer.replace('_jl#', '/')] = normalizationResult.errors
}
}
/** @type {import('./types.js').SkeletonTree[]} */

@@ -131,3 +147,12 @@ const childrenTrees = []

delete schema.oneOf[i].title
childrenTrees.push(makeSkeletonTree(schema.oneOf[i], options, validates, normalizedLayouts, expressions, `${oneOfPointer}/${i}`, title))
childrenTrees.push(makeSkeletonTree(
schema.oneOf[i],
options,
validates,
validationErrors,
normalizedLayouts,
expressions,
`${oneOfPointer}/${i}`,
title
))
}

@@ -148,2 +173,3 @@ node.children = node.children ?? []

validates,
validationErrors,
normalizedLayouts,

@@ -163,2 +189,3 @@ expressions,

validates,
validationErrors,
normalizedLayouts,

@@ -165,0 +192,0 @@ expressions,

@@ -10,2 +10,3 @@ // import Debug from 'debug'

* @param {string[]} validates
* @param {Record<string, string[]>} validationErrors
* @param {Record<string, import('@json-layout/vocabulary').NormalizedLayout>} normalizedLayouts

@@ -21,2 +22,3 @@ * @param {import('@json-layout/vocabulary').Expression[]} expressions

validates,
validationErrors,
normalizedLayouts,

@@ -27,5 +29,5 @@ expressions,

) {
const root = makeSkeletonNode(schema, options, validates, normalizedLayouts, expressions, '', pointer, null, true)
const root = makeSkeletonNode(schema, options, validates, validationErrors, normalizedLayouts, expressions, '', pointer, null, true)
validates.push(pointer)
return { title, root }
}
import type ajvModule from 'ajv'
import type MarkdownIt from 'markdown-it'
import { type NormalizedLayout, type StateNodeOptions } from '@json-layout/vocabulary'
import { type ValidateFunction, type SchemaObject } from 'ajv'
import { type ValidateFunction, type SchemaObject, type ErrorObject } from 'ajv'
import { type Display } from '../state/utils/display.js'
import { type LocaleMessages } from '../i18n/types.js'
export type CompiledExpression = (data: any, options: StateNodeOptions, display: Display) => any
export type CompiledExpression = (data: any, options: StateNodeOptions, context: object, display: Display) => any

@@ -26,2 +26,3 @@ export interface CompileOptions {

validates: Record<string, ValidateFunction>
validationErrors: Record<string, string[]>
normalizedLayouts: Record<string, NormalizedLayout>

@@ -28,0 +29,0 @@ expressions: CompiledExpression[]

@@ -9,3 +9,4 @@ /** @type {import('./types.js').LocaleMessages} */

duplicate: 'Duplicate',
sort: 'Sort'
sort: 'Sort',
showHelp: 'Show a help message'
}

@@ -9,3 +9,4 @@ /** @type {import('./types.js').LocaleMessages} */

duplicate: 'Dupliquer',
sort: 'Trier'
sort: 'Trier',
showHelp: 'Afficher un message d\'aide'
}

@@ -12,4 +12,5 @@ export interface CompileOptionsMessages {

sort: string
showHelp: string
}
export type LocaleMessages = CompileOptionsMessages & StateOptionsMessages

@@ -7,3 +7,3 @@ // eslint-disable-next-line import/no-named-default

import { Display } from './utils/display.js'
import { isGetItemsExpression, isGetItemsFetch } from '@json-layout/vocabulary'
import { isGetItemsExpression, isGetItemsFetch, isItemsLayout } from '@json-layout/vocabulary'

@@ -24,2 +24,4 @@ export { Display } from './utils/display.js'

* @typedef {import('./types.js').SelectNode} SelectNode
* @typedef {import('./types.js').AutocompleteNode} AutocompleteNode
* @typedef {import('./types.js').ComboboxNode} ComboboxNode
* @typedef {import('./types.js').CheckboxNode} CheckboxNode

@@ -41,4 +43,4 @@ * @typedef {import('./types.js').SwitchNode} SwitchNode

/** @type {(node: StateNode | undefined) => node is SelectNode} */
export const isSelect = (node) => !!node && node.layout.comp === 'select'
/** @type {(node: StateNode | undefined) => node is SelectNode | ComboboxNode | AutocompleteNode} */
export const isItemsNode = (node) => !!node && isItemsLayout(node.layout)

@@ -309,9 +311,12 @@ const logDataBinding = debug('jl:data-binding')

/**
* @private
* @param {StateNode} node
* @returns {Promise<import('@json-layout/vocabulary').SelectItems>}
* @param {string} q
* @returns {Promise<[import('@json-layout/vocabulary').SelectItems, boolean]>}
*/
async getSelectItems (node) {
if (!isSelect(node)) throw new Error('node is not a select component')
if (node.layout.items) return node.layout.items
async getSourceItems (node, q = '') {
if (!isItemsNode(node)) throw new Error('node is not a component with an items list')
if (node.layout.items) return [node.layout.items, false]
/** @type {(expression: import('@json-layout/vocabulary').Expression, data: any) => any} */

@@ -323,2 +328,3 @@ const evalSelectExpression = (expression, data) => {

let rawItems
let appliedQ = false
if (node.layout.getItems && isGetItemsExpression(node.layout.getItems)) {

@@ -329,3 +335,14 @@ rawItems = evalSelectExpression(node.layout.getItems, null)

if (node.layout.getItems && isGetItemsFetch(node.layout.getItems)) {
const url = evalSelectExpression(node.layout.getItems.url, null)
const url = new URL(evalSelectExpression(node.layout.getItems.url, null))
let qSearchParam = node.layout.getItems.qSearchParam
if (!qSearchParam) {
for (const searchParam of url.searchParams.entries()) {
if (searchParam[1] === '{q}') qSearchParam = searchParam[0]
}
}
if (qSearchParam) {
appliedQ = true
if (q) url.searchParams.set(qSearchParam, q)
else url.searchParams.delete(qSearchParam)
}
rawItems = await (await fetch(url)).json()

@@ -338,6 +355,7 @@ }

}
return rawItems.map((/** @type {any} */ rawItem) => {
/** @type {import('@json-layout/vocabulary').SelectItems} */
const items = rawItems.map((/** @type {any} */ rawItem) => {
/** @type {Partial<import('@json-layout/vocabulary').SelectItem>} */
const item = {}
if (typeof rawItem === 'object') {
/** @type {Partial<import('@json-layout/vocabulary').SelectItem>} */
const item = {}
item.value = node.layout.getItems?.itemValue ? evalSelectExpression(node.layout.getItems.itemValue, rawItem) : (node.layout.getItems?.returnObjects ? rawItem : rawItem.value)

@@ -349,17 +367,28 @@ item.key = node.layout.getItems?.itemKey ? evalSelectExpression(node.layout.getItems.itemKey, rawItem) : rawItem.key

item.title = item.title ?? item.key
return item
if (!item.icon && rawItem.icon) item.icon = rawItem.icon
} else {
/** @type {Partial<import('@json-layout/vocabulary').SelectItem>} */
const item = {}
item.value = node.layout.getItems?.itemValue ? evalSelectExpression(node.layout.getItems.itemValue, rawItem) : rawItem
item.key = node.layout.getItems?.itemKey ? evalSelectExpression(node.layout.getItems.itemKey, rawItem) : item.value
item.title = node.layout.getItems?.itemTitle ? evalSelectExpression(node.layout.getItems.itemTitle, rawItem) : item.value
return item
}
if (node.layout.getItems?.itemIcon) item.icon = evalSelectExpression(node.layout.getItems?.itemIcon, rawItem)
return item
})
return [items, appliedQ]
}
throw new Error('node is missing items or getItems parameters')
throw new Error(`node ${node.fullKey} is missing items or getItems parameters`)
}
/**
* @param {StateNode} node
* @param {string} q
* @returns {Promise<import('@json-layout/vocabulary').SelectItems>}
*/
async getItems (node, q = '') {
const [sourceItems, appliedQ] = await this.getSourceItems(node, q)
if (q && !appliedQ) return sourceItems.filter(item => item.title.toLowerCase().includes(q.toLowerCase()))
return sourceItems
}
/**
* @type {Record<string, number>}

@@ -366,0 +395,0 @@ */

@@ -128,3 +128,3 @@ import { isSwitchStruct, childIsCompObject, isCompositeLayout } from '@json-layout/vocabulary'

// console.log(expression.expr, context, mode, display)
return compiledExpression(data, options, display)
return compiledExpression(data, options, options.context, display)
}

@@ -196,3 +196,4 @@

parentOptions,
layout.options, display.width
layout.options,
display.width
)

@@ -199,0 +200,0 @@

import { type ErrorObject } from 'ajv'
import { type CompObject, type Cols, type StateNodeOptions, type TextField, type Textarea, type NumberField, type Slider, type Checkbox, type Switch, type DatePicker, type DateTimePicker, type TimePicker, type ColorPicker, type Section, type OneOfSelect, type Select, type Tabs, type VerticalTabs, type ExpansionPanels, type List } from '@json-layout/vocabulary'
import {
type CompObject,
type Cols,
type StateNodeOptions,
type TextField,
type Textarea,
type NumberField,
type Slider,
type Checkbox,
type Switch,
type DatePicker,
type DateTimePicker,
type TimePicker,
type ColorPicker,
type Section,
type OneOfSelect,
type Select,
type Autocomplete,
type Tabs,
type VerticalTabs,
type ExpansionPanels,
type List,
type Combobox
} from '@json-layout/vocabulary'
import { type SkeletonTree, type SkeletonNode, type StatefulLayout } from '../index.js'

@@ -83,2 +106,4 @@ import { type LocaleMessages } from '../i18n/types.js'

export type AutocompleteNode = Omit<StateNode, 'children'> & { layout: Autocomplete, data: any }
export type TabsNode = StateNode & { layout: Tabs, children: StateNode[] }

@@ -91,1 +116,3 @@

export type ListNode = StateNode & { layout: List, data: any[], children: StateNode[], childrenTrees: SkeletonTree[] }
export type ComboboxNode = Omit<StateNode, 'children'> & { layout: Combobox, data: any[] }

@@ -5,2 +5,3 @@ /**

* @param {string[]} validates
* @param {Record<string, string[]>} validationErrors
* @param {Record<string, import('@json-layout/vocabulary').NormalizedLayout>} normalizedLayouts

@@ -14,3 +15,3 @@ * @param {import('@json-layout/vocabulary').Expression[]} expressions

*/
export function makeSkeletonNode(schema: any, options: import('./index.js').CompileOptions, validates: string[], normalizedLayouts: Record<string, import('@json-layout/vocabulary').NormalizedLayout>, expressions: import('@json-layout/vocabulary').Expression[], key: string | number, pointer: string, parentPointer: string | null, required: boolean): import('./types.js').SkeletonNode;
export function makeSkeletonNode(schema: any, options: import('./index.js').CompileOptions, validates: string[], validationErrors: Record<string, string[]>, normalizedLayouts: Record<string, import('@json-layout/vocabulary').NormalizedLayout>, expressions: import('@json-layout/vocabulary').Expression[], key: string | number, pointer: string, parentPointer: string | null, required: boolean): import('./types.js').SkeletonNode;
//# sourceMappingURL=skeleton-node.d.ts.map

@@ -5,2 +5,3 @@ /**

* @param {string[]} validates
* @param {Record<string, string[]>} validationErrors
* @param {Record<string, import('@json-layout/vocabulary').NormalizedLayout>} normalizedLayouts

@@ -12,3 +13,3 @@ * @param {import('@json-layout/vocabulary').Expression[]} expressions

*/
export function makeSkeletonTree(schema: any, options: import('./index.js').CompileOptions, validates: string[], normalizedLayouts: Record<string, import('@json-layout/vocabulary').NormalizedLayout>, expressions: import('@json-layout/vocabulary').Expression[], pointer: string, title: string): import('./types.js').SkeletonTree;
export function makeSkeletonTree(schema: any, options: import('./index.js').CompileOptions, validates: string[], validationErrors: Record<string, string[]>, normalizedLayouts: Record<string, import('@json-layout/vocabulary').NormalizedLayout>, expressions: import('@json-layout/vocabulary').Expression[], pointer: string, title: string): import('./types.js').SkeletonTree;
//# sourceMappingURL=skeleton-tree.d.ts.map

@@ -7,3 +7,3 @@ import type ajvModule from 'ajv';

import { type LocaleMessages } from '../i18n/types.js';
export type CompiledExpression = (data: any, options: StateNodeOptions, display: Display) => any;
export type CompiledExpression = (data: any, options: StateNodeOptions, context: object, display: Display) => any;
export interface CompileOptions {

@@ -25,2 +25,3 @@ ajv: ajvModule.default;

validates: Record<string, ValidateFunction>;
validationErrors: Record<string, string[]>;
normalizedLayouts: Record<string, NormalizedLayout>;

@@ -27,0 +28,0 @@ expressions: CompiledExpression[];

@@ -11,4 +11,5 @@ export interface CompileOptionsMessages {

sort: string;
showHelp: string;
}
export type LocaleMessages = CompileOptionsMessages & StateOptionsMessages;
//# sourceMappingURL=types.d.ts.map

@@ -14,2 +14,4 @@ export { Display } from "./utils/display.js";

* @typedef {import('./types.js').SelectNode} SelectNode
* @typedef {import('./types.js').AutocompleteNode} AutocompleteNode
* @typedef {import('./types.js').ComboboxNode} ComboboxNode
* @typedef {import('./types.js').CheckboxNode} CheckboxNode

@@ -29,4 +31,4 @@ * @typedef {import('./types.js').SwitchNode} SwitchNode

export const isSection: (node: StateNode | undefined) => node is import("./types.js").SectionNode;
/** @type {(node: StateNode | undefined) => node is SelectNode} */
export const isSelect: (node: StateNode | undefined) => node is import("./types.js").SelectNode;
/** @type {(node: StateNode | undefined) => node is SelectNode | ComboboxNode | AutocompleteNode} */
export const isItemsNode: (node: StateNode | undefined) => node is import("./types.js").SelectNode | import("./types.js").AutocompleteNode | import("./types.js").ComboboxNode;
export class StatefulLayout {

@@ -150,6 +152,14 @@ /**

/**
* @private
* @param {StateNode} node
* @param {string} q
* @returns {Promise<[import('@json-layout/vocabulary').SelectItems, boolean]>}
*/
private getSourceItems;
/**
* @param {StateNode} node
* @param {string} q
* @returns {Promise<import('@json-layout/vocabulary').SelectItems>}
*/
getSelectItems(node: StateNode): Promise<import('@json-layout/vocabulary').SelectItems>;
getItems(node: StateNode, q?: string): Promise<import('@json-layout/vocabulary').SelectItems>;
/**

@@ -176,2 +186,4 @@ * @param {StateNode} node

export type SelectNode = import('./types.js').SelectNode;
export type AutocompleteNode = import('./types.js').AutocompleteNode;
export type ComboboxNode = import('./types.js').ComboboxNode;
export type CheckboxNode = import('./types.js').CheckboxNode;

@@ -178,0 +190,0 @@ export type SwitchNode = import('./types.js').SwitchNode;

import { type ErrorObject } from 'ajv';
import { type CompObject, type Cols, type StateNodeOptions, type TextField, type Textarea, type NumberField, type Slider, type Checkbox, type Switch, type DatePicker, type DateTimePicker, type TimePicker, type ColorPicker, type Section, type OneOfSelect, type Select, type Tabs, type VerticalTabs, type ExpansionPanels, type List } from '@json-layout/vocabulary';
import { type CompObject, type Cols, type StateNodeOptions, type TextField, type Textarea, type NumberField, type Slider, type Checkbox, type Switch, type DatePicker, type DateTimePicker, type TimePicker, type ColorPicker, type Section, type OneOfSelect, type Select, type Autocomplete, type Tabs, type VerticalTabs, type ExpansionPanels, type List, type Combobox } from '@json-layout/vocabulary';
import { type SkeletonTree, type SkeletonNode, type StatefulLayout } from '../index.js';

@@ -101,2 +101,6 @@ import { type LocaleMessages } from '../i18n/types.js';

};
export type AutocompleteNode = Omit<StateNode, 'children'> & {
layout: Autocomplete;
data: any;
};
export type TabsNode = StateNode & {

@@ -120,2 +124,6 @@ layout: Tabs;

};
export type ComboboxNode = Omit<StateNode, 'children'> & {
layout: Combobox;
data: any[];
};
//# sourceMappingURL=types.d.ts.map

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc