diff --git a/.gitignore b/.gitignore index ef23885..9746acc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ node_modules/ dist/ -tmp/ \ No newline at end of file +tmp/ +lib/**/*.d.ts \ No newline at end of file diff --git a/lib/base.js b/lib/base.js index ee6ad91..4e01c12 100644 --- a/lib/base.js +++ b/lib/base.js @@ -3,10 +3,20 @@ */ export default function Base() { } +/** + * Get property value + * @param {string} name + * @return {*} + */ Base.prototype.get = function(name) { return this.$model.properties.get(this, name); }; +/** + * Set property value + * @param {string} name + * @param {*} value + */ Base.prototype.set = function(name, value) { this.$model.properties.set(this, name, value); }; \ No newline at end of file diff --git a/lib/base.spec.ts b/lib/base.spec.ts new file mode 100644 index 0000000..adb5f74 --- /dev/null +++ b/lib/base.spec.ts @@ -0,0 +1,13 @@ +import Base from './base.js'; + +const baseElement = new Base(); + +baseElement.set('prop1', true); +baseElement.set('prop2', 123); +baseElement.set('prop3', 'string value'); +baseElement.set('prop4', null); +baseElement.set('prop5', undefined); +baseElement.set('prop6', { foo: null }); +baseElement.set('prop7', [ true, 123, null, undefined, 'string value', { foo: null } ]); + +baseElement.get('prop1'); diff --git a/lib/descriptor-builder.js b/lib/descriptor-builder.js index c76e2b0..f7ac47a 100644 --- a/lib/descriptor-builder.js +++ b/lib/descriptor-builder.js @@ -9,20 +9,98 @@ import { parseName as parseNameNs } from './ns.js'; +/** + * @typedef {import('./ns.js').Namespace} Namespace + * @typedef {import('./registry.js').RegisteredPackage} RegisteredPackage + * @typedef {import('./registry.js').RegisteredTypeDef} RegisteredTypeDef + * @typedef {import('./registry.js').RegisteredPropertyDef} RegisteredPropertyDef + */ + +/** + * Effective element descriptor + * aka element type descriptor + * aka element descriptor + * @typedef {{ + * readonly ns: Namespace; + * readonly name: Namespace['name']; + * readonly allTypes: Array; + * readonly allTypesByName: Record; + * readonly properties: Array; + * readonly propertiesByName: Record; + * readonly bodyProperty?: PropertyDescriptor; + * readonly idProperty?: PropertyDescriptor; + * readonly $pkg?: RegisteredPackage; + * }} EffectiveDescriptor + */ + +/** + * Property descriptor + * @typedef {RegisteredPropertyDef & { + * localName: Namespace['localName']; + * inherited?: boolean; + * definedBy?: RegisteredTypeDef; + * }} PropertyDescriptor + */ + +/** + * @typedef {{ + * name: string; + * isGeneric: true; + * ns: { + * prefix: string; + * localName: string; + * uri: string; + * }; + * }} AnyTypeDescriptor + */ /** * A utility to build element descriptors. + * @class DescriptorBuilder + * @param {Namespace} nameNs */ export default function DescriptorBuilder(nameNs) { + + /** + * @private + * @type {Namespace} + */ this.ns = nameNs; + + /** + * @private + * @type {Namespace['name']} + */ this.name = nameNs.name; + + /** + * @private + * @type {Array} + */ this.allTypes = []; + + /** + * @private + * @type {Record} + */ this.allTypesByName = {}; + + /** + * @private + * @type {Array} + */ this.properties = []; + + /** + * @private + * @type {Record} + */ this.propertiesByName = {}; } - +/** + * @return {EffectiveDescriptor} + */ DescriptorBuilder.prototype.build = function() { return pick(this, [ 'ns', @@ -38,8 +116,8 @@ DescriptorBuilder.prototype.build = function() { /** * Add property at given index. - * - * @param {Object} p + * @private + * @param {PropertyDescriptor} p * @param {Number} [idx] * @param {Boolean} [validate=true] */ @@ -61,7 +139,12 @@ DescriptorBuilder.prototype.addProperty = function(p, idx, validate) { } }; - +/** + * @private + * @param {PropertyDescriptor} oldProperty + * @param {PropertyDescriptor} newProperty + * @param {string} replace + */ DescriptorBuilder.prototype.replaceProperty = function(oldProperty, newProperty, replace) { var oldNameNs = oldProperty.ns; @@ -111,7 +194,12 @@ DescriptorBuilder.prototype.replaceProperty = function(oldProperty, newProperty, propertiesByName[oldNameNs.name] = propertiesByName[oldNameNs.localName] = newProperty; }; - +/** + * @private + * @param {PropertyDescriptor} p + * @param {string} targetPropertyName + * @param {string} replace + */ DescriptorBuilder.prototype.redefineProperty = function(p, targetPropertyName, replace) { var nsPrefix = p.ns.prefix; @@ -130,6 +218,11 @@ DescriptorBuilder.prototype.redefineProperty = function(p, targetPropertyName, r delete p.redefines; }; +/** + * @private + * @param {PropertyDescriptor} p + * @param {boolean} validate + */ DescriptorBuilder.prototype.addNamedProperty = function(p, validate) { var ns = p.ns, propsByName = this.propertiesByName; @@ -142,6 +235,10 @@ DescriptorBuilder.prototype.addNamedProperty = function(p, validate) { propsByName[ns.name] = propsByName[ns.localName] = p; }; +/** + * @private + * @param {RegisteredPropertyDef} p + */ DescriptorBuilder.prototype.removeNamedProperty = function(p) { var ns = p.ns, propsByName = this.propertiesByName; @@ -150,6 +247,11 @@ DescriptorBuilder.prototype.removeNamedProperty = function(p) { delete propsByName[ns.localName]; }; +/** + * @private + * @param {PropertyDescriptor} p + * @param {boolean} [validate] + */ DescriptorBuilder.prototype.setBodyProperty = function(p, validate) { if (validate && this.bodyProperty) { @@ -161,6 +263,11 @@ DescriptorBuilder.prototype.setBodyProperty = function(p, validate) { this.bodyProperty = p; }; +/** + * @private + * @param {PropertyDescriptor} p + * @param {boolean} [validate] + */ DescriptorBuilder.prototype.setIdProperty = function(p, validate) { if (validate && this.idProperty) { @@ -172,6 +279,10 @@ DescriptorBuilder.prototype.setIdProperty = function(p, validate) { this.idProperty = p; }; +/** + * @private + * @param {RegisteredTypeDef} typeDescriptor + */ DescriptorBuilder.prototype.assertNotTrait = function(typeDescriptor) { const _extends = typeDescriptor.extends || []; @@ -183,6 +294,10 @@ DescriptorBuilder.prototype.assertNotTrait = function(typeDescriptor) { } }; +/** + * @private + * @param {PropertyDescriptor} p + */ DescriptorBuilder.prototype.assertNotDefined = function(p, name) { var propertyName = p.name, definedProperty = this.propertiesByName[propertyName]; @@ -195,10 +310,19 @@ DescriptorBuilder.prototype.assertNotDefined = function(p, name) { } }; +/** + * @private + * @param {string} name + * @return {PropertyDescriptor} + */ DescriptorBuilder.prototype.hasProperty = function(name) { return this.propertiesByName[name]; }; +/** + * @param {RegisteredTypeDef} t + * @param {boolean} inherited + */ DescriptorBuilder.prototype.addTrait = function(t, inherited) { if (inherited) { diff --git a/lib/descriptor-builder.spec.ts b/lib/descriptor-builder.spec.ts new file mode 100644 index 0000000..cfc6e1f --- /dev/null +++ b/lib/descriptor-builder.spec.ts @@ -0,0 +1,63 @@ +import DescriptorBuilder, { PropertyDescriptor } from './descriptor-builder.js'; +import { Namespace } from './ns.js'; +import { RegisteredTypeDef } from './registry.js'; +import { expectType } from 'ts-expect'; + +const ns: Namespace = { name: 'foo:bar', localName: 'bar', prefix: 'foo' }; + +const builder = new DescriptorBuilder(ns); + +const typeStub = {} as RegisteredTypeDef; +builder.addTrait(typeStub , false); + +const descriptor = builder.build(); + +if (ns === descriptor.ns) { +} + +descriptor.allTypes.forEach(t => { + // do something + // for example, check the type + expectType(t); +}); + +for (const name of Object.keys(descriptor.allTypesByName)) { + // do something + // for example, check the type + expectType(name); + + //when + const type = descriptor.allTypesByName[name]; + //then + expectType(type); +} + +descriptor.properties.forEach(p => { + if (p.definedBy?.name === descriptor.name) { + } + + if (p.inherited) { + } + + if (p.localName === p.ns.localName) { + } + + if (p.isMany) { + } + + expectType(p); +}); + +for (const name of Object.keys(descriptor.propertiesByName)) { + //when + const propertyDesc = descriptor.propertiesByName[name]; + //then + expectType(propertyDesc); + + if (propertyDesc == descriptor.bodyProperty) { + } + + if (propertyDesc == descriptor.idProperty) { + } +} + diff --git a/lib/factory.js b/lib/factory.js index 8fb8ff8..8021e80 100644 --- a/lib/factory.js +++ b/lib/factory.js @@ -5,6 +5,49 @@ import { import Base from './base.js'; +/** + * @typedef {import('./ns.js').Namespace} Namespace + * @typedef {import('./moddle.js').default} Moddle + * @typedef {import('./properties.js').default} Properties + * @typedef {import('./registry.js').EffectiveDescriptor} EffectiveDescriptor + * @typedef {import('./base.js').default} BaseElement + * @typedef {import('./descriptor-builder.js').AnyTypeDescriptor} AnyTypeDescriptor + */ + +/** + * @template [T=Record] + * @typedef {{ + * new(attrs?: Partial): ModdleElement; + * prototype: ModdleElement; + * readonly $model: Moddle; + * readonly $descriptor: EffectiveDescriptor; + * }} ModdleElementType + */ + +/** + * @template [T=Record] + * @typedef {BaseElement & T & { + * readonly $model: Moddle; + * readonly $descriptor: EffectiveDescriptor; + * readonly $type: Namespace['name']; + * readonly $attrs: Record; + * $parent?: ModdleElement | AnyModdleElement; + * hasType: Moddle['hasType']; + * $instanceOf: Moddle['hasType']; + * }} ModdleElement + */ + +/** + * @template [T=Record] + * @typedef {BaseElement & T & { + * $type: string; + * $instanceOf: (type: string) => boolean; + * $parent?: ModdleElement | AnyModdleElement; + * readonly $model: Moddle; + * readonly $descriptor: AnyTypeDescriptor; + * }} AnyModdleElement + */ + /** * A model element factory. * @@ -12,11 +55,23 @@ import Base from './base.js'; * @param {Properties} properties */ export default function Factory(model, properties) { + + /** + * @private + */ this.model = model; + + /** + * @private + */ this.properties = properties; } - +/** + * @template [T=Record] + * @param {EffectiveDescriptor} descriptor + * @return {ModdleElementType} + */ Factory.prototype.createType = function(descriptor) { var model = this.model; @@ -38,6 +93,8 @@ Factory.prototype.createType = function(descriptor) { /** * The new type constructor + * + * @type { ModdleElementType } */ function ModdleElement(attrs) { props.define(this, '$type', { value: name, enumerable: true }); diff --git a/lib/factory.spec.ts b/lib/factory.spec.ts new file mode 100644 index 0000000..185257a --- /dev/null +++ b/lib/factory.spec.ts @@ -0,0 +1,65 @@ +import { expectType } from 'ts-expect'; + +import Factory, { AnyModdleElement, ModdleElement, ModdleElementType } from './factory.js'; +import { Moddle } from './index.js'; +import { EffectiveDescriptor } from './registry.js'; +import Base from './base.js'; +import Properties from './properties.js'; + +const factory = new Factory({} as Moddle, {} as Properties); + + +// when +const elementTypeFromFactory = factory.createType({} as EffectiveDescriptor); +// then +expectType(elementTypeFromFactory); + + +// when +const Element = factory.createType<{ foo: string }>({} as EffectiveDescriptor); +// then +expectType>(Element); + + +// when +const element = new Element(); +// then +expectType(element.foo); +expectType(element.$type); +expectType(element.$model); + + +// asset valid type values + +// when +const moddelElementStub = {} as ModdleElement<{ foo: string, bar: number, baz: ModdleElement }>; +// then +expectType(moddelElementStub.get); +expectType(moddelElementStub.set); +expectType(moddelElementStub.$model); +expectType(moddelElementStub.$descriptor); +expectType(moddelElementStub.$type); +expectType>(moddelElementStub.$attrs); +expectType(moddelElementStub.hasType); +expectType(moddelElementStub.$instanceOf); +expectType(moddelElementStub.$parent); +expectType(moddelElementStub.foo); +expectType(moddelElementStub.bar); +expectType(moddelElementStub.baz); + + +// when +const fuzzyElement = {} as ModdleElement; +// then +expectType(fuzzyElement.someProperty); + + +// when +type RefType = { foo: string, bar: number, baz: ModdleElement }; +const ModdelElementType = {} as ModdleElementType; +const moddelElementType = new ModdelElementType({ foo: 'bar' }); +// then +expectType>(moddelElementType); +expectType(ModdelElementType.$model); +expectType(ModdelElementType.$descriptor); +expectType>(ModdelElementType.prototype); \ No newline at end of file diff --git a/lib/moddle.js b/lib/moddle.js index 6e8a3ee..fe6e33b 100644 --- a/lib/moddle.js +++ b/lib/moddle.js @@ -13,6 +13,82 @@ import { parseName as parseNameNs } from './ns.js'; +/** + * @typedef {import('./registry.js').RegisteredTypeDef} RegisteredTypeDef + * @typedef {import('./registry.js').RegisteredPackage} RegisteredPackage + * @typedef {import('./base.js').default} BaseElement + * @typedef {import('./descriptor-builder.js').EffectiveDescriptor} EffectiveDescriptor + * @typedef {import('./descriptor-builder.js').AnyTypeDescriptor} AnyTypeDescriptor + * @typedef {import('./descriptor-builder.js').PropertyDescriptor} PropertyDescriptor + */ + +/** + * @template [T=Record] + * @typedef {import('./factory.js').ModdleElement} ModdleElement + * @typedef {import('./factory.js').ModdleElementType} ModdleElementType + * @typedef {import('./factory.js').AnyModdleElement} AnyModdleElement + */ + +/** + * Package definition + * @typedef {{ + * $schema?: string; + * name: string; + * prefix: string; + * types?: Array; + * [key: string]: any; + * } & PackageDefinitionXmlExtension} PackageDefinition + */ + +/** + * Set of extended parameters for package definition used in moddle-xml. + * @typedef {{ + * uri?: string; + * xml?: { + * tagAlias?: 'lowerCase'; + * typePrefix?: string; + * }; + * }} PackageDefinitionXmlExtension + */ + +/** + * Type definition in declaration in package + * @typedef {{ + * name: string; + * isAbstract?: boolean; + * properties?: Array; + * superClass?: Array; + * extends?: Array; + * meta?: Record; + * [key: string]: any; + * }} TypeDefinition + */ + +/** + * Set of extended parameters for property definition used in moddle-xml. + * @typedef {{ + * isBody?: boolean; + * isAttr?: boolean; + * xml?: { + * serialize?: string; + * }; + * }} PropertyDefinitionXmlExtension + */ + +/** + * Property definition of type definition + * @typedef {{ + * name: string; + * type: 'String' | 'Boolean' | 'Integer' | 'Real' | string; + * default?: string | boolean | number; + * isMany?: boolean; + * isReference?: boolean; + * isId?: boolean; + * redefines?: string; + * replaces?: string; + * [key: string]: any; + * } & PropertyDefinitionXmlExtension} PropertyDefinition + */ // Moddle implementation ///////////////////////////////////////////////// @@ -23,7 +99,7 @@ import { * * @example * - * var Moddle = require('moddle'); + * import Moddle from 'moddle'; * * var pkg = { * name: 'mypackage', @@ -35,23 +111,31 @@ import { * * var moddle = new Moddle([pkg]); * - * @param {Array} packages the packages to contain - * - * @param { { strict?: boolean } } [config] moddle configuration + * @param {Array | Record} packages the packages to contain + * @param {{ strict?: boolean }} [config={}] moddle configuration */ export default function Moddle(packages, config = {}) { + /** @type Readonly */ this.properties = new Properties(this); + /** @type Readonly */ this.factory = new Factory(this, this.properties); + + /** @type Readonly */ this.registry = new Registry(packages, this.properties); + /** + * @type {Record} + */ this.typeCache = {}; + /** + * @type {Readonly<{readonly strict?: boolean}>} + */ this.config = config; } - /** * Create an instance of the specified type. * @@ -62,9 +146,10 @@ export default function Moddle(packages, config = {}) { * var foo = moddle.create('my:Foo'); * var bar = moddle.create('my:Bar', { id: 'BAR_1' }); * - * @param {String|Object} descriptor the type descriptor or name know to the model - * @param {Object} attrs a number of attributes to initialize the model instance with - * @return {Object} model instance + * @template [T=Record] + * @param {String|EffectiveDescriptor} descriptor the type descriptor or name know to the model + * @param {Partial} [attrs] a number of attributes to initialize the model instance with + * @return {ModdleElement} model instance */ Moddle.prototype.create = function(descriptor, attrs) { var Type = this.getType(descriptor); @@ -76,7 +161,6 @@ Moddle.prototype.create = function(descriptor, attrs) { return new Type(attrs); }; - /** * Returns the type representing a given descriptor * @@ -87,8 +171,9 @@ Moddle.prototype.create = function(descriptor, attrs) { * var Foo = moddle.getType('my:Foo'); * var foo = new Foo({ 'id' : 'FOO_1' }); * - * @param {String|Object} descriptor the type descriptor or name know to the model - * @return {Object} the type representing the descriptor + * @template [T=Record] + * @param {String|EffectiveDescriptor} descriptor the type descriptor or name know to the model + * @return {ModdleElementType} the type representing the descriptor */ Moddle.prototype.getType = function(descriptor) { @@ -106,7 +191,6 @@ Moddle.prototype.getType = function(descriptor) { return type; }; - /** * Creates an any-element type to be used within model instances. * @@ -128,16 +212,17 @@ Moddle.prototype.getType = function(descriptor) { * * // go ahead and serialize the stuff * - * + * @template [T=Record] * @param {String} name the name of the element * @param {String} nsUri the namespace uri of the element - * @param {Object} [properties] a map of properties to initialize the instance with - * @return {Object} the any type instance + * @param {T} [properties] a map of properties to initialize the instance with + * @return {AnyModdleElement} the any type instance */ Moddle.prototype.createAny = function(name, nsUri, properties) { var nameNs = parseNameNs(name); + /** @type AnyModdleElement */ var element = { $type: name, $instanceOf: function(type) { @@ -151,6 +236,7 @@ Moddle.prototype.createAny = function(name, nsUri, properties) { } }; + /** @type AnyTypeDescriptor */ var descriptor = { name: name, isGeneric: true, @@ -181,8 +267,8 @@ Moddle.prototype.createAny = function(name, nsUri, properties) { /** * Returns a registered package by uri or prefix - * - * @return {Object} the package + * @param {string} uriOrPrefix + * @return {RegisteredPackage} the package */ Moddle.prototype.getPackage = function(uriOrPrefix) { return this.registry.getPackage(uriOrPrefix); @@ -191,7 +277,7 @@ Moddle.prototype.getPackage = function(uriOrPrefix) { /** * Returns a snapshot of all known packages * - * @return {Object} the package + * @return {Readonly>} the package */ Moddle.prototype.getPackages = function() { return this.registry.getPackages(); @@ -199,16 +285,25 @@ Moddle.prototype.getPackages = function() { /** * Returns the descriptor for an element + * @param {ModdleElement | ModdleElementType} element + * @return {EffectiveDescriptor} */ Moddle.prototype.getElementDescriptor = function(element) { return element.$descriptor; }; /** + * @overload * Returns true if the given descriptor or instance * represents the given type. - * - * May be applied to this, if element is omitted. + * @param {ModdleElement | ModdleElementType} element + * @param {string} type + * @return {boolean} + */ +/** + * @overload + * @param {string} type + * @return {boolean} */ Moddle.prototype.hasType = function(element, type) { if (type === undefined) { @@ -223,13 +318,18 @@ Moddle.prototype.hasType = function(element, type) { /** * Returns the descriptor of an elements named property + * @param {ModdleElement | ModdleElementType} element + * @param {string} property + * @return {PropertyDescriptor} */ Moddle.prototype.getPropertyDescriptor = function(element, property) { return this.getElementDescriptor(element).propertiesByName[property]; }; /** - * Returns a mapped type's descriptor + * Return registered type definition + * @param {string} type + * @return {RegisteredTypeDef} */ Moddle.prototype.getTypeDescriptor = function(type) { return this.registry.typeMap[type]; diff --git a/lib/moddle.spec.ts b/lib/moddle.spec.ts new file mode 100644 index 0000000..4c4d28c --- /dev/null +++ b/lib/moddle.spec.ts @@ -0,0 +1,173 @@ +import { Moddle } from './index.js'; +import { PackageDefinition } from './moddle.js'; +import { ModdleElement } from './factory.js'; +import { expectType } from 'ts-expect'; +import { EffectiveDescriptor, RegisteredPackage } from './registry.js'; + +const packages: PackageDefinition[] = [ + { + $schema: 'http://localhost/example/scheme', + uri: 'http://localhost/example', + name: 'Example', + prefix: 'exmpl', + xml: { + tagAlias: 'lowerCase', + }, + types: [ + { + name: 'Base', + isAbstract: true, + meta: { + description: 'this is base element for all', + }, + }, + { + name: 'Root', + superClass: [ 'Base' ], + customAttribute: 'useless attribute', + properties: [ + { + name: 'code', + type: 'String', + isAttr: true, + }, + { + name: 'attributes', + type: 'Attributes', + }, + { + name: 'anyElements', + type: 'Element', + isMany: true, + }, + ], + }, + { + name: 'Attributes', + superClass: [ 'Base' ], + properties: [ + { + name: 'attribute', + type: 'exmpl:Attribute', + isMany: true, + }, + ], + }, + { + name: 'Attribute', + superClass: [ 'Base' ], + properties: [ + { + name: 'key', + type: 'String', + isAttr: true, + }, + { + name: 'value', + type: 'String', + isAttr: true, + }, + ], + }, + ], + }, +]; + + +const moddle = new Moddle(packages, { strict: true }); + + +// work with registered type elements +const AttributeType = moddle.getType<{ key: string, value: string }>('exmpl:Attribute'); + +const attribute = AttributeType.$model.create(AttributeType.$descriptor, { key: 'guid', value: '44e3-4a40-a0a0' }); + +type RootModdelType = { location: string, attributes: ModdleElement<{ attribute: [] }> }; + +const root = moddle.create('exmpl:Root'); + +root.get('code'); + +const attrs = moddle.create<{ attribute: ModdleElement[] }>('exmpl:Attributes', { attribute: [ attribute ] }); + +attrs.$parent = root; + +root.set('attributes', [ attrs ]); + +attribute.$parent = attrs; + +if (attrs.$type === undefined || attribute.$attrs.value === undefined) { + // nothing +} + +if (attrs.hasType('unknown:Type') || attrs.$instanceOf(root, 'exmpl:Attributes')) { + // nothing +} else if (attrs.hasType(AttributeType, 'unknown:type')) { + // good, but nothing +} else if (attrs.hasType(root, 'foo:bar') || moddle.hasType(root, 'foo:bar')) { + // mmm..... nothing +} + + +// work with any type element +const anyModdelElement = moddle.createAny( + 'anyElement1', + 'http://localhost/anyElement1', + { foo: '', bar: 17, baz: {} as ModdleElement }, +); + +root.set('anyElements', [ anyModdelElement ]); + +anyModdelElement.$parent = root; + +anyModdelElement.get('bar'); + +anyModdelElement.set('baz', undefined); + +const fooVal = anyModdelElement.foo; +expectType(fooVal); + +const barVal = anyModdelElement.bar; +expectType(barVal); + +const bazVal = anyModdelElement.baz; +expectType(bazVal); + +const anyElementType = anyModdelElement.$type; +expectType(anyElementType); + +anyModdelElement.$instanceOf('anyElement2'); + +anyModdelElement.$parent = moddle.createAny('anyElement2', 'http://localhost/anyElement2'); + + +const effectiveDescriptor1 = moddle.getElementDescriptor(AttributeType); +expectType(effectiveDescriptor1); + +const effectiveDescriptor2 = moddle.getElementDescriptor(root); +expectType(effectiveDescriptor2); + + +const registeredPackage = moddle.getPackage('exmpl'); +expectType(registeredPackage); + +const registeredPackages = moddle.getPackages(); +const firstType = registeredPackages.map(pkg => pkg.types)[0]; +const firstTypeName = firstType?.map(t => t?.ns?.name)[0]; +expectType(firstTypeName); + + +const attrsPropDesc = moddle.getPropertyDescriptor(attrs, 'attribute'); +if (attrsPropDesc.isMany === true) { + // good +} + +const attrPropDesc = moddle.getPropertyDescriptor(AttributeType, 'key'); +attrPropDesc.isAttr ? void 0 : void 0; + + +const typeDef = moddle.getTypeDescriptor('exmpl:Root'); + +if (typeDef?.superClass?.[1] === 'BaseElement') { + // it's OK +} \ No newline at end of file diff --git a/lib/ns.js b/lib/ns.js index 927465f..251d063 100644 --- a/lib/ns.js +++ b/lib/ns.js @@ -1,3 +1,11 @@ +/** + * @typedef {{ + * name: string; + * prefix: string; + * localName: string; + * }} Namespace + */ + /** * Parses a namespaced attribute name of the form (ns:)localName to an object, * given a default prefix to assume in case no explicit namespace is given. @@ -5,7 +13,7 @@ * @param {String} name * @param {String} [defaultPrefix] the default prefix to take, if none is present. * - * @return {Object} the parsed name + * @return {Namespace} the parsed name */ export function parseName(name, defaultPrefix) { var parts = name.split(/:/), diff --git a/lib/ns.spec.ts b/lib/ns.spec.ts new file mode 100644 index 0000000..95a73b9 --- /dev/null +++ b/lib/ns.spec.ts @@ -0,0 +1,14 @@ +import { expectType } from 'ts-expect'; + +import { parseName } from './ns.js'; + +// when +const ns = parseName('foo:bar', 'baz'); +// then +expectType<{ name: string, localName: string, prefix: string }>(ns); + + +// when +const { prefix } = parseName('foo:bar'); +// then +expectType(prefix); diff --git a/lib/properties.js b/lib/properties.js index f57e8c4..6682ed4 100644 --- a/lib/properties.js +++ b/lib/properties.js @@ -3,21 +3,30 @@ import { isString } from 'min-dash'; +/** + * @typedef {import('./moddle.js').default} Moddle + * @typedef {import('./descriptor-builder.js').PropertyDescriptor} PropertyDesc + * @typedef {import('./registry.js').EffectiveDescriptor} EffectiveDescriptor + * @typedef {import('./factory.js').ModdleElement} ModdleElement + * @typedef {import('./descriptor-builder.js').AnyTypeDescriptor} AnyTypeDescriptor + */ + /** * A utility that gets and sets properties of model elements. * - * @param {Model} model + * @param {Moddle} model */ export default function Properties(model) { + + /** @type {Moddle} */ this.model = model; } - /** * Sets a named property on the target element. * If the value is undefined, the property gets deleted. * - * @param {Object} target + * @param {ModdleElement} target * @param {String} name * @param {Object} value */ @@ -59,7 +68,7 @@ Properties.prototype.set = function(target, name, value) { /** * Returns the named property of the given element * - * @param {Object} target + * @param {ModdleElement} target * @param {String} name * * @return {Object} @@ -82,13 +91,12 @@ Properties.prototype.get = function(target, name) { return target[propertyName]; }; - /** * Define a property on the target element - * - * @param {Object} target + * @template [T=any] + * @param {NonNullable} target * @param {String} name - * @param {Object} options + * @param {PropertyDescriptor} options */ Properties.prototype.define = function(target, name, options) { @@ -108,9 +116,11 @@ Properties.prototype.define = function(target, name, options) { Object.defineProperty(target, name, options); }; - /** * Define the descriptor for an element + * @template [T=any] + * @param {NonNullable} target + * @param {EffectiveDescriptor | AnyTypeDescriptor} descriptor */ Properties.prototype.defineDescriptor = function(target, descriptor) { this.define(target, '$descriptor', { value: descriptor }); @@ -118,6 +128,9 @@ Properties.prototype.defineDescriptor = function(target, descriptor) { /** * Define the model for an element + * @template [T=any] + * @param {NonNullable} target + * @param {Moddle} model */ Properties.prototype.defineModel = function(target, model) { this.define(target, '$model', { value: model }); @@ -126,10 +139,10 @@ Properties.prototype.defineModel = function(target, model) { /** * Return property with the given name on the element. * - * @param {any} target + * @param {ModdleElement} target * @param {string} name * - * @return {object | null} property + * @return {PropertyDesc | null} property */ Properties.prototype.getProperty = function(target, name) { diff --git a/lib/properties.spec.ts b/lib/properties.spec.ts new file mode 100644 index 0000000..197a39c --- /dev/null +++ b/lib/properties.spec.ts @@ -0,0 +1,41 @@ +import { expectType } from 'ts-expect'; + +import Properties from './properties.js'; +import { Moddle } from './index.js'; +import { ModdleElement } from './factory.js'; +import { EffectiveDescriptor } from './registry.js'; +import { AnyTypeDescriptor, PropertyDescriptor as PropertyDesc } from './descriptor-builder.js'; + + +const properties = new Properties({} as Moddle); + +expectType(properties.model); + +const moddelElementStub = {} as ModdleElement; + +properties.set(moddelElementStub, 'prop1', undefined); +properties.set(moddelElementStub, 'prop2', null); +properties.set(moddelElementStub, 'prop3', true); +properties.set(moddelElementStub, 'prop4', 1); +properties.set(moddelElementStub, 'prop5', 'string value'); +properties.set(moddelElementStub, 'prop6', []); +properties.set(moddelElementStub, 'prop7', {} as ModdleElement); + +expectType(properties.get(moddelElementStub, 'prop1')); +expectType(properties.get(moddelElementStub, 'prop2')); +expectType(properties.get(moddelElementStub, 'prop3')); +expectType(properties.get(moddelElementStub, 'prop4')); +expectType(properties.get(moddelElementStub, 'prop5')); +expectType>(properties.get(moddelElementStub, 'prop6')); +expectType(properties.get(moddelElementStub, 'prop7')); + +properties.define(moddelElementStub, '$foo', { writable: false } as PropertyDescriptor); +properties.define<{ foo: string }>({ foo: 'bar' }, '$baz', {} as PropertyDescriptor); + +properties.defineDescriptor(moddelElementStub, {} as EffectiveDescriptor); +properties.defineDescriptor<{ foo: string }>({ foo: 'bar' }, {} as AnyTypeDescriptor); + +properties.defineModel(moddelElementStub, {} as Moddle); +properties.defineModel<{ foo: string }>({ foo: 'bar' }, {} as Moddle); + +expectType(properties.getProperty(moddelElementStub, 'prop1')); diff --git a/lib/registry.js b/lib/registry.js index 6acd246..3ccedd3 100644 --- a/lib/registry.js +++ b/lib/registry.js @@ -14,34 +14,94 @@ import { parseName as parseNameNs } from './ns.js'; +/** + * @typedef {import('./ns.js').Namespace} Namespace + * @typedef {import('./moddle.js').PackageDefinition} PackageDefinition + * @typedef {import('./moddle.js').TypeDefinition} TypeDefinition + * @typedef {import('./moddle.js').PropertyDefinition} PropertyDefinition + * @typedef {import('./properties.js').default} Properties + * @typedef {import('./descriptor-builder.js').EffectiveDescriptor} EffectiveDescriptor + */ + +/** + * Registered package definition + * @typedef {Omit & { + * types?: Array; + * }} RegisteredPackage + */ + +/** + * Registered type definition + * @typedef {Omit & { + * properties?: Array; + * propertiesByName?: Record; + * superClass?: Array; + * extends?: Array; + * meta?: Record; + * traits?: Array; + * ns?: Namespace; + * readonly $pkg?: RegisteredPackage; + * }} RegisteredTypeDef + */ + +/** + * Registered property definition + * @typedef {PropertyDefinition & { ns: Namespace }} RegisteredPropertyDef + */ /** * A registry of Moddle packages. * - * @param {Array} packages + * @param {Array | Record} packages * @param {Properties} properties */ export default function Registry(packages, properties) { + + /** + * @private + * @type {Record} registered packages map + */ this.packageMap = {}; + + /** + * @type {Record} + */ this.typeMap = {}; + /** + * @private + * @type {Array} all registered packages + */ this.packages = []; + /** + * @private + * @type {Properties} + */ this.properties = properties; forEach(packages, bind(this.registerPackage, this)); } - +/** + * @param {string} uriOrPrefix uri or prefix of package + * @return {RegisteredPackage} registered package + */ Registry.prototype.getPackage = function(uriOrPrefix) { return this.packageMap[uriOrPrefix]; }; +/** + * @return {Array} all registered packages + */ Registry.prototype.getPackages = function() { return this.packages; }; - +/** + * @private + * @param {PackageDefinition} pkg registering package + */ Registry.prototype.registerPackage = function(pkg) { // copy package @@ -61,12 +121,13 @@ Registry.prototype.registerPackage = function(pkg) { this.packages.push(pkg); }; - /** + * @private * Register a type from a specific package with us + * @param {TypeDefinition} type + * @param {RegisteredPackage} pkg */ Registry.prototype.registerType = function(type, pkg) { - type = assign({}, type, { superClass: (type.superClass || []).slice(), extends: (type.extends || []).slice(), @@ -76,7 +137,7 @@ Registry.prototype.registerType = function(type, pkg) { var ns = parseNameNs(type.name, pkg.prefix), name = ns.name, - propertiesByName = {}; + /** @type {Record} */ propertiesByName = {}; // parse properties forEach(type.properties, bind(function(p) { @@ -121,18 +182,24 @@ Registry.prototype.registerType = function(type, pkg) { this.typeMap[name] = type; }; +/** + * @callback IteratorFn + * @param {RegisteredTypeDef} type + * @param {boolean} inherited + */ /** * Traverse the type hierarchy from bottom to top, * calling iterator with (type, inherited) for all elements in * the inheritance chain. - * - * @param {Object} nsName - * @param {Function} iterator + * @private + * @param {Namespace} nsName + * @param {IteratorFn} iterator * @param {Boolean} [trait=false] */ Registry.prototype.mapTypes = function(nsName, iterator, trait) { + /** @type {RegisteredTypeDef} */ var type = isBuiltInType(nsName.name) ? { name: nsName.name } : this.typeMap[nsName.name]; var self = this; @@ -178,13 +245,10 @@ Registry.prototype.mapTypes = function(nsName, iterator, trait) { forEach(type.traits, traverseTrait); }; - /** * Returns the effective descriptor for a type. - * - * @param {String} type the namespaced name (ns:localName) of the type - * - * @return {Descriptor} the resulting effective descriptor + * @param {Namespace['name']} name the namespaced name (ns:localName) of the type + * @return {EffectiveDescriptor} the resulting effective descriptor */ Registry.prototype.getEffectiveDescriptor = function(name) { @@ -204,15 +268,23 @@ Registry.prototype.getEffectiveDescriptor = function(name) { return descriptor; }; - +/** + * @private + * @param {RegisteredTypeDef | EffectiveDescriptor} target + * @param {RegisteredPackage} pkg + */ Registry.prototype.definePackage = function(target, pkg) { this.properties.define(target, '$pkg', { value: pkg }); }; - - // helpers //////////////////////////// +/** + * Checking already defined packages + * @param {Record} packageMap + * @param {PackageDefinition} pkg + * @param {'prefix' | 'uri'} identifierKey + */ function ensureAvailable(packageMap, pkg, identifierKey) { var value = pkg[identifierKey]; diff --git a/lib/registry.spec.ts b/lib/registry.spec.ts new file mode 100644 index 0000000..edb6ac6 --- /dev/null +++ b/lib/registry.spec.ts @@ -0,0 +1,33 @@ +import Registry, { RegisteredPackage, RegisteredTypeDef } from './registry.js'; +import { PackageDefinition } from './moddle.js'; +import Properties from './properties.js'; +import { Moddle } from './index.js'; +import { expectType } from 'ts-expect'; +import { EffectiveDescriptor } from './descriptor-builder.js'; + +const packagesStub = {} as Record; + +const registry = new Registry(packagesStub, new Properties({} as Moddle)); + +//when +const desc = registry.getEffectiveDescriptor('some:element'); +//then +expectType(desc); + + +//when +const fooBarType = registry.typeMap['foo:bar']; +//then +expectType(fooBarType); + + +//when +const pkg = registry.getPackage('foo'); +//then +expectType(pkg); + + +//when +const pkgs = registry.getPackages(); +//then +expectType>(pkgs); diff --git a/lib/types.js b/lib/types.js index 0fdec4f..aaa7191 100644 --- a/lib/types.js +++ b/lib/types.js @@ -10,7 +10,7 @@ var BUILTINS = { }; /** - * Converters for built in types from string representations + * Converters for built-in types from string representations */ var TYPE_CONVERTERS = { String: function(s) { return s; }, @@ -19,8 +19,44 @@ var TYPE_CONVERTERS = { Real: function(s) { return parseFloat(s); } }; +/** + * @typedef {'String'} StringType + * @typedef {'Boolean'} BooleanType + * @typedef {'Integer'} IntegerType + * @typedef {'Real'} RealType + * @typedef {'Element'} ElementType + * @typedef {StringType | BooleanType | IntegerType | RealType} BuiltInSimpleType + * @typedef {BuiltInSimpleType | ElementType} BuiltInType + */ + +/** + * Convert given value to string + * @overlord + * @param {StringType} type + * @param {any} value + * @return {string} + */ +/** + * Convert given value to boolean + * @overlord + * @param {BooleanType} type + * @param {any} value + * @return {boolean} + */ +/** + * Convert given value to number + * @overlord + * @param {IntegerType | RealType} type + * @param {any} value + * @return {number} + */ /** * Convert a type to its real representation + * @template T + * @overlord + * @param {Exclude} type + * @param {T} value + * @return {T} */ export function coerceType(type, value) { @@ -35,13 +71,31 @@ export function coerceType(type, value) { /** * Return whether the given type is built-in + * @overload + * @param {BuiltInType} type + * @return {true} + */ +/** + * Return whether the given type is built-in + * @overload + * @param {Exclude} type + * @return {false} */ export function isBuiltIn(type) { return !!BUILTINS[type]; } /** - * Return whether the given type is simple + * Return true if the given type is simple + * @overload + * @param {BuiltInSimpleType} type + * @return {true} + */ +/** + * Return false the given type is not simple + * @overload + * @param {Exclude} type + * @return {false} */ export function isSimple(type) { return !!TYPE_CONVERTERS[type]; diff --git a/lib/types.spec.ts b/lib/types.spec.ts new file mode 100644 index 0000000..0f12fb2 --- /dev/null +++ b/lib/types.spec.ts @@ -0,0 +1,80 @@ +import { expectType } from 'ts-expect'; + +import { + BooleanType, + coerceType, + ElementType, + IntegerType, + isBuiltIn, + isSimple, + RealType, + StringType +} from './types.js'; + +// when +const isBuiltInTypes = isBuiltIn('String') && isBuiltIn('Real') && isBuiltIn('Integer') && isBuiltIn('Boolean') && + isBuiltIn('Element'); +// then +expectType(isBuiltInTypes); + + +// when +const isBuiltInType = isBuiltIn('foo:bar'); +// then +expectType(isBuiltInType); + + +// when +const isSimpleTypes = isSimple('String') && isSimple('Real') && isSimple('Integer') && isSimple('Boolean'); +// then +expectType(isSimpleTypes); + + +// when +const isBuiltInPrimitives = isSimple('foo:bar') || isSimple('Element'); +// then +expectType(isBuiltInPrimitives); + + +// when +const stringValue = coerceType('String', 'string value'); +// then +expectType(stringValue); + + +// when +const realValue = coerceType('Real', '1.34'); +// then +expectType(realValue); + + +// when +const intValue = coerceType('Integer', '2'); +// then +expectType(intValue); + + +// when +const booleanValue = coerceType('Boolean', '2'); +// then +expectType(booleanValue); + + +// when +const objValue = coerceType('foo:bar', { foo: 'bar' }); +// then +expectType<{ foo: string }>(objValue); + + +// when +const numArrayValue = coerceType('Element', [ 1 ]); +// then +expectType(numArrayValue); + + +// asset valid type values +expectType('String'); +expectType('Boolean'); +expectType('Integer'); +expectType('Real'); +expectType('Element'); \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 058531b..4e0e140 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,13 +14,17 @@ "devDependencies": { "ajv": "^8.17.1", "ajv-cli": "^5.0.0", + "bio-dts": "^0.12.0", "chai": "^4.5.0", + "del-cli": "^6.0.0", "eslint": "^9.17.0", "eslint-plugin-bpmn-io": "^2.0.2", "fast-glob": "^3.3.3", "mocha": "^10.8.2", "npm-run-all": "^4.1.2", - "rollup": "^4.30.1" + "rollup": "^4.30.1", + "ts-expect": "^1.3.0", + "typescript": "^5.7.2" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -32,6 +36,56 @@ "node": ">=0.10.0" } }, + "node_modules/@babel/helper-string-parser": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", + "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.3.tgz", + "integrity": "sha512-WJ/CvmY8Mea8iDXo6a7RK2wbmJITT5fN3BEkRuFlxVyNx8jOKIIhmC4fSkTcPcf8JyavbBwIe6OpiCOBXt/IcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.26.3" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/types": { + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.3.tgz", + "integrity": "sha512-vN5p+1kl59GVKMvTHt55NzzmYVxprfJD+ql7U9NFIfKCBkYE55LYtS+WtPlaYOyzydrKI8Nezd+aZextrd+FMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -532,6 +586,19 @@ "win32" ] }, + "node_modules/@sindresorhus/merge-streams": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz", + "integrity": "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@types/estree": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", @@ -854,6 +921,19 @@ "node": "*" } }, + "node_modules/ast-types": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.16.1.tgz", + "integrity": "sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/available-typed-arrays": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", @@ -885,6 +965,21 @@ "node": ">=8" } }, + "node_modules/bio-dts": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/bio-dts/-/bio-dts-0.12.0.tgz", + "integrity": "sha512-hzKQGAR3uoyurX9TCpYl6b0aJC8M7ss+z/p6EOHYxdJueNeqc8XEhE6/1U++rKvRR0nLsIdAwWXVul5AXqLrfw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.26.3", + "recast": "^0.23.9", + "tiny-glob": "^0.2.9" + }, + "bin": { + "bio-dts": "bin/cmd.js" + } + }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -1296,6 +1391,48 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/del": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/del/-/del-8.0.0.tgz", + "integrity": "sha512-R6ep6JJ+eOBZsBr9esiNN1gxFbZE4Q2cULkUSFumGYecAiS6qodDvcPx/sFuWHMNul7DWmrtoEOpYSm7o6tbSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "globby": "^14.0.2", + "is-glob": "^4.0.3", + "is-path-cwd": "^3.0.0", + "is-path-inside": "^4.0.0", + "p-map": "^7.0.2", + "slash": "^5.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/del-cli": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/del-cli/-/del-cli-6.0.0.tgz", + "integrity": "sha512-9nitGV2W6KLFyya4qYt4+9AKQFL+c0Ehj5K7V7IwlxTc6RMCfQUGY9E9pLG6e8TQjtwXpuiWIGGZb3mfVxyZkw==", + "dev": true, + "license": "MIT", + "dependencies": { + "del": "^8.0.0", + "meow": "^13.2.0" + }, + "bin": { + "del": "cli.js", + "del-cli": "cli.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/diff": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", @@ -2247,6 +2384,54 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/globalyzer": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/globalyzer/-/globalyzer-0.1.0.tgz", + "integrity": "sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/globby": { + "version": "14.0.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-14.0.2.tgz", + "integrity": "sha512-s3Fq41ZVh7vbbe2PN3nrW7yC7U7MFVc5c98/iTl9c2GawNMKx/J648KQRW6WKkuU8GIbbh2IXfIRQjOZnXcTnw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sindresorhus/merge-streams": "^2.1.0", + "fast-glob": "^3.3.2", + "ignore": "^5.2.4", + "path-type": "^5.0.0", + "slash": "^5.1.0", + "unicorn-magic": "^0.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby/node_modules/path-type": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-5.0.0.tgz", + "integrity": "sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globrex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", + "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==", + "dev": true, + "license": "MIT" + }, "node_modules/gopd": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", @@ -2693,6 +2878,32 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-path-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-3.0.0.tgz", + "integrity": "sha512-kyiNFFLU0Ampr6SDZitD/DwUo4Zs1nSdnygUBqsu3LooL00Qvb5j+UnvApUn/TTj1J3OuE6BTdQ5rudKmU2ZaA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-path-inside": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-4.0.0.tgz", + "integrity": "sha512-lJJV/5dYS+RcL8uQdBDW9c9uWFLLBNRyFhnAKXw5tVqLlKZ4RMGZKv+YQ/IA3OhD+RpbJa1LLFM1FQPGyIXvOA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-plain-obj": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", @@ -3084,6 +3295,19 @@ "node": ">= 0.10.0" } }, + "node_modules/meow": { + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-13.2.0.tgz", + "integrity": "sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -3502,6 +3726,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/p-map": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-7.0.3.tgz", + "integrity": "sha512-VkndIv2fIB99swvQoA65bm+fsmt6UNdGeIB0oxBs+WhAhdh08QA04JXpI7rbB9r08/nkbysKoya9rtDERYOYMA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -3726,6 +3963,23 @@ "node": ">=8.10.0" } }, + "node_modules/recast": { + "version": "0.23.9", + "resolved": "https://registry.npmjs.org/recast/-/recast-0.23.9.tgz", + "integrity": "sha512-Hx/BGIbwj+Des3+xy5uAtAbdCyqK9y9wbBcDFDYanLS9JnMqf7OeF87HQwUimE87OEc72mr6tkKUKMBBL+hF9Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ast-types": "^0.16.1", + "esprima": "~4.0.0", + "source-map": "~0.6.1", + "tiny-invariant": "^1.3.3", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">= 4" + } + }, "node_modules/reflect.getprototypeof": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.6.tgz", @@ -4042,6 +4296,29 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/slash": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", + "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/spdx-correct": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.2.tgz", @@ -4266,6 +4543,24 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/tiny-glob": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/tiny-glob/-/tiny-glob-0.2.9.tgz", + "integrity": "sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==", + "dev": true, + "license": "MIT", + "dependencies": { + "globalyzer": "0.1.0", + "globrex": "^0.1.2" + } + }, + "node_modules/tiny-invariant": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", + "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==", + "dev": true, + "license": "MIT" + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -4279,6 +4574,20 @@ "node": ">=8.0" } }, + "node_modules/ts-expect": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ts-expect/-/ts-expect-1.3.0.tgz", + "integrity": "sha512-e4g0EJtAjk64xgnFPD6kTBUtpnMVzDrMb12N1YZV0VvSlhnVT3SGxiYTLdGy8Q5cYHOIC/FAHmZ10eGrAguicQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD" + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -4391,6 +4700,20 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/typescript": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz", + "integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, "node_modules/unbox-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", @@ -4406,6 +4729,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/unicorn-magic": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", + "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -4621,6 +4957,37 @@ "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", "dev": true }, + "@babel/helper-string-parser": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", + "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", + "dev": true + }, + "@babel/helper-validator-identifier": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", + "dev": true + }, + "@babel/parser": { + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.3.tgz", + "integrity": "sha512-WJ/CvmY8Mea8iDXo6a7RK2wbmJITT5fN3BEkRuFlxVyNx8jOKIIhmC4fSkTcPcf8JyavbBwIe6OpiCOBXt/IcA==", + "dev": true, + "requires": { + "@babel/types": "^7.26.3" + } + }, + "@babel/types": { + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.3.tgz", + "integrity": "sha512-vN5p+1kl59GVKMvTHt55NzzmYVxprfJD+ql7U9NFIfKCBkYE55LYtS+WtPlaYOyzydrKI8Nezd+aZextrd+FMA==", + "dev": true, + "requires": { + "@babel/helper-string-parser": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9" + } + }, "@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -4909,6 +5276,12 @@ "dev": true, "optional": true }, + "@sindresorhus/merge-streams": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz", + "integrity": "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==", + "dev": true + }, "@types/estree": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", @@ -5133,6 +5506,15 @@ "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", "dev": true }, + "ast-types": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.16.1.tgz", + "integrity": "sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==", + "dev": true, + "requires": { + "tslib": "^2.0.1" + } + }, "available-typed-arrays": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", @@ -5154,6 +5536,17 @@ "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true }, + "bio-dts": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/bio-dts/-/bio-dts-0.12.0.tgz", + "integrity": "sha512-hzKQGAR3uoyurX9TCpYl6b0aJC8M7ss+z/p6EOHYxdJueNeqc8XEhE6/1U++rKvRR0nLsIdAwWXVul5AXqLrfw==", + "dev": true, + "requires": { + "@babel/parser": "^7.26.3", + "recast": "^0.23.9", + "tiny-glob": "^0.2.9" + } + }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -5441,6 +5834,30 @@ "object-keys": "^1.1.1" } }, + "del": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/del/-/del-8.0.0.tgz", + "integrity": "sha512-R6ep6JJ+eOBZsBr9esiNN1gxFbZE4Q2cULkUSFumGYecAiS6qodDvcPx/sFuWHMNul7DWmrtoEOpYSm7o6tbSA==", + "dev": true, + "requires": { + "globby": "^14.0.2", + "is-glob": "^4.0.3", + "is-path-cwd": "^3.0.0", + "is-path-inside": "^4.0.0", + "p-map": "^7.0.2", + "slash": "^5.1.0" + } + }, + "del-cli": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/del-cli/-/del-cli-6.0.0.tgz", + "integrity": "sha512-9nitGV2W6KLFyya4qYt4+9AKQFL+c0Ehj5K7V7IwlxTc6RMCfQUGY9E9pLG6e8TQjtwXpuiWIGGZb3mfVxyZkw==", + "dev": true, + "requires": { + "del": "^8.0.0", + "meow": "^13.2.0" + } + }, "diff": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", @@ -6104,6 +6521,40 @@ "gopd": "^1.0.1" } }, + "globalyzer": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/globalyzer/-/globalyzer-0.1.0.tgz", + "integrity": "sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q==", + "dev": true + }, + "globby": { + "version": "14.0.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-14.0.2.tgz", + "integrity": "sha512-s3Fq41ZVh7vbbe2PN3nrW7yC7U7MFVc5c98/iTl9c2GawNMKx/J648KQRW6WKkuU8GIbbh2IXfIRQjOZnXcTnw==", + "dev": true, + "requires": { + "@sindresorhus/merge-streams": "^2.1.0", + "fast-glob": "^3.3.2", + "ignore": "^5.2.4", + "path-type": "^5.0.0", + "slash": "^5.1.0", + "unicorn-magic": "^0.1.0" + }, + "dependencies": { + "path-type": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-5.0.0.tgz", + "integrity": "sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==", + "dev": true + } + } + }, + "globrex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", + "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==", + "dev": true + }, "gopd": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", @@ -6392,6 +6843,18 @@ "has-tostringtag": "^1.0.0" } }, + "is-path-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-3.0.0.tgz", + "integrity": "sha512-kyiNFFLU0Ampr6SDZitD/DwUo4Zs1nSdnygUBqsu3LooL00Qvb5j+UnvApUn/TTj1J3OuE6BTdQ5rudKmU2ZaA==", + "dev": true + }, + "is-path-inside": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-4.0.0.tgz", + "integrity": "sha512-lJJV/5dYS+RcL8uQdBDW9c9uWFLLBNRyFhnAKXw5tVqLlKZ4RMGZKv+YQ/IA3OhD+RpbJa1LLFM1FQPGyIXvOA==", + "dev": true + }, "is-plain-obj": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", @@ -6664,6 +7127,12 @@ "integrity": "sha1-htcJCzDORV1j+64S3aUaR93K+bI=", "dev": true }, + "meow": { + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-13.2.0.tgz", + "integrity": "sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==", + "dev": true + }, "merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -6964,6 +7433,12 @@ "p-limit": "^3.0.2" } }, + "p-map": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-7.0.3.tgz", + "integrity": "sha512-VkndIv2fIB99swvQoA65bm+fsmt6UNdGeIB0oxBs+WhAhdh08QA04JXpI7rbB9r08/nkbysKoya9rtDERYOYMA==", + "dev": true + }, "parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -7116,6 +7591,19 @@ "picomatch": "^2.2.1" } }, + "recast": { + "version": "0.23.9", + "resolved": "https://registry.npmjs.org/recast/-/recast-0.23.9.tgz", + "integrity": "sha512-Hx/BGIbwj+Des3+xy5uAtAbdCyqK9y9wbBcDFDYanLS9JnMqf7OeF87HQwUimE87OEc72mr6tkKUKMBBL+hF9Q==", + "dev": true, + "requires": { + "ast-types": "^0.16.1", + "esprima": "~4.0.0", + "source-map": "~0.6.1", + "tiny-invariant": "^1.3.3", + "tslib": "^2.0.1" + } + }, "reflect.getprototypeof": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.6.tgz", @@ -7319,6 +7807,18 @@ "object-inspect": "^1.13.1" } }, + "slash": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", + "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, "spdx-correct": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.2.tgz", @@ -7487,6 +7987,22 @@ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "dev": true }, + "tiny-glob": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/tiny-glob/-/tiny-glob-0.2.9.tgz", + "integrity": "sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==", + "dev": true, + "requires": { + "globalyzer": "0.1.0", + "globrex": "^0.1.2" + } + }, + "tiny-invariant": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", + "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==", + "dev": true + }, "to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -7496,6 +8012,18 @@ "is-number": "^7.0.0" } }, + "ts-expect": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ts-expect/-/ts-expect-1.3.0.tgz", + "integrity": "sha512-e4g0EJtAjk64xgnFPD6kTBUtpnMVzDrMb12N1YZV0VvSlhnVT3SGxiYTLdGy8Q5cYHOIC/FAHmZ10eGrAguicQ==", + "dev": true + }, + "tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true + }, "type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -7569,6 +8097,12 @@ "possible-typed-array-names": "^1.0.0" } }, + "typescript": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz", + "integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==", + "dev": true + }, "unbox-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", @@ -7581,6 +8115,12 @@ "which-boxed-primitive": "^1.0.2" } }, + "unicorn-magic": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", + "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==", + "dev": true + }, "uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", diff --git a/package.json b/package.json index 8f6d892..1d00133 100644 --- a/package.json +++ b/package.json @@ -3,20 +3,24 @@ "version": "7.2.0", "description": "A library for importing meta-model based file formats into JS", "scripts": { - "all": "run-s lint test test:schema", + "all": "run-s lint test test:schema generate-types", "lint": "eslint .", "pretest": "run-s build", "dev": "npm test -- --watch", "test": "mocha --reporter=spec --recursive test", "test:schema": "ajv -s resources/schema/moddle.json -d 'test/fixtures/**/*.json'", "build": "rollup -c", + "generate-types": "run-s generate-types:*", + "generate-types:generate": "del-cli \"lib/**/*.d.ts\" && npx bio-dts -r lib", + "generate-types:test": "tsc --noEmit --noImplicitAny", "prepare": "run-s build" }, "type": "module", "exports": { ".": { "import": "./dist/index.js", - "require": "./dist/index.cjs" + "require": "./dist/index.cjs", + "types": "./lib/index.d.ts" }, "./package.json": "./package.json" }, @@ -47,19 +51,25 @@ "devDependencies": { "ajv": "^8.17.1", "ajv-cli": "^5.0.0", + "bio-dts": "^0.12.0", "chai": "^4.5.0", + "del-cli": "^6.0.0", "eslint": "^9.17.0", "eslint-plugin-bpmn-io": "^2.0.2", "fast-glob": "^3.3.3", "mocha": "^10.8.2", "npm-run-all": "^4.1.2", - "rollup": "^4.30.1" + "rollup": "^4.30.1", + "ts-expect": "^1.3.0", + "typescript": "^5.7.2" }, "dependencies": { "min-dash": "^4.2.1" }, + "types": "lib/index.d.ts", "files": [ "dist", + "lib/*.d.ts", "resources/schema/moddle.json" ] } diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..78fc07b --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "allowJs": true, + "checkJs": true, + "lib": [ + "ES2018" + ], + "strict": true, + "module": "nodenext" + }, + "include": [ + "./lib/*.js", + "./lib/*.d.ts", + "./lib/*.spec.ts" + ] +} \ No newline at end of file