Fix bin/publish: copy docs.dist from project root

Fix bin/publish: use correct .env path for rspade_system
Fix bin/publish script: prevent grep exit code 1 from terminating script

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
root
2025-10-21 02:08:33 +00:00
commit f6fac6c4bc
79758 changed files with 10547827 additions and 0 deletions

93
node_modules/@jqhtml/parser/dist/ast.d.ts generated vendored Executable file
View File

@@ -0,0 +1,93 @@
import { SourceLocation } from './lexer.js';
export declare enum NodeType {
PROGRAM = "Program",
COMPONENT_DEFINITION = "ComponentDefinition",
COMPONENT_INVOCATION = "ComponentInvocation",
HTML_TAG = "HtmlTag",
TEXT = "Text",
EXPRESSION = "Expression",
IF_STATEMENT = "IfStatement",
FOR_STATEMENT = "ForStatement",
CODE_BLOCK = "CodeBlock",
FRAGMENT = "Fragment",
SLOT = "Slot"
}
export interface BaseNode {
type: NodeType;
start: number;
end: number;
line: number;
column: number;
loc?: SourceLocation;
range?: [number, number];
}
export interface ProgramNode extends BaseNode {
type: NodeType.PROGRAM;
body: ASTNode[];
}
export interface ComponentDefinitionNode extends BaseNode {
type: NodeType.COMPONENT_DEFINITION;
name: string;
body: ASTNode[];
attributes: Record<string, any>;
extends?: string;
defineArgs?: Record<string, any>;
isSlotOnly?: boolean;
slotNames?: string[];
}
export interface TextNode extends BaseNode {
type: NodeType.TEXT;
content: string;
}
export interface ExpressionNode extends BaseNode {
type: NodeType.EXPRESSION;
code: string;
escaped: boolean;
}
export interface IfStatementNode extends BaseNode {
type: NodeType.IF_STATEMENT;
condition: string;
consequent: ASTNode[];
alternate: ASTNode[] | null;
}
export interface ForStatementNode extends BaseNode {
type: NodeType.FOR_STATEMENT;
iterator: string;
body: ASTNode[];
}
export interface CodeBlockNode extends BaseNode {
type: NodeType.CODE_BLOCK;
tokens?: Array<{
type: string;
value: string;
}>;
code?: string;
}
export interface FragmentNode extends BaseNode {
type: NodeType.FRAGMENT;
children: ASTNode[];
}
export interface SlotNode extends BaseNode {
type: NodeType.SLOT;
name: string;
attributes?: Record<string, any>;
children: ASTNode[];
selfClosing: boolean;
}
export interface ComponentInvocationNode extends BaseNode {
type: NodeType.COMPONENT_INVOCATION;
name: string;
attributes: Record<string, any>;
children: ASTNode[];
selfClosing: boolean;
}
export interface HtmlTagNode extends BaseNode {
type: NodeType.HTML_TAG;
name: string;
attributes: Record<string, any>;
children: ASTNode[];
selfClosing: boolean;
}
export type ASTNode = ProgramNode | ComponentDefinitionNode | ComponentInvocationNode | HtmlTagNode | TextNode | ExpressionNode | IfStatementNode | ForStatementNode | CodeBlockNode | FragmentNode | SlotNode;
export declare function createNode<T extends ASTNode>(type: T['type'], props: Omit<T, 'type' | keyof BaseNode>, start: number, end: number, line: number, column: number, loc?: SourceLocation): T;
//# sourceMappingURL=ast.d.ts.map

1
node_modules/@jqhtml/parser/dist/ast.d.ts.map generated vendored Executable file
View File

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

29
node_modules/@jqhtml/parser/dist/ast.js generated vendored Executable file
View File

@@ -0,0 +1,29 @@
// AST Node Types for JQHTML Templates
// Simple, clear node structures for the syntax tree
export var NodeType;
(function (NodeType) {
NodeType["PROGRAM"] = "Program";
NodeType["COMPONENT_DEFINITION"] = "ComponentDefinition";
NodeType["COMPONENT_INVOCATION"] = "ComponentInvocation";
NodeType["HTML_TAG"] = "HtmlTag";
NodeType["TEXT"] = "Text";
NodeType["EXPRESSION"] = "Expression";
NodeType["IF_STATEMENT"] = "IfStatement";
NodeType["FOR_STATEMENT"] = "ForStatement";
NodeType["CODE_BLOCK"] = "CodeBlock";
NodeType["FRAGMENT"] = "Fragment";
NodeType["SLOT"] = "Slot"; // v2 slot syntax
})(NodeType || (NodeType = {}));
// Helper to create nodes with common properties
export function createNode(type, props, start, end, line, column, loc) {
return {
type,
start,
end,
line,
column,
loc,
...props
};
}
//# sourceMappingURL=ast.js.map

1
node_modules/@jqhtml/parser/dist/ast.js.map generated vendored Executable file
View File

@@ -0,0 +1 @@
{"version":3,"file":"ast.js","sourceRoot":"","sources":["../src/ast.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,oDAAoD;AAIpD,MAAM,CAAN,IAAY,QAYX;AAZD,WAAY,QAAQ;IAClB,+BAAmB,CAAA;IACnB,wDAA4C,CAAA;IAC5C,wDAA4C,CAAA;IAC5C,gCAAoB,CAAA;IACpB,yBAAa,CAAA;IACb,qCAAyB,CAAA;IACzB,wCAA4B,CAAA;IAC5B,0CAA8B,CAAA;IAC9B,oCAAwB,CAAA;IACxB,iCAAqB,CAAA;IACrB,yBAAa,CAAA,CAAE,iBAAiB;AAClC,CAAC,EAZW,QAAQ,KAAR,QAAQ,QAYnB;AAiHD,gDAAgD;AAChD,MAAM,UAAU,UAAU,CACxB,IAAe,EACf,KAAuC,EACvC,KAAa,EACb,GAAW,EACX,IAAY,EACZ,MAAc,EACd,GAAoB;IAEpB,OAAO;QACL,IAAI;QACJ,KAAK;QACL,GAAG;QACH,IAAI;QACJ,MAAM;QACN,GAAG;QACH,GAAG,KAAK;KACJ,CAAC;AACT,CAAC"}

97
node_modules/@jqhtml/parser/dist/codegen.d.ts generated vendored Executable file
View File

@@ -0,0 +1,97 @@
import { ProgramNode } from './ast.js';
export interface GeneratedCode {
code: string;
source_map?: string;
source_map_data_uri?: string;
components: Map<string, ComponentCode>;
}
export interface ComponentCode {
name: string;
render_function: string;
dependencies: string[];
tagName: string;
defaultAttributes: Record<string, any>;
defineArgs?: Record<string, any>;
extends?: string;
}
export declare class CodeGenerator {
private indent_level;
private components;
private current_component;
private in_slot;
private tag_depth;
private outputLine;
private outputColumn;
private sourceMapGenerator?;
private sourceContent?;
private sourceFile?;
private outputBuffer;
private enablePositionTracking;
private positionLog;
private currentOutputLine;
private preserveLines;
private outputLines;
private sourceLines;
generate(ast: ProgramNode, sourceFile?: string, sourceContent?: string): GeneratedCode;
/**
* Generate code with source maps using 1:1 line mapping + SourceMapGenerator
*/
generateWithSourceMap(ast: ProgramNode, sourceFile: string, sourceContent: string): GeneratedCode;
private generate_component_with_mappings_TESTING;
private generate_component;
private generate_function_body;
/**
* Generate function body with true 1:1 line mapping
* Each line in the source produces exactly one line in the output
*/
private generate_function_body_1to1;
private generate_node;
private generate_text;
private generate_expression;
private generate_if;
private generate_for;
private generate_code_block;
private generate_tag_open;
private generate_html_tag;
private generate_component_invocation;
private parse_attributes;
private generate_attributes_object;
private is_self_closing_tag;
private compile_interpolated_value;
private escape_string;
private indent;
private extract_slots_from_children;
/**
* Emit text and track position for source maps
*/
private emit;
/**
* Emit a line of text (adds newline)
*/
private emitLine;
/**
* Reset position tracking
*/
private resetPositionTracking;
/**
* Get position tracking log for debugging
*/
getPositionLog(): Array<{
line: number;
column: number;
text: string;
node?: string;
}>;
/**
* Enable/disable position tracking
*/
setPositionTracking(enabled: boolean): void;
/**
* Serialize attribute object with proper handling of identifiers and expressions
* Quoted values become strings, identifiers/expressions become raw JavaScript
*/
private serializeAttributeObject;
private build_module_code;
}
export declare function generate(ast: ProgramNode, sourceFile?: string, sourceContent?: string): GeneratedCode;
//# sourceMappingURL=codegen.d.ts.map

1
node_modules/@jqhtml/parser/dist/codegen.d.ts.map generated vendored Executable file
View File

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

1230
node_modules/@jqhtml/parser/dist/codegen.js generated vendored Executable file

File diff suppressed because it is too large Load Diff

1
node_modules/@jqhtml/parser/dist/codegen.js.map generated vendored Executable file

File diff suppressed because one or more lines are too long

25
node_modules/@jqhtml/parser/dist/compiler.d.ts generated vendored Executable file
View File

@@ -0,0 +1,25 @@
/**
* Unified JQHTML Compiler Module
*
* Single source of truth for compiling JQHTML templates to JavaScript
* with proper sourcemap generation and version injection.
*/
export interface CompileOptions {
format: 'iife' | 'esm' | 'cjs' | 'umd';
sourcemap: boolean;
version?: string;
}
export interface CompiledOutput {
code: string;
componentName: string;
}
/**
* Compile a JQHTML template to JavaScript
*
* @param source - The JQHTML template source code
* @param filename - The source filename for sourcemap generation
* @param options - Compilation options
* @returns The compiled JavaScript code as a string
*/
export declare function compileTemplate(source: string, filename: string, options: CompileOptions): CompiledOutput;
//# sourceMappingURL=compiler.d.ts.map

1
node_modules/@jqhtml/parser/dist/compiler.d.ts.map generated vendored Executable file
View File

@@ -0,0 +1 @@
{"version":3,"file":"compiler.d.ts","sourceRoot":"","sources":["../src/compiler.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC;IACvC,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,cAAc,GACtB,cAAc,CAmDhB"}

273
node_modules/@jqhtml/parser/dist/compiler.js generated vendored Executable file
View File

@@ -0,0 +1,273 @@
/**
* Unified JQHTML Compiler Module
*
* Single source of truth for compiling JQHTML templates to JavaScript
* with proper sourcemap generation and version injection.
*/
import { Lexer } from './lexer.js';
import { Parser } from './parser.js';
import { CodeGenerator } from './codegen.js';
/**
* Compile a JQHTML template to JavaScript
*
* @param source - The JQHTML template source code
* @param filename - The source filename for sourcemap generation
* @param options - Compilation options
* @returns The compiled JavaScript code as a string
*/
export function compileTemplate(source, filename, options) {
// Validate: content() must be called with <%= %> not <% %>
if (source.includes('<% content()')) {
throw new Error(`Invalid content() usage in ${filename}:\n\n` +
`content() must be output using <%= %> tags, not <% %> tags.\n\n` +
`Wrong: <% content() %>\n` +
`Right: <%= content() %>\n\n` +
`This ensures the content is properly rendered as output.`);
}
// 1. Parse the template
const lexer = new Lexer(source);
const tokens = lexer.tokenize();
const parser = new Parser(tokens, source, filename);
const ast = parser.parse();
// 2. Generate code WITHOUT sourcemap (we'll create it after wrapping)
const generator = new CodeGenerator();
const result = generator.generate(ast, filename, source);
// 3. Get component info
const componentName = result.components.keys().next().value;
if (!componentName) {
throw new Error('No component found in template');
}
const component = result.components.get(componentName);
if (!component) {
throw new Error(`Component ${componentName} not found in results`);
}
// 4. Apply format wrapping and version injection
const version = options.version || getPackageVersion();
let output = formatOutput(component, componentName, options.format, version);
// 5. Generate sourcemap AFTER wrapping (if requested)
if (options.sourcemap) {
const sourcemap = generateSourcemapForWrappedCode(output, source, filename);
output = output + '\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,' + sourcemap;
}
return {
code: output,
componentName
};
}
/**
* Get package version from package.json
* We can't use dynamic import in TypeScript, so we'll inject at build time
*/
function getPackageVersion() {
// This will be replaced by the build process
// The CLI will pass the version directly
return '__PARSER_VERSION__';
}
/**
* Serialize defineArgs/defaultAttributes with proper handling of identifiers and expressions
* Quoted values become strings, identifiers/expressions become raw JavaScript
*/
function serializeAttributeObject(obj) {
if (!obj || Object.keys(obj).length === 0) {
return '{}';
}
const entries = [];
for (const [key, value] of Object.entries(obj)) {
// Check if value is a parsed attribute object with type info
if (value && typeof value === 'object' && (value.identifier || value.expression)) {
// Identifier or expression - output as raw JavaScript (no quotes)
entries.push(`"${key}": ${value.value}`);
}
else if (value && typeof value === 'object' && value.quoted) {
// Quoted string - output as string literal
entries.push(`"${key}": ${JSON.stringify(value.value)}`);
}
else {
// Simple value - output as-is via JSON.stringify
entries.push(`"${key}": ${JSON.stringify(value)}`);
}
}
return `{${entries.join(', ')}}`;
}
/**
* Format the generated code according to the specified module format
* Moved from CLI compiler's formatOutput function
*/
function formatOutput(componentInfo, componentName, format, version) {
const name = componentInfo.name;
// Build the component definition
let componentDef = `{
_jqhtml_version: '${version}',
name: '${componentInfo.name}',
tag: '${componentInfo.tagName}',
defaultAttributes: ${serializeAttributeObject(componentInfo.defaultAttributes)},`;
// Add defineArgs if present ($ attributes from Define tag)
if (componentInfo.defineArgs) {
componentDef += `\n defineArgs: ${serializeAttributeObject(componentInfo.defineArgs)},`;
}
// Add extends if present (template inheritance)
if (componentInfo.extends) {
componentDef += `\n extends: '${componentInfo.extends}',`;
}
componentDef += `\n render: ${componentInfo.render_function.trimEnd()},
dependencies: ${JSON.stringify(componentInfo.dependencies)}
}`;
let output;
switch (format) {
case 'iife':
// Self-executing function that auto-registers with window.jqhtml
output = `// Compiled from: ${componentName}.jqhtml
(function() {
'use strict';
const template_${name} = ${componentDef};
// Self-register with jqhtml runtime
// Must use window.jqhtml since we're in bundle scope
if (!window.jqhtml) {
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
}
// Auto-register following standard jqhtml pattern
window.jqhtml.register_template(template_${name});
})();`;
break;
case 'esm':
// ES Module export with auto-registration
output = `// ES Module: ${name}
import jqhtml from '@jqhtml/core';
const template_${name} = ${componentDef};
// Auto-register following standard jqhtml pattern
jqhtml.register_template(template_${name});
export { template_${name} };
export default template_${name};`;
break;
case 'cjs':
// CommonJS export with auto-registration
output = `// CommonJS Module: ${name}
'use strict';
const template_${name} = ${componentDef};
// Auto-register if jqhtml is available
if (typeof window !== 'undefined' && window.jqhtml) {
window.jqhtml.register_template(template_${name});
}
module.exports = template_${name};
module.exports.default = template_${name};
module.exports.template_${name} = template_${name};`;
break;
case 'umd':
// Universal Module Definition with auto-registration
output = `(function (root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD
define(['@jqhtml/core'], factory);
} else if (typeof module === 'object' && module.exports) {
// CommonJS
module.exports = factory();
} else {
// Browser global
root.template_${name} = factory();
}
}(typeof self !== 'undefined' ? self : this, function (jqhtml) {
'use strict';
const template_${name} = ${componentDef};
// Auto-register with jqhtml runtime
if (typeof window !== 'undefined' && window.jqhtml) {
window.jqhtml.register_template(template_${name});
} else if (jqhtml) {
jqhtml.register_template(template_${name});
}
return template_${name};
}));`;
break;
default:
throw new Error(`Unknown format: ${format}`);
}
return output;
}
/**
* Generate a sourcemap for already-wrapped code
* This generates sourcemaps AFTER the wrapper has been applied
*/
function generateSourcemapForWrappedCode(wrappedCode, sourceContent, filename) {
// Count lines in wrapped output and source
const outputLines = wrappedCode.split('\n').length;
const sourceLines = sourceContent.split('\n').length;
// Find where the render function (template content) starts
const renderLineOffset = findRenderFunctionLine(wrappedCode);
if (renderLineOffset === 0) {
// Couldn't find render function, generate a basic mapping
console.warn('Could not find render function in wrapped output');
const mappings = new Array(outputLines).fill('AAAA').join(';');
const sourcemap = {
version: 3,
sources: [filename],
sourcesContent: [sourceContent],
mappings: mappings,
names: []
};
return Buffer.from(JSON.stringify(sourcemap)).toString('base64');
}
// Build mappings:
// 1. Lines before render content → all map to source line 1
// 2. Template content lines → map 1:1 to source lines
// 3. Lines after template content → all map to last source line
const mappings = [];
// Wrapper lines before template content
for (let i = 0; i < renderLineOffset - 1; i++) {
mappings.push('AAAA'); // Map to source line 1, column 0
}
// Template content lines (1:1 mapping)
// First line of template maps to source line 1
mappings.push('AAAA'); // Source line 1
// Remaining source lines map sequentially
for (let i = 1; i < sourceLines; i++) {
mappings.push('AACA'); // Each subsequent source line
}
// Any remaining wrapper lines after template content
const remainingLines = outputLines - mappings.length;
for (let i = 0; i < remainingLines; i++) {
mappings.push('AAAA'); // Map to last source line
}
// Create the sourcemap object
const sourcemap = {
version: 3,
sources: [filename],
sourcesContent: [sourceContent],
mappings: mappings.join(';'),
names: []
};
// Verify we have the right count
const finalCount = mappings.length;
if (finalCount !== outputLines) {
console.error(`Warning: Sourcemap line mismatch. Output has ${outputLines} lines, sourcemap has ${finalCount} mapping segments`);
}
return Buffer.from(JSON.stringify(sourcemap)).toString('base64');
}
/**
* Find the line number where template content starts in the wrapped output
* Returns 1-based line number
*/
function findRenderFunctionLine(outputCode) {
const lines = outputCode.split('\n');
for (let i = 0; i < lines.length; i++) {
// Look for the render function definition
if (lines[i].includes('render: function render(')) {
// Template content starts on the line AFTER the function declaration
// The function declaration ends with "{ let _output = []; ..."
// The next line is either empty or starts with template content
return i + 2; // i+1 for 1-based, +1 for next line after declaration
}
}
return 0; // Not found
}
//# sourceMappingURL=compiler.js.map

1
node_modules/@jqhtml/parser/dist/compiler.js.map generated vendored Executable file

File diff suppressed because one or more lines are too long

27
node_modules/@jqhtml/parser/dist/errors.d.ts generated vendored Executable file
View File

@@ -0,0 +1,27 @@
export declare class JQHTMLParseError extends Error {
line: number;
column: number;
endLine?: number;
endColumn?: number;
source?: string;
filename?: string;
severity: 'error' | 'warning';
suggestion?: string;
constructor(message: string, line: number, column: number, source?: string, filename?: string);
private buildErrorMessage;
private getCodeSnippet;
}
export declare function unclosedError(type: string, name: string, line: number, column: number, source?: string, filename?: string): JQHTMLParseError;
export declare function mismatchedTagError(opening: string, closing: string, line: number, column: number, source?: string, filename?: string): JQHTMLParseError;
export declare function syntaxError(message: string, line: number, column: number, source?: string, filename?: string): JQHTMLParseError;
export declare function getSuggestion(error: string): string;
export declare class ErrorCollector {
private errors;
private maxErrors;
constructor(maxErrors?: number);
add(error: JQHTMLParseError): void;
hasErrors(): boolean;
getErrors(): JQHTMLParseError[];
throwIfErrors(): void;
}
//# sourceMappingURL=errors.d.ts.map

1
node_modules/@jqhtml/parser/dist/errors.d.ts.map generated vendored Executable file
View File

@@ -0,0 +1 @@
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAGA,qBAAa,gBAAiB,SAAQ,KAAK;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAW;IACxC,UAAU,CAAC,EAAE,MAAM,CAAC;gBAGzB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,MAAM,EACf,QAAQ,CAAC,EAAE,MAAM;IAgBnB,OAAO,CAAC,iBAAiB;IA0BzB,OAAO,CAAC,cAAc;CAiCvB;AAGD,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,MAAM,EACf,QAAQ,CAAC,EAAE,MAAM,GAChB,gBAAgB,CAQlB;AAED,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,MAAM,EACf,QAAQ,CAAC,EAAE,MAAM,GAChB,gBAAgB,CAQlB;AAED,wBAAgB,WAAW,CACzB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,MAAM,EACf,QAAQ,CAAC,EAAE,MAAM,GAChB,gBAAgB,CAQlB;AAGD,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAiCnD;AAGD,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAA0B;IACxC,OAAO,CAAC,SAAS,CAAc;gBAEnB,SAAS,GAAE,MAAW;IAIlC,GAAG,CAAC,KAAK,EAAE,gBAAgB,GAAG,IAAI;IAMlC,SAAS,IAAI,OAAO;IAIpB,SAAS,IAAI,gBAAgB,EAAE;IAI/B,aAAa,IAAI,IAAI;CAmBtB"}

153
node_modules/@jqhtml/parser/dist/errors.js generated vendored Executable file
View File

@@ -0,0 +1,153 @@
// JQHTML Parser Error Classes
// Provides helpful error messages with code context
export class JQHTMLParseError extends Error {
line;
column;
endLine;
endColumn;
source;
filename;
severity = 'error';
suggestion;
constructor(message, line, column, source, filename) {
super(message);
this.name = 'JQHTMLParseError';
this.line = line;
this.column = column;
this.source = source;
this.filename = filename;
// Auto-add suggestions
this.suggestion = getSuggestion(message);
// Build the full error message with context
this.message = this.buildErrorMessage(message);
}
buildErrorMessage(message) {
let result = message;
// Add suggestion if available
if (this.suggestion) {
result += this.suggestion;
}
// Add location info
if (this.filename) {
result += `\n at ${this.filename}:${this.line}:${this.column}`;
}
else {
result += `\n at line ${this.line}, column ${this.column}`;
}
// Add code snippet if source is available
if (this.source) {
const snippet = this.getCodeSnippet();
if (snippet) {
result += '\n\n' + snippet;
}
}
return result;
}
getCodeSnippet() {
if (!this.source)
return '';
const lines = this.source.split('\n');
const lineIndex = this.line - 1;
// Show 3 lines before and after for better context
const contextLines = 3;
const startLine = Math.max(0, lineIndex - contextLines);
const endLine = Math.min(lines.length - 1, lineIndex + contextLines);
let snippet = '';
for (let i = startLine; i <= endLine; i++) {
const lineNum = i + 1;
const isErrorLine = i === lineIndex;
const prefix = isErrorLine ? '>' : ' ';
// Line number with padding
const lineNumStr = String(lineNum).padStart(5, ' ');
snippet += `${prefix} ${lineNumStr} | ${lines[i]}\n`;
// Add pointer to error column with better highlighting
if (isErrorLine) {
const spaces = ' '.repeat(this.column + 8);
const carets = '^'.repeat(Math.min(lines[i].length - this.column + 1, 20));
snippet += `${spaces}${carets}\n`;
}
}
return snippet;
}
}
// Common error factories
export function unclosedError(type, name, line, column, source, filename) {
return new JQHTMLParseError(`Unclosed ${type}: ${name}`, line, column, source, filename);
}
export function mismatchedTagError(opening, closing, line, column, source, filename) {
return new JQHTMLParseError(`Mismatched tags: expected </${opening}>, found </${closing}>`, line, column, source, filename);
}
export function syntaxError(message, line, column, source, filename) {
return new JQHTMLParseError(`Syntax error: ${message}`, line, column, source, filename);
}
// Helpful suggestions for common mistakes
export function getSuggestion(error) {
if (error.includes('Unclosed if statement')) {
return '\nDid you forget <% endif; %>?';
}
if (error.includes('Unclosed for statement')) {
return '\nDid you forget <% endfor; %>?';
}
if (error.includes('Unclosed component definition')) {
return '\nDid you forget the closing </Define:ComponentName> tag?';
}
if (error.includes('Unclosed slot')) {
return '\nDid you mean to use a self-closing slot? Try <#name /> instead.';
}
if (error.includes('Unclosed tag') || error.includes('Unclosed component')) {
return '\n\nThis element was opened but never closed. Make sure every opening tag has a matching closing tag.\n' +
'Common causes:\n' +
' • Missing closing tag (e.g., forgot </div>)\n' +
' • Tag opened in if/for block but closed outside (split tag conditional - not allowed)\n' +
' • Mismatched nesting (e.g., <div><span></div></span>)\n\n' +
'If opened in <% if/for %>, it MUST close in the same block:\n' +
' ❌ <% if (x) { %> <div> <% } %> </div>\n' +
' ✅ <% if (x) { %> <div>...</div> <% } %>';
}
if (error.includes('Expected %>')) {
return '\nCheck if you have a %> inside a string literal. Escape it or use a different approach.';
}
if (error.includes('Mismatched tags')) {
return '\nCheck that your opening and closing tags match exactly (case-sensitive).';
}
if (error.includes('Mixed content not allowed')) {
return '\nWhen using slots, wrap all content in <#slotname> tags. Use <#default> for the main content.';
}
return '';
}
// Error collection for batch reporting
export class ErrorCollector {
errors = [];
maxErrors = 10;
constructor(maxErrors = 10) {
this.maxErrors = maxErrors;
}
add(error) {
if (this.errors.length < this.maxErrors) {
this.errors.push(error);
}
}
hasErrors() {
return this.errors.length > 0;
}
getErrors() {
return this.errors;
}
throwIfErrors() {
if (this.errors.length === 0)
return;
if (this.errors.length === 1) {
throw this.errors[0];
}
// Multiple errors - create a combined message
let message = `Found ${this.errors.length} errors:\n\n`;
this.errors.forEach((error, index) => {
message += `Error ${index + 1}: ${error.message}\n`;
if (index < this.errors.length - 1) {
message += '\n';
}
});
throw new Error(message);
}
}
//# sourceMappingURL=errors.js.map

1
node_modules/@jqhtml/parser/dist/errors.js.map generated vendored Executable file
View File

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

8
node_modules/@jqhtml/parser/dist/index.d.ts generated vendored Executable file
View File

@@ -0,0 +1,8 @@
export { Lexer, Token, TokenType } from './lexer.js';
export { Parser } from './parser.js';
export { CodeGenerator, generate } from './codegen.js';
export { compileTemplate, CompileOptions, CompiledOutput } from './compiler.js';
export { NodeType, ASTNode, ProgramNode, ComponentDefinitionNode, TextNode, ExpressionNode, IfStatementNode, ForStatementNode, CodeBlockNode, FragmentNode } from './ast.js';
export { JQHTMLParseError, ErrorCollector } from './errors.js';
export declare function parse(source: string, filename?: string): import("./ast.js").ProgramNode;
//# sourceMappingURL=index.d.ts.map

1
node_modules/@jqhtml/parser/dist/index.d.ts.map generated vendored Executable file
View File

@@ -0,0 +1 @@
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACrD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAChF,OAAO,EACL,QAAQ,EACR,OAAO,EACP,WAAW,EACX,uBAAuB,EACvB,QAAQ,EACR,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,aAAa,EACb,YAAY,EACb,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAG/D,wBAAgB,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,kCAoBtD"}

31
node_modules/@jqhtml/parser/dist/index.js generated vendored Executable file
View File

@@ -0,0 +1,31 @@
// JQHTML Parser - Main entry point
import { Lexer } from './lexer.js';
import { Parser } from './parser.js';
export { Lexer, TokenType } from './lexer.js';
export { Parser } from './parser.js';
export { CodeGenerator, generate } from './codegen.js';
export { compileTemplate } from './compiler.js';
export { NodeType } from './ast.js';
export { JQHTMLParseError, ErrorCollector } from './errors.js';
// Convenience function for parsing with error context
export function parse(source, filename) {
try {
const lexer = new Lexer(source);
const tokens = lexer.tokenize();
const parser = new Parser(tokens, source, filename);
return parser.parse();
}
catch (error) {
// If it's already a JQHTMLParseError, just re-throw it
if (error.name === 'JQHTMLParseError') {
throw error;
}
// Otherwise wrap it with context
const message = error.message || String(error);
const enhancedMessage = filename
? `Error parsing ${filename}: ${message}`
: `Error parsing JQHTML: ${message}`;
throw new Error(enhancedMessage);
}
}
//# sourceMappingURL=index.js.map

1
node_modules/@jqhtml/parser/dist/index.js.map generated vendored Executable file
View File

@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,mCAAmC;AAEnC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,OAAO,EAAE,KAAK,EAAS,SAAS,EAAE,MAAM,YAAY,CAAC;AACrD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACvD,OAAO,EAAE,eAAe,EAAkC,MAAM,eAAe,CAAC;AAChF,OAAO,EACL,QAAQ,EAUT,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE/D,sDAAsD;AACtD,MAAM,UAAU,KAAK,CAAC,MAAc,EAAE,QAAiB;IACrD,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC;QAChC,MAAM,MAAM,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC;QAChC,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;QACpD,OAAO,MAAM,CAAC,KAAK,EAAE,CAAC;IACxB,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,uDAAuD;QACvD,IAAI,KAAK,CAAC,IAAI,KAAK,kBAAkB,EAAE,CAAC;YACtC,MAAM,KAAK,CAAC;QACd,CAAC;QAED,iCAAiC;QACjC,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC;QAC/C,MAAM,eAAe,GAAG,QAAQ;YAC9B,CAAC,CAAC,iBAAiB,QAAQ,KAAK,OAAO,EAAE;YACzC,CAAC,CAAC,yBAAyB,OAAO,EAAE,CAAC;QAEvC,MAAM,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC;IACnC,CAAC;AACH,CAAC"}

3
node_modules/@jqhtml/parser/dist/integration.d.ts generated vendored Executable file
View File

@@ -0,0 +1,3 @@
export declare function with_template(ComponentClass: any, template_name: string): any;
export declare function register_compiled_templates(template_map: Map<string, any>): void;
//# sourceMappingURL=integration.d.ts.map

1
node_modules/@jqhtml/parser/dist/integration.d.ts.map generated vendored Executable file
View File

@@ -0,0 +1 @@
{"version":3,"file":"integration.d.ts","sourceRoot":"","sources":["../src/integration.ts"],"names":[],"mappings":"AAkBA,wBAAgB,aAAa,CAAC,cAAc,EAAE,GAAG,EAAE,aAAa,EAAE,MAAM,OA8BvE;AAGD,wBAAgB,2BAA2B,CAAC,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,QASzE"}

47
node_modules/@jqhtml/parser/dist/integration.js generated vendored Executable file
View File

@@ -0,0 +1,47 @@
// JQHTML v2 Template Integration
// Connects compiled templates to Component class
/// <reference path="./types.d.ts" />
import { process_instructions, html, register_template } from './runtime.js';
// Mixin to add template support to any component
export function with_template(ComponentClass, template_name) {
const original_on_render = ComponentClass.prototype.on_render;
ComponentClass.prototype.on_render = async function () {
// Get compiled template from registry
const global_obj = typeof window !== 'undefined' ? window : global;
const template_map = global_obj.jqhtml_components;
if (!template_map || !template_map.has(template_name)) {
throw new Error(`Template not found: ${template_name}`);
}
const template_info = template_map.get(template_name);
const render_fn = template_info.render;
// Call render function with component context
const [instructions] = render_fn.call(this, this.constructor, this.data, this.args, {});
// Process instructions into DOM
const rendered = process_instructions(instructions, this);
// Clear and append to component element
this.$.empty().append(rendered);
// Call original on_render if it exists
if (original_on_render) {
await original_on_render.call(this);
}
};
return ComponentClass;
}
// Register templates from compiled module
export function register_compiled_templates(template_map) {
// Store on global object for now (MVP approach)
const global_obj = typeof window !== 'undefined' ? window : global;
global_obj.jqhtml_components = template_map;
// Also register each template
for (const [name, info] of template_map) {
register_template(name, info.render);
}
}
// Make html function available globally for templates
if (typeof window !== 'undefined') {
window.html = html;
}
else if (typeof global !== 'undefined') {
global.html = html;
}
//# sourceMappingURL=integration.js.map

1
node_modules/@jqhtml/parser/dist/integration.js.map generated vendored Executable file
View File

@@ -0,0 +1 @@
{"version":3,"file":"integration.js","sourceRoot":"","sources":["../src/integration.ts"],"names":[],"mappings":"AAAA,iCAAiC;AACjC,iDAAiD;AAEjD,qCAAqC;AAErC,OAAO,EAAE,oBAAoB,EAAE,IAAI,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAY7E,iDAAiD;AACjD,MAAM,UAAU,aAAa,CAAC,cAAmB,EAAE,aAAqB;IACtE,MAAM,kBAAkB,GAAG,cAAc,CAAC,SAAS,CAAC,SAAS,CAAC;IAE9D,cAAc,CAAC,SAAS,CAAC,SAAS,GAAG,KAAK;QACxC,sCAAsC;QACtC,MAAM,UAAU,GAAG,OAAO,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;QACnE,MAAM,YAAY,GAAI,UAAkB,CAAC,iBAAiB,CAAC;QAC3D,IAAI,CAAC,YAAY,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE,CAAC;YACtD,MAAM,IAAI,KAAK,CAAC,uBAAuB,aAAa,EAAE,CAAC,CAAC;QAC1D,CAAC;QAED,MAAM,aAAa,GAAG,YAAY,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;QACtD,MAAM,SAAS,GAAG,aAAa,CAAC,MAAM,CAAC;QAEvC,8CAA8C;QAC9C,MAAM,CAAC,YAAY,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAExF,gCAAgC;QAChC,MAAM,QAAQ,GAAG,oBAAoB,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;QAE1D,wCAAwC;QACxC,IAAI,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAEhC,uCAAuC;QACvC,IAAI,kBAAkB,EAAE,CAAC;YACvB,MAAM,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACtC,CAAC;IACH,CAAC,CAAC;IAEF,OAAO,cAAc,CAAC;AACxB,CAAC;AAED,0CAA0C;AAC1C,MAAM,UAAU,2BAA2B,CAAC,YAA8B;IACxE,gDAAgD;IAChD,MAAM,UAAU,GAAG,OAAO,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;IAClE,UAAkB,CAAC,iBAAiB,GAAG,YAAY,CAAC;IAErD,8BAA8B;IAC9B,KAAK,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,YAAY,EAAE,CAAC;QACxC,iBAAiB,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IACvC,CAAC;AACH,CAAC;AAED,sDAAsD;AACtD,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE,CAAC;IAClC,MAAM,CAAC,IAAI,GAAG,IAAI,CAAC;AACrB,CAAC;KAAM,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE,CAAC;IACxC,MAAc,CAAC,IAAI,GAAG,IAAI,CAAC;AAC9B,CAAC"}

130
node_modules/@jqhtml/parser/dist/lexer.d.ts generated vendored Executable file
View File

@@ -0,0 +1,130 @@
export declare enum TokenType {
TEXT = "TEXT",
EXPRESSION_START = "EXPRESSION_START",// <%=
EXPRESSION_UNESCAPED = "EXPRESSION_UNESCAPED",// <%!=
CODE_START = "CODE_START",// <%
TAG_END = "TAG_END",// %>
IF = "IF",
ELSE = "ELSE",
ELSEIF = "ELSEIF",
ENDIF = "ENDIF",
FOR = "FOR",
ENDFOR = "ENDFOR",
COMMENT = "COMMENT",// <%-- comment --%>
DEFINE_START = "DEFINE_START",// <Define:
DEFINE_END = "DEFINE_END",// </Define:
COMPONENT_NAME = "COMPONENT_NAME",
SLOT_START = "SLOT_START",// <#
SLOT_END = "SLOT_END",// </#
SLOT_NAME = "SLOT_NAME",
TAG_OPEN = "TAG_OPEN",// <tagname or <ComponentName
TAG_CLOSE = "TAG_CLOSE",// </tagname or </ComponentName
TAG_NAME = "TAG_NAME",// The tag/component name
SELF_CLOSING = "SELF_CLOSING",// />
ATTR_NAME = "ATTR_NAME",// $property or regular
ATTR_VALUE = "ATTR_VALUE",
COLON = "COLON",
SEMICOLON = "SEMICOLON",
GT = "GT",// >
LT = "LT",// <
SLASH = "SLASH",// /
EQUALS = "EQUALS",// =
QUOTE = "QUOTE",// " or '
EOF = "EOF",
NEWLINE = "NEWLINE",
WHITESPACE = "WHITESPACE",
JAVASCRIPT = "JAVASCRIPT"
}
export interface SourceLocation {
start: {
line: number;
column: number;
offset: number;
};
end: {
line: number;
column: number;
offset: number;
};
}
export interface Token {
type: TokenType;
value: string;
line: number;
column: number;
start: number;
end: number;
loc?: SourceLocation;
}
export declare class Lexer {
private input;
private position;
private line;
private column;
private tokens;
private savedPosition;
constructor(input: string);
/**
* Save current position for later token creation
*/
private savePosition;
/**
* Get saved position or current position
*/
private getSavedPosition;
/**
* Replace <%-- comment --%> with equivalent number of newlines
* This ensures line mapping stays accurate while removing comment content
*/
private preprocessComments;
/**
* Replace HTML comments (<!-- -->) that appear OUTSIDE of <Define> tags
* This strips documentation comments before component definitions
* HTML comments INSIDE <Define> tags are preserved in the output
*/
private preprocessHTMLComments;
/**
* Preprocess code blocks and expressions
* - Insert comment markers for empty lines in code blocks
* - Collapse multi-line expressions to single line with trailing newlines
* This ensures 1:1 line mapping in generated code
*/
private preprocessCodeBlocks;
/**
* Find the closing %> tag, properly handling strings and comments
*/
private findClosingTag;
tokenize(): Token[];
private scan_next;
private scan_text;
private scan_code_block;
private scan_comment;
private scan_html_comment;
private scan_expression;
private scan_javascript;
private scan_component_name;
private scan_slot_name;
private match_sequence;
private match_keyword;
private peek_sequence;
private peek_sequence_at;
private skip_whitespace;
private current_char;
private peek_ahead;
private advance;
private add_token;
private is_tag_name_char;
private is_tag_name_continue_char;
private scan_opening_tag;
private scan_closing_tag;
private scan_attributes;
private is_attribute_start_char;
private peek_for_colon;
private scan_attribute;
private scan_attribute_value;
private validate_unquoted_value;
private get_current_attribute_context;
private value_contains_interpolation;
private scan_interpolated_attribute_value;
}
//# sourceMappingURL=lexer.d.ts.map

1
node_modules/@jqhtml/parser/dist/lexer.d.ts.map generated vendored Executable file
View File

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

1384
node_modules/@jqhtml/parser/dist/lexer.js generated vendored Executable file

File diff suppressed because it is too large Load Diff

1
node_modules/@jqhtml/parser/dist/lexer.js.map generated vendored Executable file

File diff suppressed because one or more lines are too long

53
node_modules/@jqhtml/parser/dist/parser.d.ts generated vendored Executable file
View File

@@ -0,0 +1,53 @@
import { Token } from './lexer.js';
import { ProgramNode } from './ast.js';
export declare class Parser {
private tokens;
private current;
private source?;
private filename?;
private static readonly VOID_ELEMENTS;
constructor(tokens: Token[], source?: string, filename?: string);
parse(): ProgramNode;
private parse_top_level;
private parse_component_definition;
private parse_content;
private parse_expression;
private parse_code_block;
private parse_if_statement;
private parse_for_statement;
private static readonly JAVASCRIPT_RESERVED_WORDS;
private parse_slot;
private parse_tag;
private parse_attributes;
private parse_attribute_value;
private check_closing_tag;
private match;
private check;
private check_ahead;
private check_sequence;
private advance;
private is_at_end;
private peek;
private peek_ahead;
private previous;
private current_token;
private previous_token;
/**
* Create a SourceLocation from start and end tokens
* Propagates loc field if available, falls back to old fields for compatibility
*/
private create_location;
private consume;
private validate_component_children;
/**
* Compile method for simplified API
* Parses the template and returns component metadata and render function
*/
compile(): {
name: string;
tagName: string;
defaultAttributes: Record<string, any>;
renderFunction: string;
};
}
//# sourceMappingURL=parser.d.ts.map

1
node_modules/@jqhtml/parser/dist/parser.d.ts.map generated vendored Executable file
View File

@@ -0,0 +1 @@
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,EAA6B,MAAM,YAAY,CAAC;AAC9D,OAAO,EAGL,WAAW,EASZ,MAAM,UAAU,CAAC;AAUlB,qBAAa,MAAM;IACjB,OAAO,CAAC,MAAM,CAAU;IACxB,OAAO,CAAC,OAAO,CAAa;IAC5B,OAAO,CAAC,MAAM,CAAC,CAAS;IACxB,OAAO,CAAC,QAAQ,CAAC,CAAS;IAI1B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,aAAa,CAGlC;gBAES,MAAM,EAAE,KAAK,EAAE,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM;IAO/D,KAAK,IAAI,WAAW;IA0EpB,OAAO,CAAC,eAAe;IAgBvB,OAAO,CAAC,0BAA0B;IAqNlC,OAAO,CAAC,aAAa;IA6DrB,OAAO,CAAC,gBAAgB;IAoBxB,OAAO,CAAC,gBAAgB;IAmCxB,OAAO,CAAC,kBAAkB;IA+G1B,OAAO,CAAC,mBAAmB;IAsD3B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,yBAAyB,CAW9C;IAGH,OAAO,CAAC,UAAU;IAmGlB,OAAO,CAAC,SAAS;IAsMjB,OAAO,CAAC,gBAAgB;IAyDxB,OAAO,CAAC,qBAAqB;IA+D7B,OAAO,CAAC,iBAAiB;IAgBzB,OAAO,CAAC,KAAK;IAUb,OAAO,CAAC,KAAK;IAKb,OAAO,CAAC,WAAW;IAOnB,OAAO,CAAC,cAAc;IAYtB,OAAO,CAAC,OAAO;IAKf,OAAO,CAAC,SAAS;IAIjB,OAAO,CAAC,IAAI;IAIZ,OAAO,CAAC,UAAU;IAQlB,OAAO,CAAC,QAAQ;IAIhB,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,cAAc;IAItB;;;OAGG;IACH,OAAO,CAAC,eAAe;IAYvB,OAAO,CAAC,OAAO;IA4Cf,OAAO,CAAC,2BAA2B;IA+BnC;;;OAGG;IACH,OAAO,IAAI;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAAC,cAAc,EAAE,MAAM,CAAA;KAAE;CAkC7G"}

838
node_modules/@jqhtml/parser/dist/parser.js generated vendored Executable file
View File

@@ -0,0 +1,838 @@
// JQHTML Parser - Builds AST from tokens
// Simple recursive descent parser, no complex libraries
import { TokenType } from './lexer.js';
import { NodeType, createNode } from './ast.js';
import { unclosedError, mismatchedTagError, syntaxError, getSuggestion } from './errors.js';
import { CodeGenerator } from './codegen.js';
export class Parser {
tokens;
current = 0;
source;
filename;
// HTML5 void elements that cannot have closing tags
// These are automatically treated as self-closing
static VOID_ELEMENTS = new Set([
'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input',
'link', 'meta', 'source', 'track', 'wbr'
]);
constructor(tokens, source, filename) {
this.tokens = tokens;
this.source = source;
this.filename = filename;
}
// Main entry point - parse tokens into AST
parse() {
const body = [];
const start = this.current_token();
// Skip leading whitespace and newlines
while (!this.is_at_end() && (this.match(TokenType.NEWLINE) ||
(this.match(TokenType.TEXT) && this.previous_token().value.trim() === ''))) {
// Skip whitespace
}
// Check if file is empty (only whitespace)
if (this.is_at_end()) {
// Empty file is allowed
return createNode(NodeType.PROGRAM, { body: [] }, start.start, start.end, start.line, start.column, this.create_location(start, start));
}
// Must have exactly one Define tag at top level
if (!this.check(TokenType.DEFINE_START)) {
const token = this.current_token();
throw syntaxError('JQHTML files must have exactly one top-level <Define:ComponentName> tag', token.line, token.column, this.source, this.filename);
}
// Parse the single component definition
const component = this.parse_component_definition();
if (component) {
body.push(component);
}
// Skip trailing whitespace and newlines
while (!this.is_at_end() && (this.match(TokenType.NEWLINE) || this.match(TokenType.TEXT) && this.previous_token().value.trim() === '')) {
// Skip whitespace
}
// Ensure no other content after the Define tag
if (!this.is_at_end()) {
const token = this.current_token();
throw syntaxError('JQHTML files must have exactly one top-level <Define:ComponentName> tag. Found additional content after the component definition.', token.line, token.column, this.source, this.filename);
}
const end = this.previous_token();
return createNode(NodeType.PROGRAM, { body }, start.start, end.end, start.line, start.column, this.create_location(start, end));
}
// Parse top-level constructs
parse_top_level() {
// Skip whitespace-only text nodes at top level
if (this.match(TokenType.NEWLINE)) {
return null;
}
// Component definition
if (this.check(TokenType.DEFINE_START)) {
return this.parse_component_definition();
}
// Regular content
return this.parse_content();
}
// Parse <Define:ComponentName>...</Define:ComponentName>
parse_component_definition() {
const start_token = this.consume(TokenType.DEFINE_START, 'Expected <Define:');
const name_token = this.consume(TokenType.COMPONENT_NAME, 'Expected component name');
// Validate component name starts with capital letter
if (!/^[A-Z]/.test(name_token.value)) {
throw syntaxError(`Component name '${name_token.value}' must start with a capital letter. Convention is First_Letter_With_Underscores.`, name_token.line, name_token.column, this.source, this.filename);
}
// Parse attributes (like tag="span", class="card", extends="Parent", $prop=value)
const attributes = {};
const defineArgs = {}; // $ attributes (raw JS, not data- attributes)
let extendsValue;
// Skip any leading newlines before attributes
while (this.match(TokenType.NEWLINE)) {
// Skip
}
while (!this.check(TokenType.GT) && !this.is_at_end()) {
const attr_name = this.consume(TokenType.ATTR_NAME, 'Expected attribute name');
// Validate that $id is not used in Define tags
if (attr_name.value === '$id') {
throw syntaxError('$id is not allowed in <Define:> tags. Component definitions cannot have scoped IDs.', attr_name.line, attr_name.column, this.source, this.filename);
}
this.consume(TokenType.EQUALS, 'Expected =');
const attr_value = this.parse_attribute_value();
// Check if attribute value contains template expressions (dynamic content)
// Define tag attributes must be static - they're part of the template definition, not runtime values
const hasInterpolation = attr_value &&
typeof attr_value === 'object' &&
(attr_value.interpolated === true ||
(attr_value.parts && attr_value.parts.some((p) => p.type === 'expression')));
if (hasInterpolation) {
// Special error message for class attribute - most common case
if (attr_name.value === 'class') {
const error = syntaxError(`Template expressions cannot be used in <Define:> tag attributes. The <Define> tag is a static template definition, not a live component instance.`, attr_name.line, attr_name.column, this.source, this.filename);
error.message += '\n\n' +
' For dynamic classes, set the class attribute on the component invocation instead:\n' +
' ❌ <Define:MyComponent class="<%= this.args.col_class || \'default\' %>">\n' +
' ✅ <Define:MyComponent class="static-class">\n' +
' ...\n' +
' </Define:MyComponent>\n\n' +
' Then when using the component:\n' +
' <MyComponent class="col-md-8 col-xl-4" />\n\n' +
' Or set attributes dynamically in on_create() or on_ready():\n' +
' on_ready() {\n' +
' const classes = this.args.col_class || \'col-12 col-md-6\';\n' +
' this.$.addClass(classes);\n' +
' }';
throw error;
}
else {
// General error for other attributes
const error = syntaxError(`Template expressions cannot be used in <Define:> tag attributes. The <Define> tag is a static template definition, not a live component instance.`, attr_name.line, attr_name.column, this.source, this.filename);
error.message += '\n\n' +
` For dynamic "${attr_name.value}" attribute values, set them dynamically in lifecycle methods:\n` +
' ❌ <Define:MyComponent ' + attr_name.value + '="<%= expression %>">\n' +
' ✅ <Define:MyComponent>\n' +
' ...\n' +
' </Define:MyComponent>\n\n' +
' Then in your component class:\n' +
' on_create() {\n' +
` this.$.attr('${attr_name.value}', this.args.some_value);\n` +
' }\n\n' +
' Or use on_ready() for attributes that need DOM to be fully initialized.';
throw error;
}
}
// Handle special attributes on Define tags
if (attr_name.value === 'extends') {
// extends="ParentComponent" - explicit template inheritance
if (typeof attr_value === 'object' && attr_value.quoted) {
extendsValue = attr_value.value;
}
else if (typeof attr_value === 'string') {
extendsValue = attr_value;
}
else {
throw syntaxError(`extends attribute must be a quoted string with the parent component name`, attr_name.line, attr_name.column, this.source, this.filename);
}
}
else if (attr_name.value.startsWith('$')) {
// $ attributes on Define tags are raw JS assignments (like component invocations)
// Store them separately - they don't become data- attributes
const propName = attr_name.value.substring(1); // Remove $
defineArgs[propName] = attr_value;
}
else {
// Regular attributes (tag="span", class="card", etc.)
attributes[attr_name.value] = attr_value;
}
// Skip newlines between attributes
while (this.match(TokenType.NEWLINE)) {
// Skip
}
}
this.consume(TokenType.GT, 'Expected >');
const body = [];
// Parse until we find the closing tag
while (!this.check(TokenType.DEFINE_END)) {
if (this.is_at_end()) {
const error = unclosedError('component definition', name_token.value, name_token.line, name_token.column, this.source, this.filename);
error.message += getSuggestion(error.message);
throw error;
}
const node = this.parse_content();
if (node) {
body.push(node);
}
}
// Consume closing tag
this.consume(TokenType.DEFINE_END, 'Expected </Define:');
const closing_name = this.consume(TokenType.COMPONENT_NAME, 'Expected component name');
if (closing_name.value !== name_token.value) {
throw mismatchedTagError(`Define:${name_token.value}`, `Define:${closing_name.value}`, closing_name.line, closing_name.column, this.source, this.filename);
}
const end_token = this.consume(TokenType.GT, 'Expected >');
// Detect slot-only templates for inheritance
let isSlotOnly = false;
let slotNames = [];
// Check if body contains only slot nodes (ignoring whitespace-only text)
const nonWhitespaceNodes = body.filter(node => {
if (node.type === NodeType.TEXT) {
return node.content.trim() !== '';
}
return true;
});
if (nonWhitespaceNodes.length > 0) {
// Check if ALL non-whitespace nodes are slots
const allSlots = nonWhitespaceNodes.every(node => node.type === NodeType.SLOT);
if (allSlots) {
isSlotOnly = true;
slotNames = nonWhitespaceNodes.map(node => node.name);
}
}
return createNode(NodeType.COMPONENT_DEFINITION, {
name: name_token.value,
body,
attributes,
extends: extendsValue,
defineArgs: Object.keys(defineArgs).length > 0 ? defineArgs : undefined,
isSlotOnly,
slotNames
}, start_token.start, end_token.end, start_token.line, start_token.column, this.create_location(start_token, end_token));
}
// Parse content (text, expressions, control flow)
parse_content() {
// Comments are now preprocessed into whitespace by the lexer
// Plain text
if (this.match(TokenType.TEXT)) {
const token = this.previous();
return createNode(NodeType.TEXT, { content: token.value }, token.start, token.end, token.line, token.column, this.create_location(token, token));
}
// Expression <%= ... %> or <%!= ... %>
if (this.match(TokenType.EXPRESSION_START) ||
this.match(TokenType.EXPRESSION_UNESCAPED)) {
return this.parse_expression();
}
// Code block <% ... %>
if (this.match(TokenType.CODE_START)) {
return this.parse_code_block();
}
// Slot <#name>...</#name>
if (this.match(TokenType.SLOT_START)) {
return this.parse_slot();
}
// HTML tags and component invocations
if (this.match(TokenType.TAG_OPEN)) {
return this.parse_tag();
}
// Skip newlines in content
if (this.match(TokenType.NEWLINE)) {
const token = this.previous();
return createNode(NodeType.TEXT, { content: token.value }, token.start, token.end, token.line, token.column, this.create_location(token, token));
}
// Advance if we don't recognize the token
if (!this.is_at_end()) {
this.advance();
}
return null;
}
// Parse <%= expression %> or <%!= expression %>
parse_expression() {
const start_token = this.previous(); // EXPRESSION_START or EXPRESSION_UNESCAPED
const code_token = this.consume(TokenType.JAVASCRIPT, 'Expected JavaScript code');
const end_token = this.consume(TokenType.TAG_END, 'Expected %>');
return createNode(NodeType.EXPRESSION, {
code: code_token.value,
escaped: start_token.type === TokenType.EXPRESSION_START
}, start_token.start, end_token.end, start_token.line, start_token.column, this.create_location(start_token, end_token));
}
// Parse <% code %> - collect tokens with their types for proper transformation
parse_code_block() {
const start_token = this.previous(); // CODE_START
// Collect tokens with their types
const tokens = [];
while (!this.check(TokenType.TAG_END)) {
if (this.is_at_end()) {
throw syntaxError('Unterminated code block - expected %>', start_token.line, start_token.column, this.source, this.filename);
}
const token = this.advance();
tokens.push({ type: token.type, value: token.value });
}
const end_token = this.consume(TokenType.TAG_END, 'Expected %>');
return createNode(NodeType.CODE_BLOCK, { tokens }, // Pass tokens array instead of concatenated code
start_token.start, end_token.end, start_token.line, start_token.column, this.create_location(start_token, end_token));
}
// Parse if statement with colon style only
parse_if_statement(start_token) {
console.log('[Parser] Parsing if statement at line', start_token.line);
this.consume(TokenType.IF, 'Expected if');
const condition_token = this.consume(TokenType.JAVASCRIPT, 'Expected condition');
console.log('[Parser] If condition:', condition_token.value);
this.consume(TokenType.TAG_END, 'Expected %>');
const consequent = [];
let alternate = null;
// Parse consequent branch
while (!this.check_sequence(TokenType.CODE_START, TokenType.ELSE) &&
!this.check_sequence(TokenType.CODE_START, TokenType.ENDIF)) {
if (this.is_at_end()) {
const error = unclosedError('if statement', `if (${condition_token.value})`, start_token.line, start_token.column, this.source, this.filename);
error.message += getSuggestion(error.message);
throw error;
}
const node = this.parse_content();
if (node) {
consequent.push(node);
}
}
// Check for else branch
if (this.check_sequence(TokenType.CODE_START, TokenType.ELSE)) {
console.log('[Parser] Found else branch');
this.advance(); // CODE_START
this.advance(); // ELSE
// Check if this is an "else if"
if (this.check(TokenType.IF)) {
console.log('[Parser] This is an else if statement');
// This is an else if - put back the ELSE token and parse as new if statement
this.current--; // Put back ELSE
this.current--; // Put back CODE_START
// Parse the else if as a new if statement
alternate = [];
const elseIfNode = this.parse_content();
if (elseIfNode) {
alternate.push(elseIfNode);
}
}
else {
// Regular else branch
// Skip optional trailing code
if (this.check(TokenType.JAVASCRIPT)) {
this.advance();
}
this.consume(TokenType.TAG_END, 'Expected %>');
alternate = [];
// Parse else branch
while (!this.check_sequence(TokenType.CODE_START, TokenType.ENDIF)) {
if (this.is_at_end()) {
const error = unclosedError('if statement (in else branch)', `if (${condition_token.value})`, start_token.line, start_token.column, this.source, this.filename);
error.message += getSuggestion(error.message);
throw error;
}
const node = this.parse_content();
if (node) {
alternate.push(node);
}
}
}
}
// Consume endif
this.consume(TokenType.CODE_START, 'Expected <%');
this.consume(TokenType.ENDIF, 'Expected endif');
// Skip optional semicolon
if (this.check(TokenType.JAVASCRIPT)) {
this.advance();
}
const end_token = this.consume(TokenType.TAG_END, 'Expected %>');
return createNode(NodeType.IF_STATEMENT, {
condition: condition_token.value,
consequent,
alternate
}, start_token.start, end_token.end, start_token.line, start_token.column, this.create_location(start_token, end_token));
}
// Parse for loop
parse_for_statement(start_token) {
this.consume(TokenType.FOR, 'Expected for');
const iterator_token = this.consume(TokenType.JAVASCRIPT, 'Expected iterator expression');
this.consume(TokenType.TAG_END, 'Expected %>');
const body = [];
// Parse loop body
while (!this.check_sequence(TokenType.CODE_START, TokenType.ENDFOR)) {
if (this.is_at_end()) {
const error = unclosedError('for statement', `for ${iterator_token.value}`, start_token.line, start_token.column, this.source, this.filename);
error.message += getSuggestion(error.message);
throw error;
}
const node = this.parse_content();
if (node) {
body.push(node);
}
}
// Consume endfor
this.consume(TokenType.CODE_START, 'Expected <%');
this.consume(TokenType.ENDFOR, 'Expected endfor');
// Skip optional semicolon
if (this.check(TokenType.JAVASCRIPT)) {
this.advance();
}
const end_token = this.consume(TokenType.TAG_END, 'Expected %>');
return createNode(NodeType.FOR_STATEMENT, {
iterator: iterator_token.value,
body
}, start_token.start, end_token.end, start_token.line, start_token.column, this.create_location(start_token, end_token));
}
// JavaScript reserved words that cannot be used as slot names
static JAVASCRIPT_RESERVED_WORDS = new Set([
// Keywords
'break', 'case', 'catch', 'class', 'const', 'continue', 'debugger', 'default',
'delete', 'do', 'else', 'enum', 'export', 'extends', 'false', 'finally',
'for', 'function', 'if', 'import', 'in', 'instanceof', 'let', 'new', 'null',
'return', 'super', 'switch', 'this', 'throw', 'true', 'try', 'typeof',
'var', 'void', 'while', 'with', 'yield',
// Future reserved words
'implements', 'interface', 'package', 'private', 'protected', 'public', 'static', 'await',
// Other problematic words
'arguments', 'eval'
]);
// Parse slot <#name>content</#name> or <#name />
parse_slot() {
const start_token = this.previous(); // SLOT_START
const name_token = this.consume(TokenType.SLOT_NAME, 'Expected slot name');
// Validate slot name against JavaScript reserved words
if (Parser.JAVASCRIPT_RESERVED_WORDS.has(name_token.value.toLowerCase())) {
throw syntaxError(`Slot name "${name_token.value}" is a JavaScript reserved word and cannot be used. Please choose a different name.`, name_token.line, name_token.column, this.source, this.filename);
}
// TODO: Parse attributes for let:prop syntax in future
const attributes = {};
// Check for self-closing slot
if (this.match(TokenType.SLASH)) {
const end_token = this.consume(TokenType.GT, 'Expected >');
return createNode(NodeType.SLOT, {
name: name_token.value,
attributes,
children: [],
selfClosing: true
}, start_token.start, end_token.end, start_token.line, start_token.column, this.create_location(start_token, end_token));
}
// Regular slot with content
this.consume(TokenType.GT, 'Expected >');
const children = [];
// Parse until we find the closing tag
while (!this.check(TokenType.SLOT_END)) {
if (this.is_at_end()) {
const error = unclosedError('slot', name_token.value, name_token.line, name_token.column, this.source, this.filename);
error.message += getSuggestion(error.message);
throw error;
}
const node = this.parse_content();
if (node) {
children.push(node);
}
}
// Consume closing tag
this.consume(TokenType.SLOT_END, 'Expected </#');
const closing_name = this.consume(TokenType.SLOT_NAME, 'Expected slot name');
if (closing_name.value !== name_token.value) {
throw mismatchedTagError(name_token.value, closing_name.value, closing_name.line, closing_name.column, this.source, this.filename);
}
const end_token = this.consume(TokenType.GT, 'Expected >');
return createNode(NodeType.SLOT, {
name: name_token.value,
attributes,
children,
selfClosing: false
}, start_token.start, end_token.end, start_token.line, start_token.column, this.create_location(start_token, end_token));
}
// Token navigation helpers
// Parse HTML tag or component invocation
parse_tag() {
const start_token = this.previous(); // TAG_OPEN
const name_token = this.consume(TokenType.TAG_NAME, 'Expected tag name');
let tag_name = name_token.value;
let original_tag_name = null; // Track original for $redrawable
// Check for forbidden tags
const tag_lower = tag_name.toLowerCase();
if (tag_lower === 'script' || tag_lower === 'style') {
throw syntaxError(`<${tag_name}> tags are not allowed in JQHTML templates. ` +
`Use external files or inline styles via attributes instead.`, name_token.line, name_token.column, this.source, this.filename);
}
// Determine if this is a component (starts with capital letter) or HTML tag
let is_component = tag_name[0] >= 'A' && tag_name[0] <= 'Z';
// Check if this is an HTML5 void element (only for HTML tags, not components)
const is_void_element = !is_component && Parser.VOID_ELEMENTS.has(tag_lower);
// Parse attributes
const attributes = this.parse_attributes();
// Check for $redrawable attribute transformation
// Transform <div $redrawable> to <Redrawable tag="div">
if (attributes['$redrawable'] !== undefined || attributes['data-redrawable'] !== undefined) {
const redrawable_attr = attributes['$redrawable'] !== undefined ? '$redrawable' : 'data-redrawable';
// Remove the $redrawable attribute
delete attributes[redrawable_attr];
// Store original tag name for closing tag matching
original_tag_name = tag_name;
// Add tag="original_tag_name" attribute
attributes['data-tag'] = { quoted: true, value: tag_name };
// Transform tag name to Redrawable (reserved component name)
tag_name = 'Redrawable';
is_component = true; // Now it's a component
}
// Check for explicit self-closing syntax
if (this.match(TokenType.SELF_CLOSING)) {
const end_token = this.previous();
if (is_component) {
return createNode(NodeType.COMPONENT_INVOCATION, {
name: tag_name,
attributes,
children: [],
selfClosing: true
}, start_token.start, end_token.end, start_token.line, start_token.column, this.create_location(start_token, end_token));
}
else {
return createNode(NodeType.HTML_TAG, {
name: tag_name,
attributes,
children: [],
selfClosing: true
}, start_token.start, end_token.end, start_token.line, start_token.column, this.create_location(start_token, end_token));
}
}
// Auto-close void elements even without explicit /> syntax
// This matches standard HTML5 authoring where <input> doesn't need />
if (is_void_element) {
// Skip newlines before >
while (this.match(TokenType.NEWLINE)) {
// Skip newlines
}
const end_token = this.consume(TokenType.GT, 'Expected >');
// Void elements are always HTML tags (not components)
return createNode(NodeType.HTML_TAG, {
name: tag_name,
attributes,
children: [],
selfClosing: true
}, start_token.start, end_token.end, start_token.line, start_token.column, this.create_location(start_token, end_token));
}
// Must be a paired tag - skip newlines before >
while (this.match(TokenType.NEWLINE)) {
// Skip newlines
}
this.consume(TokenType.GT, 'Expected >');
// Parse children
const children = [];
// Keep parsing content until we hit the closing tag
// For $redrawable transforms, accept either original or transformed name
while (!this.check_closing_tag(tag_name) &&
!(original_tag_name && this.check_closing_tag(original_tag_name))) {
if (this.is_at_end()) {
const error = unclosedError(is_component ? 'component' : 'tag', tag_name, start_token.line, start_token.column, this.source, this.filename);
throw error;
}
const child = this.parse_content();
if (child) {
children.push(child);
}
}
// Consume closing tag
this.consume(TokenType.TAG_CLOSE, 'Expected </');
const close_name = this.consume(TokenType.TAG_NAME, 'Expected tag name');
// For $redrawable transforms, accept either original or transformed tag name
const is_valid_closing = close_name.value === tag_name ||
(original_tag_name && close_name.value === original_tag_name);
if (!is_valid_closing) {
throw mismatchedTagError(original_tag_name || tag_name, // Show original name in error
close_name.value, close_name.line, close_name.column, this.source, this.filename);
}
const end_token = this.consume(TokenType.GT, 'Expected >');
if (is_component) {
// Validate mixed content mode for components
this.validate_component_children(children, tag_name, start_token);
return createNode(NodeType.COMPONENT_INVOCATION, {
name: tag_name,
attributes,
children,
selfClosing: false
}, start_token.start, end_token.end, start_token.line, start_token.column, this.create_location(start_token, end_token));
}
else {
return createNode(NodeType.HTML_TAG, {
name: tag_name,
attributes,
children,
selfClosing: false
}, start_token.start, end_token.end, start_token.line, start_token.column, this.create_location(start_token, end_token));
}
}
// Parse attributes from tokens
parse_attributes() {
const attributes = {};
// Skip any leading newlines
while (this.match(TokenType.NEWLINE)) {
// Skip
}
while (this.check(TokenType.ATTR_NAME)) {
const name_token = this.advance();
let name = name_token.value;
let value = true; // Default for boolean attributes
// Check for equals sign and value
if (this.match(TokenType.EQUALS)) {
// Check if this is a compound value with interpolation
if (this.check(TokenType.ATTR_VALUE) ||
this.check(TokenType.EXPRESSION_START) ||
this.check(TokenType.EXPRESSION_UNESCAPED)) {
value = this.parse_attribute_value();
}
}
// Handle special attribute prefixes
if (name.startsWith('$')) {
if (name === '$id') {
// Special case: $id becomes regular id (will be scoped in codegen)
name = 'id';
}
else {
// General case: $property becomes data-property
name = 'data-' + name.substring(1);
// Keep the value object intact to preserve quoted/unquoted distinction
}
}
else if (name.startsWith(':')) {
// Property binding: :prop="value" becomes data-bind-prop
// Preserve whether value was quoted or not for proper code generation
name = 'data-bind-' + name.substring(1);
// Keep the value object intact to preserve quoted/unquoted distinction
}
else if (name.startsWith('@')) {
// Event binding: @click="handler" becomes data-on-click
// Preserve whether value was quoted or not for proper code generation
name = 'data-on-' + name.substring(1);
// Keep the value object intact to preserve quoted/unquoted distinction
}
attributes[name] = value;
// Skip newlines between attributes
while (this.match(TokenType.NEWLINE)) {
// Skip
}
}
return attributes;
}
// Parse potentially compound attribute value
parse_attribute_value() {
const parts = [];
// For simple string values that are quoted in the source, return them with a quoted flag
// This helps the codegen distinguish between $foo="bar" and $foo=bar
const firstToken = this.peek();
const isSimpleValue = this.check(TokenType.ATTR_VALUE) &&
!this.check_ahead(1, TokenType.EXPRESSION_START) &&
!this.check_ahead(1, TokenType.EXPRESSION_UNESCAPED);
// Collect all parts of the attribute value
while (this.check(TokenType.ATTR_VALUE) ||
this.check(TokenType.EXPRESSION_START) ||
this.check(TokenType.EXPRESSION_UNESCAPED)) {
if (this.check(TokenType.ATTR_VALUE)) {
const token = this.advance();
parts.push({ type: 'text', value: token.value, escaped: true });
}
else if (this.check(TokenType.EXPRESSION_START) ||
this.check(TokenType.EXPRESSION_UNESCAPED)) {
const is_escaped = this.peek().type === TokenType.EXPRESSION_START;
this.advance(); // consume <%= or <%!=
const expr_token = this.consume(TokenType.JAVASCRIPT, 'Expected expression');
this.consume(TokenType.TAG_END, 'Expected %>');
parts.push({ type: 'expression', value: expr_token.value, escaped: is_escaped });
}
}
// If it's a single text part, check if it's quoted
if (parts.length === 1 && parts[0].type === 'text') {
const value = parts[0].value;
// Check if the value has quotes (preserved by lexer for quoted strings)
if ((value.startsWith('"') && value.endsWith('"')) ||
(value.startsWith("'") && value.endsWith("'"))) {
// Return a marker that this was a quoted string
return { quoted: true, value: value.slice(1, -1) };
}
// Check if it's a parenthesized expression: $attr=(expr)
if (value.startsWith('(') && value.endsWith(')')) {
// Return as an expression - remove the parentheses
return { expression: true, value: value.slice(1, -1) };
}
// Check if it's a bare identifier or member expression: $attr=identifier or $attr=this.method
// Valid identifiers can include dots for member access (e.g., this.handleClick, data.user.name)
// Can be prefixed with ! for negation (e.g., !this.canEdit)
// Pattern: optional ! then starts with letter/$/_ then any combo of letters/numbers/$/_ and dots
if (/^!?[a-zA-Z_$][a-zA-Z0-9_$.]*$/.test(value)) {
// Return as an identifier expression
return { identifier: true, value: value };
}
// Otherwise, treat as a literal string value
return value;
}
// Any expression or multiple parts needs interpolation handling
return { interpolated: true, parts };
}
// Check if we're at a closing tag for the given name
check_closing_tag(tag_name) {
if (!this.check(TokenType.TAG_CLOSE)) {
return false;
}
// Look ahead to see if the tag name matches
const next_pos = this.current + 1;
if (next_pos < this.tokens.length &&
this.tokens[next_pos].type === TokenType.TAG_NAME &&
this.tokens[next_pos].value === tag_name) {
return true;
}
return false;
}
match(...types) {
for (const type of types) {
if (this.check(type)) {
this.advance();
return true;
}
}
return false;
}
check(type) {
if (this.is_at_end())
return false;
return this.peek().type === type;
}
check_ahead(offset, type) {
if (this.current + offset >= this.tokens.length) {
return false;
}
return this.tokens[this.current + offset].type === type;
}
check_sequence(...types) {
for (let i = 0; i < types.length; i++) {
if (this.current + i >= this.tokens.length) {
return false;
}
if (this.tokens[this.current + i].type !== types[i]) {
return false;
}
}
return true;
}
advance() {
if (!this.is_at_end())
this.current++;
return this.previous();
}
is_at_end() {
return this.peek().type === TokenType.EOF;
}
peek() {
return this.tokens[this.current];
}
peek_ahead(offset) {
const pos = this.current + offset;
if (pos >= this.tokens.length) {
return this.tokens[this.tokens.length - 1]; // Return EOF token
}
return this.tokens[pos];
}
previous() {
return this.tokens[this.current - 1];
}
current_token() {
return this.tokens[this.current] || this.tokens[this.tokens.length - 1];
}
previous_token() {
return this.tokens[Math.max(0, this.current - 1)];
}
/**
* Create a SourceLocation from start and end tokens
* Propagates loc field if available, falls back to old fields for compatibility
*/
create_location(start, end) {
if (start.loc && end.loc) {
// Use new loc field if available
return {
start: start.loc.start,
end: end.loc.end
};
}
// Fall back to old fields for backward compatibility
return undefined;
}
consume(type, message) {
if (this.check(type))
return this.advance();
const token = this.peek();
// Special case: Detecting template expressions inside HTML tag attributes
if (type === TokenType.GT &&
(token.type === TokenType.EXPRESSION_START || token.type === TokenType.EXPRESSION_UNESCAPED)) {
const error = syntaxError('Template expressions (<% %>) cannot be used as attribute values inside HTML tags', token.line, token.column, this.source, this.filename);
// Add helpful remediation examples
error.message += '\n\n' +
' Use template expressions INSIDE attribute values instead:\n' +
' ✅ <tag style="<%= expression %>">\n' +
' ✅ <tag class="<%= condition ? \'active\' : \'\' %>">\n\n' +
' Or use conditional logic before the tag:\n' +
' ✅ <% let attrs = expression ? \'value\' : \'\'; %>\n' +
' <tag attr="<%= attrs %>">\n\n' +
' Or set attributes in on_ready() using jQuery:\n' +
' ✅ <tag $id="my_element">\n' +
' on_ready() {\n' +
' if (this.args.required) this.$id(\'my_element\').attr(\'required\', true);\n' +
' }';
throw error;
}
const error = syntaxError(`${message}. Got ${token.type} instead`, token.line, token.column, this.source, this.filename);
throw error;
}
// Validate component children to prevent mixed content mode
validate_component_children(children, componentName, startToken) {
let hasSlots = false;
let hasNonSlotContent = false;
for (const child of children) {
if (child.type === NodeType.SLOT) {
hasSlots = true;
}
else if (child.type === NodeType.TEXT) {
// Check if it's non-whitespace text
const textContent = child.content;
if (textContent.trim() !== '') {
hasNonSlotContent = true;
}
}
else {
// Any other node type (expressions, tags, etc.) is non-slot content
hasNonSlotContent = true;
}
}
// If component has both slots and non-slot content, throw error
if (hasSlots && hasNonSlotContent) {
throw syntaxError(`Mixed content not allowed: when using slots, all content must be inside <#slotname> tags`, startToken.line, startToken.column, this.source, this.filename);
}
}
/**
* Compile method for simplified API
* Parses the template and returns component metadata and render function
*/
compile() {
// Parse to get AST
const ast = this.parse();
// Generate code with sourcemap
const generator = new CodeGenerator();
const result = generator.generateWithSourceMap(ast, this.filename || 'template.jqhtml', this.source || '');
// Extract the single component (should only be one per file)
const componentEntries = Array.from(result.components.entries());
if (componentEntries.length === 0) {
throw new Error('No component definition found in template');
}
if (componentEntries.length > 1) {
const names = componentEntries.map(([name]) => name).join(', ');
throw new Error(`Multiple component definitions found: ${names}. Only one component per file is allowed.`);
}
// Extract component information
const [name, componentDef] = componentEntries[0];
return {
name: name,
tagName: componentDef.tagName || 'div',
defaultAttributes: componentDef.defaultAttributes || {},
renderFunction: componentDef.render_function
};
}
}
//# sourceMappingURL=parser.js.map

1
node_modules/@jqhtml/parser/dist/parser.js.map generated vendored Executable file

File diff suppressed because one or more lines are too long

6
node_modules/@jqhtml/parser/dist/runtime.d.ts generated vendored Executable file
View File

@@ -0,0 +1,6 @@
export declare function process_instructions(instructions: any[], component: any): JQuery;
export declare function html(str: any): string;
export declare function register_template(name: string, render_fn: Function): void;
export declare function get_template(name: string): Function | undefined;
export declare function create_templated_component(ComponentClass: any, template_name: string, args?: Record<string, any>, element?: JQuery): any;
//# sourceMappingURL=runtime.d.ts.map

1
node_modules/@jqhtml/parser/dist/runtime.d.ts.map generated vendored Executable file
View File

@@ -0,0 +1 @@
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAMA,wBAAgB,oBAAoB,CAAC,YAAY,EAAE,GAAG,EAAE,EAAE,SAAS,EAAE,GAAG,GAAG,MAAM,CA6EhF;AAGD,wBAAgB,IAAI,CAAC,GAAG,EAAE,GAAG,GAAG,MAAM,CAMrC;AAMD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,QAElE;AAGD,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS,CAE/D;AAGD,wBAAgB,0BAA0B,CACxC,cAAc,EAAE,GAAG,EACnB,aAAa,EAAE,MAAM,EACrB,IAAI,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,EAC9B,OAAO,CAAC,EAAE,MAAM,GACf,GAAG,CAsBL"}

106
node_modules/@jqhtml/parser/dist/runtime.js generated vendored Executable file
View File

@@ -0,0 +1,106 @@
// JQHTML v2 Runtime - Processes instruction arrays from compiled templates
// Minimal implementation focused on MVP functionality
/// <reference path="./types.d.ts" />
// Process instruction array into DOM elements
export function process_instructions(instructions, component) {
const fragment = document.createDocumentFragment();
const stack = [];
let current = fragment;
for (const instruction of instructions) {
// Plain text
if (typeof instruction === 'string') {
const text = document.createTextNode(instruction);
current.appendChild(text);
continue;
}
// Tag instruction: {tag: [name, attrs, selfClosing]}
if (instruction.tag) {
const [tag_name, attrs, self_closing] = instruction.tag;
const element = document.createElement(tag_name);
// Set attributes
for (const [key, value] of Object.entries(attrs || {})) {
element.setAttribute(key, String(value));
}
current.appendChild(element);
// Push to stack if not self-closing
if (!self_closing) {
stack.push(current);
current = element;
}
continue;
}
// Component instruction: {comp: [name, props]}
if (instruction.comp) {
const [comp_name, props] = instruction.comp;
// Create placeholder div for component
const placeholder = document.createElement('div');
placeholder.setAttribute('data-component', comp_name);
placeholder.setAttribute('data-props', JSON.stringify(props || {}));
placeholder.setAttribute('data-state', 'uninitialized');
placeholder.className = 'jqhtml-component';
current.appendChild(placeholder);
// TODO: In future, instantiate component here
continue;
}
// Slot instruction: {slot: [name, props, renderFn]}
if (instruction.slot) {
const [slot_name, props, render_fn] = instruction.slot;
// Execute slot render function if provided
if (render_fn && typeof render_fn === 'function') {
const slot_context = { ...props };
const [slot_output] = render_fn.call(component, slot_context);
// Process slot output recursively
const slot_dom = process_instructions(slot_output, component);
slot_dom.each(function () {
current.appendChild(this);
});
}
continue;
}
// Closing tag (when we see a string like "</div>")
if (typeof instruction === 'string' && instruction.match(/^<\//)) {
if (stack.length > 0) {
current = stack.pop();
}
}
}
return $(fragment.childNodes);
}
// HTML escape function required by generated code
export function html(str) {
if (str == null)
return '';
const div = document.createElement('div');
div.textContent = String(str);
return div.innerHTML;
}
// Component template registry
const template_registry = new Map();
// Register a compiled template
export function register_template(name, render_fn) {
template_registry.set(name, render_fn);
}
// Get a compiled template
export function get_template(name) {
return template_registry.get(name);
}
// Create component with template
export function create_templated_component(ComponentClass, template_name, args = {}, element) {
const template = get_template(template_name);
if (!template) {
throw new Error(`Template not found: ${template_name}`);
}
// Create component instance - element first, then args
const component = new ComponentClass(element, args);
// Override on_render to use template
component.on_render = async function () {
// Call template render function
const [instructions] = template.call(this, ComponentClass, this.data, this.args, {});
// Process instructions into DOM
const rendered = process_instructions(instructions, this);
// Clear and append
this.$.empty().append(rendered);
};
return component;
}
//# sourceMappingURL=runtime.js.map

1
node_modules/@jqhtml/parser/dist/runtime.js.map generated vendored Executable file
View File

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