chore: fixing typing issues

This commit is contained in:
Kacper Kula 2025-02-01 13:53:46 +00:00
parent e30401b551
commit 8bbd976056
5 changed files with 54 additions and 50 deletions

View file

@ -1,2 +1,5 @@
# 0.1.1 (2025-02-01)
chore: Fixed typing in configParser
# 0.1.0 (2025-01-31)
Initial release!

View file

@ -1,7 +1,7 @@
{
"id": "sqlseal-charts",
"name": "SQLSeal Charts",
"version": "0.1.0",
"version": "0.1.1",
"minAppVersion": "0.15.0",
"isDesktopOnly": false,
"description": "Charts extension for SQLSeal plugin. Generate pie charts, bar charts, line charts and more using data stored in your vault!",

View file

@ -1,6 +1,6 @@
{
"name": "sqlseal-charts",
"version": "0.1.0",
"version": "0.1.1",
"description": "Chart extension for SQLSeal Obsidian plugin",
"main": "main.js",
"scripts": {

View file

@ -1,29 +1,33 @@
import * as acorn from 'acorn';
import { Node, ObjectExpression, Property, CallExpression, Identifier, Literal,
ArrayExpression, MemberExpression, ArrowFunctionExpression, BlockStatement,
TemplateLiteral } from 'estree';
import type {
Node, ObjectExpression, Property, CallExpression, Identifier,
Literal, ArrayExpression, MemberExpression, ArrowFunctionExpression,
BlockStatement, TemplateLiteral, ExpressionStatement, TemplateElement
} from 'acorn';
type AllowedFunctions = Record<string, (...args: any[]) => any>;
type AllowedVariables = Record<string, any>;
// Define more specific types for function parameters and returns
type AllowedFunction = (...args: unknown[]) => unknown;
type AllowedFunctions = Record<string, AllowedFunction>;
type AllowedVariables = Record<string, unknown>;
// Extended to include function scope
interface EvaluationContext {
allowedFunctions: AllowedFunctions;
allowedVariables: AllowedVariables;
scope: Record<string, any>;
scope: Record<string, unknown>;
}
export function parseCode(
code: string,
allowedFunctions: AllowedFunctions = {},
allowedVariables: AllowedVariables = {}
) {
): unknown {
const wrappedCode = `(${code})`;
const ast = acorn.parse(wrappedCode, {
ecmaVersion: 2020,
sourceType: 'module'
}) as any;
})
const context: EvaluationContext = {
allowedFunctions,
@ -31,7 +35,7 @@ export function parseCode(
scope: {}
};
function evaluateNode(node: Node, context: EvaluationContext): any {
function evaluateNode(node: Node, context: EvaluationContext): unknown {
if (!node) {
throw new Error('Null node encountered');
}
@ -54,23 +58,21 @@ export function parseCode(
case 'BlockStatement':
return evaluateBlockStatement(node as BlockStatement, context);
case 'TemplateLiteral':
return evaluateTemplateLiteral(node as any, context);
return evaluateTemplateLiteral(node as TemplateLiteral, context);
case 'TemplateElement':
return (node as any).value.cooked;
return (node as TemplateElement).value.cooked;
default:
throw new Error(`Unsupported node type: ${node.type}`);
}
}
function evaluateArrowFunction(node: ArrowFunctionExpression, context: EvaluationContext): Function {
return (...args: any[]) => {
// Create a new scope for the function execution
return (...args: unknown[]) => {
const functionContext: EvaluationContext = {
...context,
scope: { ...context.scope }
};
// Bind parameters to arguments
node.params.forEach((param, index) => {
if (param.type === 'Identifier') {
functionContext.scope[param.name] = args[index];
@ -79,7 +81,6 @@ export function parseCode(
}
});
// Handle both expression and block body
if (node.body.type === 'BlockStatement') {
return evaluateBlockStatement(node.body, functionContext);
} else {
@ -88,26 +89,22 @@ export function parseCode(
};
}
function evaluateBlockStatement(node: BlockStatement, context: EvaluationContext): any {
let result: any;
function evaluateBlockStatement(node: BlockStatement, context: EvaluationContext) {
let result: unknown;
for (const statement of node.body) {
result = evaluateNode(statement, context);
}
return result; // Returns the value of the last statement
return result;
}
function evaluateTemplateLiteral(node: TemplateLiteral, context: EvaluationContext): string {
let result = '';
const expressions = node.expressions;
const quasis = node.quasis;
for (let i = 0; i < quasis.length; i++) {
// Add the template string part
result += evaluateNode(quasis[i], context);
for (let i = 0; i < node.quasis.length; i++) {
result += evaluateNode(node.quasis[i], context) as string;
// Add the expression value if there is one
if (i < expressions.length) {
const value = evaluateNode(expressions[i], context);
if (i < node.expressions.length) {
const value = evaluateNode(node.expressions[i], context);
result += value != null ? String(value) : '';
}
}
@ -115,20 +112,19 @@ export function parseCode(
return result;
}
function evaluateIdentifier(node: Identifier, context: EvaluationContext): any {
function evaluateIdentifier(node: Identifier, context: EvaluationContext) {
const varName = node.name;
// Check scope first, then allowed variables
if (context.scope.hasOwnProperty(varName)) {
if (Object.prototype.hasOwnProperty.call(context.scope, varName)) {
return context.scope[varName];
}
if (context.allowedVariables.hasOwnProperty(varName)) {
if (Object.prototype.hasOwnProperty.call(context.allowedVariables, varName)) {
return context.allowedVariables[varName];
}
throw new Error(`Variable "${varName}" is not allowed`);
}
function evaluateMemberExpression(node: MemberExpression, context: EvaluationContext): any {
// Evaluate the object part of the member expression
function evaluateMemberExpression(node: MemberExpression, context: EvaluationContext): unknown {
const object = node.object.type === 'MemberExpression'
? evaluateMemberExpression(node.object, context)
: node.object.type === 'Identifier'
@ -139,45 +135,49 @@ export function parseCode(
throw new Error('Cannot access properties of null or undefined');
}
// Handle computed (bracket notation) access
if (node.computed) {
const propertyValue = evaluateNode(node.property, context);
if (typeof propertyValue !== 'number' && typeof propertyValue !== 'string') {
throw new Error('Property access must use number or string');
}
return object[propertyValue];
return (object as Record<string | number, unknown>)[propertyValue];
}
// Handle dot notation access
if (node.property.type === 'Identifier') {
return object[node.property.name];
return (object as Record<string, unknown>)[node.property.name];
}
throw new Error('Invalid property access');
}
function evaluateObject(node: ObjectExpression, context: EvaluationContext): Record<string, any> {
const result: Record<string, any> = {};
function evaluateObject(node: acorn.ObjectExpression, context: EvaluationContext): Record<string, unknown> {
const result: Record<string, unknown> = {};
for (const prop of node.properties) {
const property = prop as Property;
const key = property.key.type === 'Identifier' ?
property.key.name :
(property.key as Literal).value;
const key = property.key.type === 'Identifier'
? property.key.name
: (property.key as Literal).value;
result[key as string] = evaluateNode(property.value, context);
if (typeof key === 'string') {
result[key] = evaluateNode(property.value, context);
}
}
return result;
}
function evaluateArray(node: ArrayExpression, context: EvaluationContext): any[] {
function evaluateArray(node: ArrayExpression, context: EvaluationContext): unknown[] {
return node.elements.map(element =>
element ? evaluateNode(element, context) : null
);
}
function evaluateCall(node: CallExpression, context: EvaluationContext): any {
const isExpressionStatement = (x:(acorn.Statement | acorn.ModuleDeclaration)): x is ExpressionStatement => {
return !!x && x.type === 'ExpressionStatement'
}
function evaluateCall(node: CallExpression, context: EvaluationContext): unknown {
let func: Function;
if (node.callee.type === 'Identifier') {
@ -187,7 +187,7 @@ export function parseCode(
}
func = context.allowedFunctions[callee];
} else if (node.callee.type === 'ArrowFunctionExpression') {
func = evaluateArrowFunction(node.callee as ArrowFunctionExpression, context);
func = evaluateArrowFunction(node.callee, context);
} else {
throw new Error('Unsupported function call type');
}
@ -196,8 +196,8 @@ export function parseCode(
return func(...args);
}
const expressionStatement = ast.body[0];
if (!expressionStatement || expressionStatement.type !== 'ExpressionStatement') {
const expressionStatement = ast.body[0]
if (!isExpressionStatement(expressionStatement)) {
throw new Error('Invalid input structure');
}

View file

@ -1,3 +1,4 @@
{
"0.1.0": "0.15.0"
"0.1.0": "0.15.0",
"0.1.1": "0.15.0"
}