Fix code quality violations and rename select input components

Move small tasks from wishlist to todo, update npm packages
Replace #[Auth] attributes with manual auth checks and code quality rule
Remove on_jqhtml_ready lifecycle method from framework
Complete ACL system with 100-based role indexing and /dev/acl tester
WIP: ACL system implementation with debug instrumentation
Convert rsx:check JS linting to RPC socket server
Clean up docs and fix $id→$sid in man pages, remove SSR/FPC feature
Reorganize wishlists: priority order, mark sublayouts complete, add email
Update model_fetch docs: mark MVP complete, fix enum docs, reorganize
Comprehensive documentation overhaul: clarity, compression, and critical rules
Convert Contacts/Projects CRUD to Model.fetch() and add fetch_or_null()
Add JS ORM relationship lazy-loading and fetch array handling
Add JS ORM relationship fetching and CRUD documentation
Fix ORM hydration and add IDE resolution for Base_* model stubs
Rename Json_Tree_Component to JS_Tree_Debug_Component and move to framework
Enhance JS ORM infrastructure and add Json_Tree class name badges

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
root
2025-11-23 21:39:43 +00:00
parent 78553d4edf
commit 84ca3dfe42
167 changed files with 7538 additions and 49164 deletions

38
node_modules/.package-lock.json generated vendored
View File

@@ -2211,9 +2211,9 @@
}
},
"node_modules/@jqhtml/core": {
"version": "2.2.218",
"resolved": "http://privatenpm.hanson.xyz/@jqhtml/core/-/core-2.2.218.tgz",
"integrity": "sha512-CEbrpoi70Y5ET1fBXHK38fZTi5MAtZEY2c779mwjw3Dn7SjpoxvCYet/AJLJI7lngA6eJl9BPaPwALMHbafkLQ==",
"version": "2.2.220",
"resolved": "http://privatenpm.hanson.xyz/@jqhtml/core/-/core-2.2.220.tgz",
"integrity": "sha512-Ig2P8LGKbWbTVVpSMWIIt5MQejFlhF1kVKudHbTM78Gsw4RYLg2jk2/f22Az4uDqQiVdtjT/E/cVlPrcgk2NRg==",
"license": "MIT",
"dependencies": {
"@rollup/plugin-node-resolve": "^16.0.1",
@@ -2237,9 +2237,9 @@
}
},
"node_modules/@jqhtml/parser": {
"version": "2.2.218",
"resolved": "http://privatenpm.hanson.xyz/@jqhtml/parser/-/parser-2.2.218.tgz",
"integrity": "sha512-i8Y/tx/mIwhAw8YZd99j2i8iLWSU/9Ua88u4p0h3sCCeIWGT7QGvrr7vF+OiUcb8ECtX1188ODlHWdWt7vb45w==",
"version": "2.2.220",
"resolved": "http://privatenpm.hanson.xyz/@jqhtml/parser/-/parser-2.2.220.tgz",
"integrity": "sha512-xN2pjoBSfo/2G681/z3Vi2NODXBGGI+Y6xDDdmqs01J/vCJ/ojEU/rLgwfXHGVRVRIaGsPfKPhI+EW2+5n57Bg==",
"license": "MIT",
"dependencies": {
"@types/jest": "^29.5.11",
@@ -2257,9 +2257,9 @@
}
},
"node_modules/@jqhtml/router": {
"version": "2.2.218",
"resolved": "http://privatenpm.hanson.xyz/@jqhtml/router/-/router-2.2.218.tgz",
"integrity": "sha512-aQum/FdDlqbtNbtkIJFN5sGNTBhlGBn5duclsyv0CYmJ8ruC2Gr0y5FILBeuc1lFSmG/6UJZ+eOlrQ4QDk2zng==",
"version": "2.2.220",
"resolved": "http://privatenpm.hanson.xyz/@jqhtml/router/-/router-2.2.220.tgz",
"integrity": "sha512-PgD/VdkpjlXbNCvHVEMX4o/DNLUTYyF57p+6Kcz+1cxSvHjIhaX72Bi2vkDORqCRloCCf3rG9yJecMOYDUg4GQ==",
"license": "MIT",
"dependencies": {
"@rollup/plugin-node-resolve": "^16.0.1",
@@ -2277,21 +2277,21 @@
}
},
"node_modules/@jqhtml/vscode-extension": {
"version": "2.2.218",
"resolved": "http://privatenpm.hanson.xyz/@jqhtml/vscode-extension/-/vscode-extension-2.2.218.tgz",
"integrity": "sha512-fEOcYqi2AVkLxxJ3ovwKqJQGpLI9C6sgcRWs3HVuDH6UYpNiRPUwzSxf/M7j+wZY5y5tt7KGSDK5JjbSj0PqqQ==",
"version": "2.2.220",
"resolved": "http://privatenpm.hanson.xyz/@jqhtml/vscode-extension/-/vscode-extension-2.2.220.tgz",
"integrity": "sha512-H9ZfHU/MueUhjE4UmkOh/lJiqNHB4pQEbRTjrPDRhz+XFwHm1+dImtrgpiePYCDDHxdRW1rbJKGQ2IWcUwJ2Mg==",
"license": "MIT",
"engines": {
"vscode": "^1.74.0"
}
},
"node_modules/@jqhtml/webpack-loader": {
"version": "2.2.218",
"resolved": "http://privatenpm.hanson.xyz/@jqhtml/webpack-loader/-/webpack-loader-2.2.218.tgz",
"integrity": "sha512-QN/4qTsxPjB9OWHdNVvif05ygw9FYblF6KYyHPvdZ0NNWNoUMYBcKizjjTjFAsUMqWQkT4RETx5XxkiomgKPPQ==",
"version": "2.2.220",
"resolved": "http://privatenpm.hanson.xyz/@jqhtml/webpack-loader/-/webpack-loader-2.2.220.tgz",
"integrity": "sha512-P21MC0xUKAHg0gWyYF+by7b6eJhss5vLngRqWSijm5bBfoRpI6n3jyIWIA/cG/hyBMxPGrh+UHKJJQjrfpCs7A==",
"license": "MIT",
"dependencies": {
"@jqhtml/parser": "2.2.218",
"@jqhtml/parser": "2.2.220",
"@types/loader-utils": "^2.0.6",
"@types/node": "^20.0.0",
"@types/webpack": "^5.28.5",
@@ -4017,9 +4017,9 @@
"license": "MIT"
},
"node_modules/baseline-browser-mapping": {
"version": "2.8.30",
"resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.30.tgz",
"integrity": "sha512-aTUKW4ptQhS64+v2d6IkPzymEzzhw+G0bA1g3uBRV3+ntkH+svttKseW5IOR4Ed6NUVKqnY7qT3dKvzQ7io4AA==",
"version": "2.8.31",
"resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.31.tgz",
"integrity": "sha512-a28v2eWrrRWPpJSzxc+mKwm0ZtVx/G8SepdQZDArnXYU/XS+IF6mp8aB/4E+hH1tyGCoDo3KlUCdlSxGDsRkAw==",
"license": "Apache-2.0",
"bin": {
"baseline-browser-mapping": "dist/cli.js"

View File

@@ -278,7 +278,7 @@ class CustomInput extends Component {
Templates compile to instruction arrays:
```javascript
[
{tag: ['div', {class: 'container', $id: 'root'}, false]},
{tag: ['div', {class: 'container', $sid: 'root'}, false]},
{text: 'Static content'},
{expr: function() { return this.data.title; }},
{comp: ['ChildComponent', {props: 'values'}, [

View File

@@ -260,7 +260,7 @@ class TabsComponent extends Component {
}
selectTab(tabId) {
// Use $id() for scoped selection
// Use $sid() for scoped selection
this.$sid('tab1').removeClass('active');
this.$sid('tab2').removeClass('active');
this.$sid(tabId).addClass('active');
@@ -428,7 +428,7 @@ await component.render(); // "Widget rendered" logs again
- `should_rerender()` - Control re-rendering after load
- `emit(event, data)` - Emit jQuery events
- `on(event, callback)` - Register lifecycle event callback
- `$id(localId)` - Get scoped jQuery element
- `$sid(localId)` - Get scoped jQuery element
- `id(localId)` - Get scoped component instance
- `parent()` - Get parent component
- `children()` - Get direct child components

View File

@@ -101,16 +101,26 @@ export declare class Jqhtml_Component {
_ready(): Promise<void>;
/**
* Public API: Wait for component to be fully ready
* Returns a promise that resolves when the component reaches ready state
* Returns a promise that resolves when the component reaches ready state.
* Optionally accepts a callback that executes when ready.
*
* @example
* await component.ready(); // Wait for component initialization
* // Promise pattern
* await component.ready();
*
* @example
* const child = this.id('child_component');
* await child.ready(); // Wait for child to be ready
* // Callback pattern
* component.ready(() => {
* console.log('Component is ready!');
* });
*
* @example
* // Both patterns work together
* await component.ready(() => console.log('Callback fired'));
*
* @param callback Optional callback to execute when ready
*/
ready(): Promise<void>;
ready(callback?: () => void): Promise<void>;
/**
* Wait for all child components to reach ready state
* Ensures bottom-up ordering (children ready before parent)

View File

@@ -1 +1 @@
{"version":3,"file":"component.d.ts","sourceRoot":"","sources":["../src/component.ts"],"names":[],"mappings":"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"}
{"version":3,"file":"component.d.ts","sourceRoot":"","sources":["../src/component.ts"],"names":[],"mappings":"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"}

View File

@@ -479,7 +479,7 @@ function process_instruction_to_html(instruction, html, tagElements, components,
function process_tag_to_html(instruction, html, tagElements, components, context) {
const [tagName, attrs, selfClosing] = instruction.tag;
// Check if we need to track this element for second pass
const needsTracking = Object.keys(attrs).some(key => key === '$id' || key.startsWith('$') || key.startsWith('@') ||
const needsTracking = Object.keys(attrs).some(key => key === '$sid' || key.startsWith('$') || key.startsWith('@') ||
key.startsWith('on') ||
key.startsWith('data-bind-') || key.startsWith('data-__-on-'));
// Start building tag
@@ -632,7 +632,7 @@ function process_rawtag_to_html(instruction, html) {
* Apply attributes with special handling to a DOM element
*
* This function processes various attribute types and applies them to the element:
* - $id: Creates component-scoped IDs (handled elsewhere in HTML generation)
* - $sid: Creates component-scoped IDs (handled elsewhere in HTML generation)
* - $*: Stored via jQuery .data() only (added to context.args for components)
* - @*: Event handlers with automatic preventDefault and context binding
* - on*: Standard event handlers with context binding
@@ -650,7 +650,7 @@ function process_rawtag_to_html(instruction, html) {
*/
function apply_attributes(element, attrs, context) {
for (const [key, value] of Object.entries(attrs)) {
if (key === '$id' || key === 'id') {
if (key === '$sid' || key === 'id') {
// Already handled in HTML generation
continue;
}
@@ -1811,23 +1811,39 @@ class Jqhtml_Component {
}
/**
* Public API: Wait for component to be fully ready
* Returns a promise that resolves when the component reaches ready state
* Returns a promise that resolves when the component reaches ready state.
* Optionally accepts a callback that executes when ready.
*
* @example
* await component.ready(); // Wait for component initialization
* // Promise pattern
* await component.ready();
*
* @example
* const child = this.id('child_component');
* await child.ready(); // Wait for child to be ready
* // Callback pattern
* component.ready(() => {
* console.log('Component is ready!');
* });
*
* @example
* // Both patterns work together
* await component.ready(() => console.log('Callback fired'));
*
* @param callback Optional callback to execute when ready
*/
ready() {
// If already ready, resolve immediately
ready(callback) {
// If already ready, execute callback immediately and resolve
if (this._ready_state >= 4) {
if (callback)
callback();
return Promise.resolve();
}
// Return promise that resolves when ready event fires
return new Promise((resolve) => {
this.on('ready', () => resolve());
this.on('ready', () => {
if (callback)
callback();
resolve();
});
});
}
/**
@@ -3354,7 +3370,7 @@ function init_jquery_plugin(jQuery) {
if (selector &&
typeof selector === 'object' &&
selector.$ &&
typeof selector.$id === 'function' &&
typeof selector.$sid === 'function' &&
typeof selector.id === 'function') {
// Return the component's jQuery element
return selector.$;
@@ -4221,7 +4237,7 @@ function init(jQuery) {
}
}
// Version - will be replaced during build with actual version from package.json
const version = '2.2.218';
const version = '2.2.220';
// Default export with all functionality
const jqhtml = {
// Core

File diff suppressed because one or more lines are too long

View File

@@ -475,7 +475,7 @@ function process_instruction_to_html(instruction, html, tagElements, components,
function process_tag_to_html(instruction, html, tagElements, components, context) {
const [tagName, attrs, selfClosing] = instruction.tag;
// Check if we need to track this element for second pass
const needsTracking = Object.keys(attrs).some(key => key === '$id' || key.startsWith('$') || key.startsWith('@') ||
const needsTracking = Object.keys(attrs).some(key => key === '$sid' || key.startsWith('$') || key.startsWith('@') ||
key.startsWith('on') ||
key.startsWith('data-bind-') || key.startsWith('data-__-on-'));
// Start building tag
@@ -628,7 +628,7 @@ function process_rawtag_to_html(instruction, html) {
* Apply attributes with special handling to a DOM element
*
* This function processes various attribute types and applies them to the element:
* - $id: Creates component-scoped IDs (handled elsewhere in HTML generation)
* - $sid: Creates component-scoped IDs (handled elsewhere in HTML generation)
* - $*: Stored via jQuery .data() only (added to context.args for components)
* - @*: Event handlers with automatic preventDefault and context binding
* - on*: Standard event handlers with context binding
@@ -646,7 +646,7 @@ function process_rawtag_to_html(instruction, html) {
*/
function apply_attributes(element, attrs, context) {
for (const [key, value] of Object.entries(attrs)) {
if (key === '$id' || key === 'id') {
if (key === '$sid' || key === 'id') {
// Already handled in HTML generation
continue;
}
@@ -1807,23 +1807,39 @@ class Jqhtml_Component {
}
/**
* Public API: Wait for component to be fully ready
* Returns a promise that resolves when the component reaches ready state
* Returns a promise that resolves when the component reaches ready state.
* Optionally accepts a callback that executes when ready.
*
* @example
* await component.ready(); // Wait for component initialization
* // Promise pattern
* await component.ready();
*
* @example
* const child = this.id('child_component');
* await child.ready(); // Wait for child to be ready
* // Callback pattern
* component.ready(() => {
* console.log('Component is ready!');
* });
*
* @example
* // Both patterns work together
* await component.ready(() => console.log('Callback fired'));
*
* @param callback Optional callback to execute when ready
*/
ready() {
// If already ready, resolve immediately
ready(callback) {
// If already ready, execute callback immediately and resolve
if (this._ready_state >= 4) {
if (callback)
callback();
return Promise.resolve();
}
// Return promise that resolves when ready event fires
return new Promise((resolve) => {
this.on('ready', () => resolve());
this.on('ready', () => {
if (callback)
callback();
resolve();
});
});
}
/**
@@ -3350,7 +3366,7 @@ function init_jquery_plugin(jQuery) {
if (selector &&
typeof selector === 'object' &&
selector.$ &&
typeof selector.$id === 'function' &&
typeof selector.$sid === 'function' &&
typeof selector.id === 'function') {
// Return the component's jQuery element
return selector.$;
@@ -4217,7 +4233,7 @@ function init(jQuery) {
}
}
// Version - will be replaced during build with actual version from package.json
const version = '2.2.218';
const version = '2.2.220';
// Default export with all functionality
const jqhtml = {
// Core

File diff suppressed because one or more lines are too long

View File

@@ -1,5 +1,5 @@
/**
* JQHTML Core v2.2.218
* JQHTML Core v2.2.220
* (c) 2025 JQHTML Team
* Released under the MIT License
*/
@@ -480,7 +480,7 @@ function process_instruction_to_html(instruction, html, tagElements, components,
function process_tag_to_html(instruction, html, tagElements, components, context) {
const [tagName, attrs, selfClosing] = instruction.tag;
// Check if we need to track this element for second pass
const needsTracking = Object.keys(attrs).some(key => key === '$id' || key.startsWith('$') || key.startsWith('@') ||
const needsTracking = Object.keys(attrs).some(key => key === '$sid' || key.startsWith('$') || key.startsWith('@') ||
key.startsWith('on') ||
key.startsWith('data-bind-') || key.startsWith('data-__-on-'));
// Start building tag
@@ -633,7 +633,7 @@ function process_rawtag_to_html(instruction, html) {
* Apply attributes with special handling to a DOM element
*
* This function processes various attribute types and applies them to the element:
* - $id: Creates component-scoped IDs (handled elsewhere in HTML generation)
* - $sid: Creates component-scoped IDs (handled elsewhere in HTML generation)
* - $*: Stored via jQuery .data() only (added to context.args for components)
* - @*: Event handlers with automatic preventDefault and context binding
* - on*: Standard event handlers with context binding
@@ -651,7 +651,7 @@ function process_rawtag_to_html(instruction, html) {
*/
function apply_attributes(element, attrs, context) {
for (const [key, value] of Object.entries(attrs)) {
if (key === '$id' || key === 'id') {
if (key === '$sid' || key === 'id') {
// Already handled in HTML generation
continue;
}
@@ -1812,23 +1812,39 @@ class Jqhtml_Component {
}
/**
* Public API: Wait for component to be fully ready
* Returns a promise that resolves when the component reaches ready state
* Returns a promise that resolves when the component reaches ready state.
* Optionally accepts a callback that executes when ready.
*
* @example
* await component.ready(); // Wait for component initialization
* // Promise pattern
* await component.ready();
*
* @example
* const child = this.id('child_component');
* await child.ready(); // Wait for child to be ready
* // Callback pattern
* component.ready(() => {
* console.log('Component is ready!');
* });
*
* @example
* // Both patterns work together
* await component.ready(() => console.log('Callback fired'));
*
* @param callback Optional callback to execute when ready
*/
ready() {
// If already ready, resolve immediately
ready(callback) {
// If already ready, execute callback immediately and resolve
if (this._ready_state >= 4) {
if (callback)
callback();
return Promise.resolve();
}
// Return promise that resolves when ready event fires
return new Promise((resolve) => {
this.on('ready', () => resolve());
this.on('ready', () => {
if (callback)
callback();
resolve();
});
});
}
/**
@@ -3355,7 +3371,7 @@ function init_jquery_plugin(jQuery) {
if (selector &&
typeof selector === 'object' &&
selector.$ &&
typeof selector.$id === 'function' &&
typeof selector.$sid === 'function' &&
typeof selector.id === 'function') {
// Return the component's jQuery element
return selector.$;
@@ -4222,7 +4238,7 @@ function init(jQuery) {
}
}
// Version - will be replaced during build with actual version from package.json
const version = '2.2.218';
const version = '2.2.220';
// Default export with all functionality
const jqhtml = {
// Core

File diff suppressed because one or more lines are too long

View File

@@ -1,6 +1,6 @@
{
"name": "@jqhtml/core",
"version": "2.2.218",
"version": "2.2.220",
"description": "Core runtime library for JQHTML",
"type": "module",
"main": "./dist/index.js",

View File

@@ -481,7 +481,7 @@ Templates compile to three instruction types:
{tag: ["div", {"class": "user-card"}, false]}
{tag: ["img", {"src": "/avatar.jpg", "alt": "User"}, true]}
{tag: ["button", {"onclick": this.handleClick}, false]}
{tag: ["div", {"data-sid": "header"}, false]} // $id becomes data-id
{tag: ["div", {"data-sid": "header"}, false]} // $sid becomes data-id
```
### 2. Component Instruction

View File

@@ -1348,7 +1348,7 @@ export class CodeGenerator {
for (const [name, component] of this.components) {
code += `// Component: ${name}\n`;
code += `jqhtml_components.set('${name}', {\n`;
code += ` _jqhtml_version: '2.2.218',\n`; // Version will be replaced during build
code += ` _jqhtml_version: '2.2.220',\n`; // Version will be replaced during build
code += ` name: '${name}',\n`;
code += ` tag: '${component.tagName}',\n`;
code += ` defaultAttributes: ${this.serializeAttributeObject(component.defaultAttributes)},\n`;

View File

@@ -1199,7 +1199,7 @@ export class Lexer {
`Only @ event attributes (unquoted) and $ attributes (either) allow unquoted values:\n` +
` ✓ Correct: @click=this.handleClick (passes function reference)\n` +
` ✓ Correct: $data=this.complexObject (passes object)\n` +
` ✓ Correct: $id="my-id" (passes string)`;
` ✓ Correct: $sid="my-id" (passes string)`;
throw error;
}
const value_start = this.position;

File diff suppressed because one or more lines are too long

View File

@@ -779,7 +779,7 @@ export class Parser {
' ✅ <% let attrs = expression ? \'value\' : \'\'; %>\n' +
' <tag attr="<%= attrs %>">\n\n' +
' Or set attributes in on_ready() using jQuery:\n' +
' ✅ <tag $id="my_element">\n' +
' ✅ <tag $sid="my_element">\n' +
' on_ready() {\n' +
' if (this.args.required) this.$sid(\'my_element\').attr(\'required\', true);\n' +
' }';

File diff suppressed because one or more lines are too long

View File

@@ -1,6 +1,6 @@
{
"name": "@jqhtml/parser",
"version": "2.2.218",
"version": "2.2.220",
"description": "JQHTML template parser - converts templates to JavaScript",
"type": "module",
"main": "dist/index.js",

View File

@@ -877,12 +877,12 @@ class Jqhtml_Layout extends core.Jqhtml_Component {
}
/**
* Get the content container where routes render
* Must contain an element with $id="content"
* Must contain an element with $sid="content"
*/
$content() {
const $content = this.$id('content');
const $content = this.$sid('content');
if (!$content.length) {
throw new Error(`Layout ${this.constructor.name} must have an element with $id="content"`);
throw new Error(`Layout ${this.constructor.name} must have an element with $sid="content"`);
}
return $content;
}

File diff suppressed because one or more lines are too long

View File

@@ -875,12 +875,12 @@ class Jqhtml_Layout extends Jqhtml_Component {
}
/**
* Get the content container where routes render
* Must contain an element with $id="content"
* Must contain an element with $sid="content"
*/
$content() {
const $content = this.$sid('content');
if (!$content.length) {
throw new Error(`Layout ${this.constructor.name} must have an element with $id="content"`);
throw new Error(`Layout ${this.constructor.name} must have an element with $sid="content"`);
}
return $content;
}

File diff suppressed because one or more lines are too long

View File

@@ -1,5 +1,5 @@
/**
* JQHTML Router v2.2.218
* JQHTML Router v2.2.220
* (c) 2025 JQHTML Team
* Released under the MIT License
*/
@@ -880,12 +880,12 @@ class Jqhtml_Layout extends Jqhtml_Component {
}
/**
* Get the content container where routes render
* Must contain an element with $id="content"
* Must contain an element with $sid="content"
*/
$content() {
const $content = this.$sid('content');
if (!$content.length) {
throw new Error(`Layout ${this.constructor.name} must have an element with $id="content"`);
throw new Error(`Layout ${this.constructor.name} must have an element with $sid="content"`);
}
return $content;
}

File diff suppressed because one or more lines are too long

View File

@@ -29,7 +29,7 @@ export declare class Jqhtml_Layout extends Jqhtml_Component {
post_dispatch(route_info: RouteInfo): Promise<void>;
/**
* Get the content container where routes render
* Must contain an element with $id="content"
* Must contain an element with $sid="content"
*/
$content(): JQuery;
/**

View File

@@ -1,6 +1,6 @@
{
"name": "@jqhtml/router",
"version": "2.2.218",
"version": "2.2.220",
"description": "Client-side routing for JQHTML applications",
"type": "module",
"main": "dist/index.js",

View File

@@ -1 +1 @@
2.2.218
2.2.220

File diff suppressed because one or more lines are too long

View File

@@ -2,7 +2,7 @@
"name": "@jqhtml/vscode-extension",
"displayName": "JQHTML",
"description": "Syntax highlighting and language support for JQHTML template files",
"version": "2.2.218",
"version": "2.2.220",
"publisher": "jqhtml",
"license": "MIT",
"publishConfig": {

View File

@@ -1,6 +1,6 @@
{
"name": "@jqhtml/webpack-loader",
"version": "2.2.218",
"version": "2.2.220",
"description": "Webpack loader for JQHTML templates",
"type": "module",
"main": "dist/index.js",
@@ -30,7 +30,7 @@
"template"
],
"dependencies": {
"@jqhtml/parser": "2.2.218",
"@jqhtml/parser": "2.2.220",
"@types/loader-utils": "^2.0.6",
"@types/node": "^20.0.0",
"@types/webpack": "^5.28.5",

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,7 +1,7 @@
{
"name": "baseline-browser-mapping",
"main": "./dist/index.cjs",
"version": "2.8.30",
"version": "2.8.31",
"description": "A library for obtaining browser versions with their maximum supported Baseline feature set and Widely Available status.",
"exports": {
".": {