@run-iq/plugin-sdk 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js.map +1 -1
- package/package.json +5 -3
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/base/BasePlugin.ts","../src/base/BaseModel.ts","../src/testing/PluginTester.ts","../src/validation/SchemaValidator.ts"],"sourcesContent":["export { BasePlugin } from './base/BasePlugin.js';\nexport { BaseModel } from './base/BaseModel.js';\nexport { PluginTester } from './testing/PluginTester.js';\nexport type { TestReport } from './testing/PluginTester.js';\nexport { SchemaValidator } from './validation/SchemaValidator.js';\nexport type { SchemaDefinition, SchemaFieldDef } from './validation/SchemaValidator.js';\nexport type {\n Rule,\n Expression,\n EvaluationInput,\n EvaluationResult,\n BreakdownItem,\n SkippedRule,\n SkipReason,\n PPEPlugin,\n PluginContext,\n CalculationModel,\n ValidationResult,\n DSLEvaluator,\n ISnapshotAdapter,\n Snapshot,\n EvaluationTrace,\n TraceStep,\n RuleFieldDescriptor,\n InputFieldDescriptor,\n RuleExample,\n PluginDescriptor,\n PluginBundle,\n} from './types/index.js';\n","import type {\n PPEPlugin,\n PluginContext,\n EvaluationInput,\n EvaluationResult,\n Rule,\n CalculationModel,\n PPEError,\n} from '@run-iq/core';\n\nexport abstract class BasePlugin implements PPEPlugin {\n abstract readonly name: string;\n abstract readonly version: string;\n abstract readonly models: CalculationModel[];\n\n onInit(context: PluginContext): void {\n for (const model of this.models) {\n context.modelRegistry.register(model);\n }\n }\n\n beforeEvaluate(input: EvaluationInput, _rules: ReadonlyArray<Rule>): EvaluationInput {\n return input;\n }\n\n afterEvaluate(_input: EvaluationInput, result: EvaluationResult): EvaluationResult {\n return result;\n }\n\n onError(_error: PPEError, _input: EvaluationInput): void {\n // no-op by default\n }\n\n teardown(): void {\n // no-op by default\n }\n}\n","import type { CalculationModel, ValidationResult, Rule } from '@run-iq/core';\n\nexport abstract class BaseModel implements CalculationModel {\n abstract readonly name: string;\n abstract readonly version: string;\n\n abstract validateParams(params: unknown): ValidationResult;\n\n abstract calculate(\n input: Record<string, unknown>,\n matchedRule: Readonly<Rule>,\n params: unknown,\n ): number;\n}\n","import type {\n PPEPlugin,\n PluginContext,\n EvaluationInput,\n Rule,\n CalculationModel,\n} from '@run-iq/core';\n\nexport interface TestReport {\n readonly passed: string[];\n readonly failed: Array<{ test: string; error: string }>;\n readonly summary: 'PASS' | 'FAIL';\n}\n\nexport class PluginTester {\n private readonly plugin: PPEPlugin;\n\n constructor(plugin: PPEPlugin) {\n this.plugin = plugin;\n }\n\n async assertDeterminism(\n input: EvaluationInput,\n rules: ReadonlyArray<Rule>,\n context: PluginContext,\n ): Promise<void> {\n this.plugin.onInit(context);\n\n const results: EvaluationInput[] = [];\n for (let i = 0; i < 3; i++) {\n if (this.plugin.beforeEvaluate) {\n results.push(this.plugin.beforeEvaluate(input, rules));\n }\n }\n\n if (results.length === 3) {\n const json0 = JSON.stringify(results[0]);\n const json1 = JSON.stringify(results[1]);\n const json2 = JSON.stringify(results[2]);\n if (json0 !== json1 || json1 !== json2) {\n throw new Error('Determinism violation: different results for same input');\n }\n }\n }\n\n async assertImmutability(input: EvaluationInput, rules: ReadonlyArray<Rule>): Promise<void> {\n const inputCopy = JSON.parse(JSON.stringify(input)) as EvaluationInput;\n const rulesCopy = JSON.parse(JSON.stringify(rules)) as Rule[];\n\n if (this.plugin.beforeEvaluate) {\n this.plugin.beforeEvaluate(input, rules);\n }\n\n if (JSON.stringify(input) !== JSON.stringify(inputCopy)) {\n throw new Error('Immutability violation: beforeEvaluate mutated input');\n }\n if (JSON.stringify(rules) !== JSON.stringify(rulesCopy)) {\n throw new Error('Immutability violation: beforeEvaluate mutated rules');\n }\n }\n\n async assertParamsValidation(\n modelName: string,\n invalidParams: unknown[],\n context: PluginContext,\n ): Promise<void> {\n this.plugin.onInit(context);\n\n const model = this.findModel(modelName, context);\n if (!model) {\n throw new Error(`Model \"${modelName}\" not found in plugin`);\n }\n\n for (const params of invalidParams) {\n const result = model.validateParams(params);\n if (result.valid) {\n throw new Error(\n `Expected model \"${modelName}\" to reject params: ${JSON.stringify(params)}`,\n );\n }\n }\n }\n\n async assertNoSideEffects(input: EvaluationInput, rules: ReadonlyArray<Rule>): Promise<void> {\n if (this.plugin.beforeEvaluate) {\n const r1 = this.plugin.beforeEvaluate(input, rules);\n const r2 = this.plugin.beforeEvaluate(input, rules);\n\n if (JSON.stringify(r1) !== JSON.stringify(r2)) {\n throw new Error('Side effects detected: different results between calls');\n }\n }\n }\n\n async runAll(\n input: EvaluationInput,\n rules: ReadonlyArray<Rule>,\n context: PluginContext,\n ): Promise<TestReport> {\n const passed: string[] = [];\n const failed: Array<{ test: string; error: string }> = [];\n\n const tests = [\n { name: 'determinism', fn: () => this.assertDeterminism(input, rules, context) },\n { name: 'immutability', fn: () => this.assertImmutability(input, rules) },\n { name: 'noSideEffects', fn: () => this.assertNoSideEffects(input, rules) },\n ];\n\n for (const t of tests) {\n try {\n await t.fn();\n passed.push(t.name);\n } catch (error) {\n failed.push({\n test: t.name,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n return {\n passed,\n failed,\n summary: failed.length === 0 ? 'PASS' : 'FAIL',\n };\n }\n\n private findModel(name: string, context: PluginContext): CalculationModel | undefined {\n try {\n return context.modelRegistry.get(name);\n } catch {\n return undefined;\n }\n }\n}\n","import type { ValidationResult } from '@run-iq/core';\n\nexport interface SchemaFieldDef {\n readonly type: 'number' | 'string' | 'boolean' | 'array' | 'object';\n readonly min?: number | undefined;\n readonly max?: number | undefined;\n readonly enum?: readonly string[] | undefined;\n readonly required?: boolean | undefined;\n}\n\nexport type SchemaDefinition = Record<string, SchemaFieldDef>;\n\nexport class SchemaValidator {\n static validate(params: unknown, schema: SchemaDefinition): ValidationResult {\n const errors: string[] = [];\n\n if (params === null || typeof params !== 'object') {\n return { valid: false, errors: ['params must be a non-null object'] };\n }\n\n const obj = params as Record<string, unknown>;\n\n for (const [key, def] of Object.entries(schema)) {\n const value = obj[key];\n const isRequired = def.required !== false;\n\n if (value === undefined || value === null) {\n if (isRequired) {\n errors.push(`\"${key}\" is required`);\n }\n continue;\n }\n\n if (def.type === 'number') {\n if (typeof value !== 'number' || Number.isNaN(value)) {\n errors.push(`\"${key}\" must be a number`);\n continue;\n }\n if (def.min !== undefined && value < def.min) {\n errors.push(`\"${key}\" must be >= ${def.min}`);\n }\n if (def.max !== undefined && value > def.max) {\n errors.push(`\"${key}\" must be <= ${def.max}`);\n }\n } else if (def.type === 'string') {\n if (typeof value !== 'string') {\n errors.push(`\"${key}\" must be a string`);\n continue;\n }\n if (def.enum && !def.enum.includes(value)) {\n errors.push(`\"${key}\" must be one of: ${def.enum.join(', ')}`);\n }\n } else if (def.type === 'boolean') {\n if (typeof value !== 'boolean') {\n errors.push(`\"${key}\" must be a boolean`);\n }\n } else if (def.type === 'array') {\n if (!Array.isArray(value)) {\n errors.push(`\"${key}\" must be an array`);\n }\n } else if (def.type === 'object') {\n if (typeof value !== 'object' || Array.isArray(value)) {\n errors.push(`\"${key}\" must be an object`);\n }\n }\n }\n\n return errors.length > 0 ? { valid: false, errors } : { valid: true };\n }\n\n static number(value: unknown, opts?: { min?: number; max?: number }): boolean {\n if (typeof value !== 'number' || Number.isNaN(value)) return false;\n if (opts?.min !== undefined && value < opts.min) return false;\n if (opts?.max !== undefined && value > opts.max) return false;\n return true;\n }\n\n static string(value: unknown, opts?: { enum?: readonly string[] }): boolean {\n if (typeof value !== 'string') return false;\n if (opts?.enum && !opts.enum.includes(value)) return false;\n return true;\n }\n\n static positiveNumber(value: unknown): boolean {\n return SchemaValidator.number(value, { min: 0 });\n }\n\n static rate(value: unknown): boolean {\n return SchemaValidator.number(value, { min: 0, max: 1 });\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/base/BasePlugin.ts","../src/base/BaseModel.ts","../src/testing/PluginTester.ts","../src/validation/SchemaValidator.ts"],"sourcesContent":["export { BasePlugin } from './base/BasePlugin.js';\nexport { BaseModel } from './base/BaseModel.js';\nexport { PluginTester } from './testing/PluginTester.js';\nexport type { TestReport } from './testing/PluginTester.js';\nexport { SchemaValidator } from './validation/SchemaValidator.js';\nexport type { SchemaDefinition, SchemaFieldDef } from './validation/SchemaValidator.js';\nexport type {\n Rule,\n Expression,\n EvaluationInput,\n EvaluationResult,\n BreakdownItem,\n SkippedRule,\n SkipReason,\n PPEPlugin,\n PluginContext,\n CalculationModel,\n ValidationResult,\n DSLEvaluator,\n ISnapshotAdapter,\n Snapshot,\n EvaluationTrace,\n TraceStep,\n RuleFieldDescriptor,\n InputFieldDescriptor,\n RuleExample,\n PluginDescriptor,\n PluginBundle,\n} from './types/index.js';\n","import type {\n PPEPlugin,\n PluginContext,\n EvaluationInput,\n EvaluationResult,\n Rule,\n CalculationModel,\n PPEError,\n} from '@run-iq/core';\n\nexport abstract class BasePlugin implements PPEPlugin {\n abstract readonly name: string;\n abstract readonly version: string;\n abstract readonly models: CalculationModel[];\n\n onInit(context: PluginContext): void {\n for (const model of this.models) {\n context.modelRegistry.register(model);\n }\n }\n\n beforeEvaluate(input: EvaluationInput, _rules: ReadonlyArray<Rule>): EvaluationInput {\n return input;\n }\n\n afterEvaluate(_input: EvaluationInput, result: EvaluationResult): EvaluationResult {\n return result;\n }\n\n onError(_error: PPEError, _input: EvaluationInput): void {\n // no-op by default\n }\n\n teardown(): void {\n // no-op by default\n }\n}\n","import type { CalculationModel, CalculationOutput, ValidationResult, Rule } from '@run-iq/core';\n\nexport abstract class BaseModel implements CalculationModel {\n abstract readonly name: string;\n abstract readonly version: string;\n\n abstract validateParams(params: unknown): ValidationResult;\n\n abstract calculate(\n input: Record<string, unknown>,\n matchedRule: Readonly<Rule>,\n params: unknown,\n ): number | CalculationOutput;\n}\n","import type {\n PPEPlugin,\n PluginContext,\n EvaluationInput,\n Rule,\n CalculationModel,\n} from '@run-iq/core';\n\nexport interface TestReport {\n readonly passed: string[];\n readonly failed: Array<{ test: string; error: string }>;\n readonly summary: 'PASS' | 'FAIL';\n}\n\nexport class PluginTester {\n private readonly plugin: PPEPlugin;\n\n constructor(plugin: PPEPlugin) {\n this.plugin = plugin;\n }\n\n async assertDeterminism(\n input: EvaluationInput,\n rules: ReadonlyArray<Rule>,\n context: PluginContext,\n ): Promise<void> {\n this.plugin.onInit(context);\n\n const results: EvaluationInput[] = [];\n for (let i = 0; i < 3; i++) {\n if (this.plugin.beforeEvaluate) {\n results.push(this.plugin.beforeEvaluate(input, rules));\n }\n }\n\n if (results.length === 3) {\n const json0 = JSON.stringify(results[0]);\n const json1 = JSON.stringify(results[1]);\n const json2 = JSON.stringify(results[2]);\n if (json0 !== json1 || json1 !== json2) {\n throw new Error('Determinism violation: different results for same input');\n }\n }\n }\n\n async assertImmutability(input: EvaluationInput, rules: ReadonlyArray<Rule>): Promise<void> {\n const inputCopy = JSON.parse(JSON.stringify(input)) as EvaluationInput;\n const rulesCopy = JSON.parse(JSON.stringify(rules)) as Rule[];\n\n if (this.plugin.beforeEvaluate) {\n this.plugin.beforeEvaluate(input, rules);\n }\n\n if (JSON.stringify(input) !== JSON.stringify(inputCopy)) {\n throw new Error('Immutability violation: beforeEvaluate mutated input');\n }\n if (JSON.stringify(rules) !== JSON.stringify(rulesCopy)) {\n throw new Error('Immutability violation: beforeEvaluate mutated rules');\n }\n }\n\n async assertParamsValidation(\n modelName: string,\n invalidParams: unknown[],\n context: PluginContext,\n ): Promise<void> {\n this.plugin.onInit(context);\n\n const model = this.findModel(modelName, context);\n if (!model) {\n throw new Error(`Model \"${modelName}\" not found in plugin`);\n }\n\n for (const params of invalidParams) {\n const result = model.validateParams(params);\n if (result.valid) {\n throw new Error(\n `Expected model \"${modelName}\" to reject params: ${JSON.stringify(params)}`,\n );\n }\n }\n }\n\n async assertNoSideEffects(input: EvaluationInput, rules: ReadonlyArray<Rule>): Promise<void> {\n if (this.plugin.beforeEvaluate) {\n const r1 = this.plugin.beforeEvaluate(input, rules);\n const r2 = this.plugin.beforeEvaluate(input, rules);\n\n if (JSON.stringify(r1) !== JSON.stringify(r2)) {\n throw new Error('Side effects detected: different results between calls');\n }\n }\n }\n\n async runAll(\n input: EvaluationInput,\n rules: ReadonlyArray<Rule>,\n context: PluginContext,\n ): Promise<TestReport> {\n const passed: string[] = [];\n const failed: Array<{ test: string; error: string }> = [];\n\n const tests = [\n { name: 'determinism', fn: () => this.assertDeterminism(input, rules, context) },\n { name: 'immutability', fn: () => this.assertImmutability(input, rules) },\n { name: 'noSideEffects', fn: () => this.assertNoSideEffects(input, rules) },\n ];\n\n for (const t of tests) {\n try {\n await t.fn();\n passed.push(t.name);\n } catch (error) {\n failed.push({\n test: t.name,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n return {\n passed,\n failed,\n summary: failed.length === 0 ? 'PASS' : 'FAIL',\n };\n }\n\n private findModel(name: string, context: PluginContext): CalculationModel | undefined {\n try {\n return context.modelRegistry.get(name);\n } catch {\n return undefined;\n }\n }\n}\n","import type { ValidationResult } from '@run-iq/core';\n\nexport interface SchemaFieldDef {\n readonly type: 'number' | 'string' | 'boolean' | 'array' | 'object';\n readonly min?: number | undefined;\n readonly max?: number | undefined;\n readonly enum?: readonly string[] | undefined;\n readonly required?: boolean | undefined;\n}\n\nexport type SchemaDefinition = Record<string, SchemaFieldDef>;\n\nexport class SchemaValidator {\n static validate(params: unknown, schema: SchemaDefinition): ValidationResult {\n const errors: string[] = [];\n\n if (params === null || typeof params !== 'object') {\n return { valid: false, errors: ['params must be a non-null object'] };\n }\n\n const obj = params as Record<string, unknown>;\n\n for (const [key, def] of Object.entries(schema)) {\n const value = obj[key];\n const isRequired = def.required !== false;\n\n if (value === undefined || value === null) {\n if (isRequired) {\n errors.push(`\"${key}\" is required`);\n }\n continue;\n }\n\n if (def.type === 'number') {\n if (typeof value !== 'number' || Number.isNaN(value)) {\n errors.push(`\"${key}\" must be a number`);\n continue;\n }\n if (def.min !== undefined && value < def.min) {\n errors.push(`\"${key}\" must be >= ${def.min}`);\n }\n if (def.max !== undefined && value > def.max) {\n errors.push(`\"${key}\" must be <= ${def.max}`);\n }\n } else if (def.type === 'string') {\n if (typeof value !== 'string') {\n errors.push(`\"${key}\" must be a string`);\n continue;\n }\n if (def.enum && !def.enum.includes(value)) {\n errors.push(`\"${key}\" must be one of: ${def.enum.join(', ')}`);\n }\n } else if (def.type === 'boolean') {\n if (typeof value !== 'boolean') {\n errors.push(`\"${key}\" must be a boolean`);\n }\n } else if (def.type === 'array') {\n if (!Array.isArray(value)) {\n errors.push(`\"${key}\" must be an array`);\n }\n } else if (def.type === 'object') {\n if (typeof value !== 'object' || Array.isArray(value)) {\n errors.push(`\"${key}\" must be an object`);\n }\n }\n }\n\n return errors.length > 0 ? { valid: false, errors } : { valid: true };\n }\n\n static number(value: unknown, opts?: { min?: number; max?: number }): boolean {\n if (typeof value !== 'number' || Number.isNaN(value)) return false;\n if (opts?.min !== undefined && value < opts.min) return false;\n if (opts?.max !== undefined && value > opts.max) return false;\n return true;\n }\n\n static string(value: unknown, opts?: { enum?: readonly string[] }): boolean {\n if (typeof value !== 'string') return false;\n if (opts?.enum && !opts.enum.includes(value)) return false;\n return true;\n }\n\n static positiveNumber(value: unknown): boolean {\n return SchemaValidator.number(value, { min: 0 });\n }\n\n static rate(value: unknown): boolean {\n return SchemaValidator.number(value, { min: 0, max: 1 });\n }\n}\n"],"mappings":"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","names":[]}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PPEPlugin, CalculationModel, PluginContext, EvaluationInput, Rule, EvaluationResult, PPEError, ValidationResult, DSLEvaluator } from '@run-iq/core';
|
|
1
|
+
import { PPEPlugin, CalculationModel, PluginContext, EvaluationInput, Rule, EvaluationResult, PPEError, ValidationResult, CalculationOutput, DSLEvaluator } from '@run-iq/core';
|
|
2
2
|
export { BreakdownItem, CalculationModel, DSLEvaluator, EvaluationInput, EvaluationResult, EvaluationTrace, Expression, ISnapshotAdapter, PPEPlugin, PluginContext, Rule, SkipReason, SkippedRule, Snapshot, TraceStep, ValidationResult } from '@run-iq/core';
|
|
3
3
|
|
|
4
4
|
declare abstract class BasePlugin implements PPEPlugin {
|
|
@@ -16,7 +16,7 @@ declare abstract class BaseModel implements CalculationModel {
|
|
|
16
16
|
abstract readonly name: string;
|
|
17
17
|
abstract readonly version: string;
|
|
18
18
|
abstract validateParams(params: unknown): ValidationResult;
|
|
19
|
-
abstract calculate(input: Record<string, unknown>, matchedRule: Readonly<Rule>, params: unknown): number;
|
|
19
|
+
abstract calculate(input: Record<string, unknown>, matchedRule: Readonly<Rule>, params: unknown): number | CalculationOutput;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
interface TestReport {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PPEPlugin, CalculationModel, PluginContext, EvaluationInput, Rule, EvaluationResult, PPEError, ValidationResult, DSLEvaluator } from '@run-iq/core';
|
|
1
|
+
import { PPEPlugin, CalculationModel, PluginContext, EvaluationInput, Rule, EvaluationResult, PPEError, ValidationResult, CalculationOutput, DSLEvaluator } from '@run-iq/core';
|
|
2
2
|
export { BreakdownItem, CalculationModel, DSLEvaluator, EvaluationInput, EvaluationResult, EvaluationTrace, Expression, ISnapshotAdapter, PPEPlugin, PluginContext, Rule, SkipReason, SkippedRule, Snapshot, TraceStep, ValidationResult } from '@run-iq/core';
|
|
3
3
|
|
|
4
4
|
declare abstract class BasePlugin implements PPEPlugin {
|
|
@@ -16,7 +16,7 @@ declare abstract class BaseModel implements CalculationModel {
|
|
|
16
16
|
abstract readonly name: string;
|
|
17
17
|
abstract readonly version: string;
|
|
18
18
|
abstract validateParams(params: unknown): ValidationResult;
|
|
19
|
-
abstract calculate(input: Record<string, unknown>, matchedRule: Readonly<Rule>, params: unknown): number;
|
|
19
|
+
abstract calculate(input: Record<string, unknown>, matchedRule: Readonly<Rule>, params: unknown): number | CalculationOutput;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
interface TestReport {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/base/BasePlugin.ts","../src/base/BaseModel.ts","../src/testing/PluginTester.ts","../src/validation/SchemaValidator.ts"],"sourcesContent":["import type {\n PPEPlugin,\n PluginContext,\n EvaluationInput,\n EvaluationResult,\n Rule,\n CalculationModel,\n PPEError,\n} from '@run-iq/core';\n\nexport abstract class BasePlugin implements PPEPlugin {\n abstract readonly name: string;\n abstract readonly version: string;\n abstract readonly models: CalculationModel[];\n\n onInit(context: PluginContext): void {\n for (const model of this.models) {\n context.modelRegistry.register(model);\n }\n }\n\n beforeEvaluate(input: EvaluationInput, _rules: ReadonlyArray<Rule>): EvaluationInput {\n return input;\n }\n\n afterEvaluate(_input: EvaluationInput, result: EvaluationResult): EvaluationResult {\n return result;\n }\n\n onError(_error: PPEError, _input: EvaluationInput): void {\n // no-op by default\n }\n\n teardown(): void {\n // no-op by default\n }\n}\n","import type { CalculationModel, ValidationResult, Rule } from '@run-iq/core';\n\nexport abstract class BaseModel implements CalculationModel {\n abstract readonly name: string;\n abstract readonly version: string;\n\n abstract validateParams(params: unknown): ValidationResult;\n\n abstract calculate(\n input: Record<string, unknown>,\n matchedRule: Readonly<Rule>,\n params: unknown,\n ): number;\n}\n","import type {\n PPEPlugin,\n PluginContext,\n EvaluationInput,\n Rule,\n CalculationModel,\n} from '@run-iq/core';\n\nexport interface TestReport {\n readonly passed: string[];\n readonly failed: Array<{ test: string; error: string }>;\n readonly summary: 'PASS' | 'FAIL';\n}\n\nexport class PluginTester {\n private readonly plugin: PPEPlugin;\n\n constructor(plugin: PPEPlugin) {\n this.plugin = plugin;\n }\n\n async assertDeterminism(\n input: EvaluationInput,\n rules: ReadonlyArray<Rule>,\n context: PluginContext,\n ): Promise<void> {\n this.plugin.onInit(context);\n\n const results: EvaluationInput[] = [];\n for (let i = 0; i < 3; i++) {\n if (this.plugin.beforeEvaluate) {\n results.push(this.plugin.beforeEvaluate(input, rules));\n }\n }\n\n if (results.length === 3) {\n const json0 = JSON.stringify(results[0]);\n const json1 = JSON.stringify(results[1]);\n const json2 = JSON.stringify(results[2]);\n if (json0 !== json1 || json1 !== json2) {\n throw new Error('Determinism violation: different results for same input');\n }\n }\n }\n\n async assertImmutability(input: EvaluationInput, rules: ReadonlyArray<Rule>): Promise<void> {\n const inputCopy = JSON.parse(JSON.stringify(input)) as EvaluationInput;\n const rulesCopy = JSON.parse(JSON.stringify(rules)) as Rule[];\n\n if (this.plugin.beforeEvaluate) {\n this.plugin.beforeEvaluate(input, rules);\n }\n\n if (JSON.stringify(input) !== JSON.stringify(inputCopy)) {\n throw new Error('Immutability violation: beforeEvaluate mutated input');\n }\n if (JSON.stringify(rules) !== JSON.stringify(rulesCopy)) {\n throw new Error('Immutability violation: beforeEvaluate mutated rules');\n }\n }\n\n async assertParamsValidation(\n modelName: string,\n invalidParams: unknown[],\n context: PluginContext,\n ): Promise<void> {\n this.plugin.onInit(context);\n\n const model = this.findModel(modelName, context);\n if (!model) {\n throw new Error(`Model \"${modelName}\" not found in plugin`);\n }\n\n for (const params of invalidParams) {\n const result = model.validateParams(params);\n if (result.valid) {\n throw new Error(\n `Expected model \"${modelName}\" to reject params: ${JSON.stringify(params)}`,\n );\n }\n }\n }\n\n async assertNoSideEffects(input: EvaluationInput, rules: ReadonlyArray<Rule>): Promise<void> {\n if (this.plugin.beforeEvaluate) {\n const r1 = this.plugin.beforeEvaluate(input, rules);\n const r2 = this.plugin.beforeEvaluate(input, rules);\n\n if (JSON.stringify(r1) !== JSON.stringify(r2)) {\n throw new Error('Side effects detected: different results between calls');\n }\n }\n }\n\n async runAll(\n input: EvaluationInput,\n rules: ReadonlyArray<Rule>,\n context: PluginContext,\n ): Promise<TestReport> {\n const passed: string[] = [];\n const failed: Array<{ test: string; error: string }> = [];\n\n const tests = [\n { name: 'determinism', fn: () => this.assertDeterminism(input, rules, context) },\n { name: 'immutability', fn: () => this.assertImmutability(input, rules) },\n { name: 'noSideEffects', fn: () => this.assertNoSideEffects(input, rules) },\n ];\n\n for (const t of tests) {\n try {\n await t.fn();\n passed.push(t.name);\n } catch (error) {\n failed.push({\n test: t.name,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n return {\n passed,\n failed,\n summary: failed.length === 0 ? 'PASS' : 'FAIL',\n };\n }\n\n private findModel(name: string, context: PluginContext): CalculationModel | undefined {\n try {\n return context.modelRegistry.get(name);\n } catch {\n return undefined;\n }\n }\n}\n","import type { ValidationResult } from '@run-iq/core';\n\nexport interface SchemaFieldDef {\n readonly type: 'number' | 'string' | 'boolean' | 'array' | 'object';\n readonly min?: number | undefined;\n readonly max?: number | undefined;\n readonly enum?: readonly string[] | undefined;\n readonly required?: boolean | undefined;\n}\n\nexport type SchemaDefinition = Record<string, SchemaFieldDef>;\n\nexport class SchemaValidator {\n static validate(params: unknown, schema: SchemaDefinition): ValidationResult {\n const errors: string[] = [];\n\n if (params === null || typeof params !== 'object') {\n return { valid: false, errors: ['params must be a non-null object'] };\n }\n\n const obj = params as Record<string, unknown>;\n\n for (const [key, def] of Object.entries(schema)) {\n const value = obj[key];\n const isRequired = def.required !== false;\n\n if (value === undefined || value === null) {\n if (isRequired) {\n errors.push(`\"${key}\" is required`);\n }\n continue;\n }\n\n if (def.type === 'number') {\n if (typeof value !== 'number' || Number.isNaN(value)) {\n errors.push(`\"${key}\" must be a number`);\n continue;\n }\n if (def.min !== undefined && value < def.min) {\n errors.push(`\"${key}\" must be >= ${def.min}`);\n }\n if (def.max !== undefined && value > def.max) {\n errors.push(`\"${key}\" must be <= ${def.max}`);\n }\n } else if (def.type === 'string') {\n if (typeof value !== 'string') {\n errors.push(`\"${key}\" must be a string`);\n continue;\n }\n if (def.enum && !def.enum.includes(value)) {\n errors.push(`\"${key}\" must be one of: ${def.enum.join(', ')}`);\n }\n } else if (def.type === 'boolean') {\n if (typeof value !== 'boolean') {\n errors.push(`\"${key}\" must be a boolean`);\n }\n } else if (def.type === 'array') {\n if (!Array.isArray(value)) {\n errors.push(`\"${key}\" must be an array`);\n }\n } else if (def.type === 'object') {\n if (typeof value !== 'object' || Array.isArray(value)) {\n errors.push(`\"${key}\" must be an object`);\n }\n }\n }\n\n return errors.length > 0 ? { valid: false, errors } : { valid: true };\n }\n\n static number(value: unknown, opts?: { min?: number; max?: number }): boolean {\n if (typeof value !== 'number' || Number.isNaN(value)) return false;\n if (opts?.min !== undefined && value < opts.min) return false;\n if (opts?.max !== undefined && value > opts.max) return false;\n return true;\n }\n\n static string(value: unknown, opts?: { enum?: readonly string[] }): boolean {\n if (typeof value !== 'string') return false;\n if (opts?.enum && !opts.enum.includes(value)) return false;\n return true;\n }\n\n static positiveNumber(value: unknown): boolean {\n return SchemaValidator.number(value, { min: 0 });\n }\n\n static rate(value: unknown): boolean {\n return SchemaValidator.number(value, { min: 0, max: 1 });\n }\n}\n"],"mappings":";AAUO,IAAe,aAAf,MAA+C;AAAA,EAKpD,OAAO,SAA8B;AACnC,eAAW,SAAS,KAAK,QAAQ;AAC/B,cAAQ,cAAc,SAAS,KAAK;AAAA,IACtC;AAAA,EACF;AAAA,EAEA,eAAe,OAAwB,QAA8C;AACnF,WAAO;AAAA,EACT;AAAA,EAEA,cAAc,QAAyB,QAA4C;AACjF,WAAO;AAAA,EACT;AAAA,EAEA,QAAQ,QAAkB,QAA+B;AAAA,EAEzD;AAAA,EAEA,WAAiB;AAAA,EAEjB;AACF;;;AClCO,IAAe,YAAf,MAAqD;AAW5D;;;ACCO,IAAM,eAAN,MAAmB;AAAA,EACP;AAAA,EAEjB,YAAY,QAAmB;AAC7B,SAAK,SAAS;AAAA,EAChB;AAAA,EAEA,MAAM,kBACJ,OACA,OACA,SACe;AACf,SAAK,OAAO,OAAO,OAAO;AAE1B,UAAM,UAA6B,CAAC;AACpC,aAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,UAAI,KAAK,OAAO,gBAAgB;AAC9B,gBAAQ,KAAK,KAAK,OAAO,eAAe,OAAO,KAAK,CAAC;AAAA,MACvD;AAAA,IACF;AAEA,QAAI,QAAQ,WAAW,GAAG;AACxB,YAAM,QAAQ,KAAK,UAAU,QAAQ,CAAC,CAAC;AACvC,YAAM,QAAQ,KAAK,UAAU,QAAQ,CAAC,CAAC;AACvC,YAAM,QAAQ,KAAK,UAAU,QAAQ,CAAC,CAAC;AACvC,UAAI,UAAU,SAAS,UAAU,OAAO;AACtC,cAAM,IAAI,MAAM,yDAAyD;AAAA,MAC3E;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,mBAAmB,OAAwB,OAA2C;AAC1F,UAAM,YAAY,KAAK,MAAM,KAAK,UAAU,KAAK,CAAC;AAClD,UAAM,YAAY,KAAK,MAAM,KAAK,UAAU,KAAK,CAAC;AAElD,QAAI,KAAK,OAAO,gBAAgB;AAC9B,WAAK,OAAO,eAAe,OAAO,KAAK;AAAA,IACzC;AAEA,QAAI,KAAK,UAAU,KAAK,MAAM,KAAK,UAAU,SAAS,GAAG;AACvD,YAAM,IAAI,MAAM,sDAAsD;AAAA,IACxE;AACA,QAAI,KAAK,UAAU,KAAK,MAAM,KAAK,UAAU,SAAS,GAAG;AACvD,YAAM,IAAI,MAAM,sDAAsD;AAAA,IACxE;AAAA,EACF;AAAA,EAEA,MAAM,uBACJ,WACA,eACA,SACe;AACf,SAAK,OAAO,OAAO,OAAO;AAE1B,UAAM,QAAQ,KAAK,UAAU,WAAW,OAAO;AAC/C,QAAI,CAAC,OAAO;AACV,YAAM,IAAI,MAAM,UAAU,SAAS,uBAAuB;AAAA,IAC5D;AAEA,eAAW,UAAU,eAAe;AAClC,YAAM,SAAS,MAAM,eAAe,MAAM;AAC1C,UAAI,OAAO,OAAO;AAChB,cAAM,IAAI;AAAA,UACR,mBAAmB,SAAS,uBAAuB,KAAK,UAAU,MAAM,CAAC;AAAA,QAC3E;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,oBAAoB,OAAwB,OAA2C;AAC3F,QAAI,KAAK,OAAO,gBAAgB;AAC9B,YAAM,KAAK,KAAK,OAAO,eAAe,OAAO,KAAK;AAClD,YAAM,KAAK,KAAK,OAAO,eAAe,OAAO,KAAK;AAElD,UAAI,KAAK,UAAU,EAAE,MAAM,KAAK,UAAU,EAAE,GAAG;AAC7C,cAAM,IAAI,MAAM,wDAAwD;AAAA,MAC1E;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,OACJ,OACA,OACA,SACqB;AACrB,UAAM,SAAmB,CAAC;AAC1B,UAAM,SAAiD,CAAC;AAExD,UAAM,QAAQ;AAAA,MACZ,EAAE,MAAM,eAAe,IAAI,MAAM,KAAK,kBAAkB,OAAO,OAAO,OAAO,EAAE;AAAA,MAC/E,EAAE,MAAM,gBAAgB,IAAI,MAAM,KAAK,mBAAmB,OAAO,KAAK,EAAE;AAAA,MACxE,EAAE,MAAM,iBAAiB,IAAI,MAAM,KAAK,oBAAoB,OAAO,KAAK,EAAE;AAAA,IAC5E;AAEA,eAAW,KAAK,OAAO;AACrB,UAAI;AACF,cAAM,EAAE,GAAG;AACX,eAAO,KAAK,EAAE,IAAI;AAAA,MACpB,SAAS,OAAO;AACd,eAAO,KAAK;AAAA,UACV,MAAM,EAAE;AAAA,UACR,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,QAC9D,CAAC;AAAA,MACH;AAAA,IACF;AAEA,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,SAAS,OAAO,WAAW,IAAI,SAAS;AAAA,IAC1C;AAAA,EACF;AAAA,EAEQ,UAAU,MAAc,SAAsD;AACpF,QAAI;AACF,aAAO,QAAQ,cAAc,IAAI,IAAI;AAAA,IACvC,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AACF;;;AC1HO,IAAM,kBAAN,MAAM,iBAAgB;AAAA,EAC3B,OAAO,SAAS,QAAiB,QAA4C;AAC3E,UAAM,SAAmB,CAAC;AAE1B,QAAI,WAAW,QAAQ,OAAO,WAAW,UAAU;AACjD,aAAO,EAAE,OAAO,OAAO,QAAQ,CAAC,kCAAkC,EAAE;AAAA,IACtE;AAEA,UAAM,MAAM;AAEZ,eAAW,CAAC,KAAK,GAAG,KAAK,OAAO,QAAQ,MAAM,GAAG;AAC/C,YAAM,QAAQ,IAAI,GAAG;AACrB,YAAM,aAAa,IAAI,aAAa;AAEpC,UAAI,UAAU,UAAa,UAAU,MAAM;AACzC,YAAI,YAAY;AACd,iBAAO,KAAK,IAAI,GAAG,eAAe;AAAA,QACpC;AACA;AAAA,MACF;AAEA,UAAI,IAAI,SAAS,UAAU;AACzB,YAAI,OAAO,UAAU,YAAY,OAAO,MAAM,KAAK,GAAG;AACpD,iBAAO,KAAK,IAAI,GAAG,oBAAoB;AACvC;AAAA,QACF;AACA,YAAI,IAAI,QAAQ,UAAa,QAAQ,IAAI,KAAK;AAC5C,iBAAO,KAAK,IAAI,GAAG,gBAAgB,IAAI,GAAG,EAAE;AAAA,QAC9C;AACA,YAAI,IAAI,QAAQ,UAAa,QAAQ,IAAI,KAAK;AAC5C,iBAAO,KAAK,IAAI,GAAG,gBAAgB,IAAI,GAAG,EAAE;AAAA,QAC9C;AAAA,MACF,WAAW,IAAI,SAAS,UAAU;AAChC,YAAI,OAAO,UAAU,UAAU;AAC7B,iBAAO,KAAK,IAAI,GAAG,oBAAoB;AACvC;AAAA,QACF;AACA,YAAI,IAAI,QAAQ,CAAC,IAAI,KAAK,SAAS,KAAK,GAAG;AACzC,iBAAO,KAAK,IAAI,GAAG,qBAAqB,IAAI,KAAK,KAAK,IAAI,CAAC,EAAE;AAAA,QAC/D;AAAA,MACF,WAAW,IAAI,SAAS,WAAW;AACjC,YAAI,OAAO,UAAU,WAAW;AAC9B,iBAAO,KAAK,IAAI,GAAG,qBAAqB;AAAA,QAC1C;AAAA,MACF,WAAW,IAAI,SAAS,SAAS;AAC/B,YAAI,CAAC,MAAM,QAAQ,KAAK,GAAG;AACzB,iBAAO,KAAK,IAAI,GAAG,oBAAoB;AAAA,QACzC;AAAA,MACF,WAAW,IAAI,SAAS,UAAU;AAChC,YAAI,OAAO,UAAU,YAAY,MAAM,QAAQ,KAAK,GAAG;AACrD,iBAAO,KAAK,IAAI,GAAG,qBAAqB;AAAA,QAC1C;AAAA,MACF;AAAA,IACF;AAEA,WAAO,OAAO,SAAS,IAAI,EAAE,OAAO,OAAO,OAAO,IAAI,EAAE,OAAO,KAAK;AAAA,EACtE;AAAA,EAEA,OAAO,OAAO,OAAgB,MAAgD;AAC5E,QAAI,OAAO,UAAU,YAAY,OAAO,MAAM,KAAK,EAAG,QAAO;AAC7D,QAAI,MAAM,QAAQ,UAAa,QAAQ,KAAK,IAAK,QAAO;AACxD,QAAI,MAAM,QAAQ,UAAa,QAAQ,KAAK,IAAK,QAAO;AACxD,WAAO;AAAA,EACT;AAAA,EAEA,OAAO,OAAO,OAAgB,MAA8C;AAC1E,QAAI,OAAO,UAAU,SAAU,QAAO;AACtC,QAAI,MAAM,QAAQ,CAAC,KAAK,KAAK,SAAS,KAAK,EAAG,QAAO;AACrD,WAAO;AAAA,EACT;AAAA,EAEA,OAAO,eAAe,OAAyB;AAC7C,WAAO,iBAAgB,OAAO,OAAO,EAAE,KAAK,EAAE,CAAC;AAAA,EACjD;AAAA,EAEA,OAAO,KAAK,OAAyB;AACnC,WAAO,iBAAgB,OAAO,OAAO,EAAE,KAAK,GAAG,KAAK,EAAE,CAAC;AAAA,EACzD;AACF;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/base/BasePlugin.ts","../src/base/BaseModel.ts","../src/testing/PluginTester.ts","../src/validation/SchemaValidator.ts"],"sourcesContent":["import type {\n PPEPlugin,\n PluginContext,\n EvaluationInput,\n EvaluationResult,\n Rule,\n CalculationModel,\n PPEError,\n} from '@run-iq/core';\n\nexport abstract class BasePlugin implements PPEPlugin {\n abstract readonly name: string;\n abstract readonly version: string;\n abstract readonly models: CalculationModel[];\n\n onInit(context: PluginContext): void {\n for (const model of this.models) {\n context.modelRegistry.register(model);\n }\n }\n\n beforeEvaluate(input: EvaluationInput, _rules: ReadonlyArray<Rule>): EvaluationInput {\n return input;\n }\n\n afterEvaluate(_input: EvaluationInput, result: EvaluationResult): EvaluationResult {\n return result;\n }\n\n onError(_error: PPEError, _input: EvaluationInput): void {\n // no-op by default\n }\n\n teardown(): void {\n // no-op by default\n }\n}\n","import type { CalculationModel, CalculationOutput, ValidationResult, Rule } from '@run-iq/core';\n\nexport abstract class BaseModel implements CalculationModel {\n abstract readonly name: string;\n abstract readonly version: string;\n\n abstract validateParams(params: unknown): ValidationResult;\n\n abstract calculate(\n input: Record<string, unknown>,\n matchedRule: Readonly<Rule>,\n params: unknown,\n ): number | CalculationOutput;\n}\n","import type {\n PPEPlugin,\n PluginContext,\n EvaluationInput,\n Rule,\n CalculationModel,\n} from '@run-iq/core';\n\nexport interface TestReport {\n readonly passed: string[];\n readonly failed: Array<{ test: string; error: string }>;\n readonly summary: 'PASS' | 'FAIL';\n}\n\nexport class PluginTester {\n private readonly plugin: PPEPlugin;\n\n constructor(plugin: PPEPlugin) {\n this.plugin = plugin;\n }\n\n async assertDeterminism(\n input: EvaluationInput,\n rules: ReadonlyArray<Rule>,\n context: PluginContext,\n ): Promise<void> {\n this.plugin.onInit(context);\n\n const results: EvaluationInput[] = [];\n for (let i = 0; i < 3; i++) {\n if (this.plugin.beforeEvaluate) {\n results.push(this.plugin.beforeEvaluate(input, rules));\n }\n }\n\n if (results.length === 3) {\n const json0 = JSON.stringify(results[0]);\n const json1 = JSON.stringify(results[1]);\n const json2 = JSON.stringify(results[2]);\n if (json0 !== json1 || json1 !== json2) {\n throw new Error('Determinism violation: different results for same input');\n }\n }\n }\n\n async assertImmutability(input: EvaluationInput, rules: ReadonlyArray<Rule>): Promise<void> {\n const inputCopy = JSON.parse(JSON.stringify(input)) as EvaluationInput;\n const rulesCopy = JSON.parse(JSON.stringify(rules)) as Rule[];\n\n if (this.plugin.beforeEvaluate) {\n this.plugin.beforeEvaluate(input, rules);\n }\n\n if (JSON.stringify(input) !== JSON.stringify(inputCopy)) {\n throw new Error('Immutability violation: beforeEvaluate mutated input');\n }\n if (JSON.stringify(rules) !== JSON.stringify(rulesCopy)) {\n throw new Error('Immutability violation: beforeEvaluate mutated rules');\n }\n }\n\n async assertParamsValidation(\n modelName: string,\n invalidParams: unknown[],\n context: PluginContext,\n ): Promise<void> {\n this.plugin.onInit(context);\n\n const model = this.findModel(modelName, context);\n if (!model) {\n throw new Error(`Model \"${modelName}\" not found in plugin`);\n }\n\n for (const params of invalidParams) {\n const result = model.validateParams(params);\n if (result.valid) {\n throw new Error(\n `Expected model \"${modelName}\" to reject params: ${JSON.stringify(params)}`,\n );\n }\n }\n }\n\n async assertNoSideEffects(input: EvaluationInput, rules: ReadonlyArray<Rule>): Promise<void> {\n if (this.plugin.beforeEvaluate) {\n const r1 = this.plugin.beforeEvaluate(input, rules);\n const r2 = this.plugin.beforeEvaluate(input, rules);\n\n if (JSON.stringify(r1) !== JSON.stringify(r2)) {\n throw new Error('Side effects detected: different results between calls');\n }\n }\n }\n\n async runAll(\n input: EvaluationInput,\n rules: ReadonlyArray<Rule>,\n context: PluginContext,\n ): Promise<TestReport> {\n const passed: string[] = [];\n const failed: Array<{ test: string; error: string }> = [];\n\n const tests = [\n { name: 'determinism', fn: () => this.assertDeterminism(input, rules, context) },\n { name: 'immutability', fn: () => this.assertImmutability(input, rules) },\n { name: 'noSideEffects', fn: () => this.assertNoSideEffects(input, rules) },\n ];\n\n for (const t of tests) {\n try {\n await t.fn();\n passed.push(t.name);\n } catch (error) {\n failed.push({\n test: t.name,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n return {\n passed,\n failed,\n summary: failed.length === 0 ? 'PASS' : 'FAIL',\n };\n }\n\n private findModel(name: string, context: PluginContext): CalculationModel | undefined {\n try {\n return context.modelRegistry.get(name);\n } catch {\n return undefined;\n }\n }\n}\n","import type { ValidationResult } from '@run-iq/core';\n\nexport interface SchemaFieldDef {\n readonly type: 'number' | 'string' | 'boolean' | 'array' | 'object';\n readonly min?: number | undefined;\n readonly max?: number | undefined;\n readonly enum?: readonly string[] | undefined;\n readonly required?: boolean | undefined;\n}\n\nexport type SchemaDefinition = Record<string, SchemaFieldDef>;\n\nexport class SchemaValidator {\n static validate(params: unknown, schema: SchemaDefinition): ValidationResult {\n const errors: string[] = [];\n\n if (params === null || typeof params !== 'object') {\n return { valid: false, errors: ['params must be a non-null object'] };\n }\n\n const obj = params as Record<string, unknown>;\n\n for (const [key, def] of Object.entries(schema)) {\n const value = obj[key];\n const isRequired = def.required !== false;\n\n if (value === undefined || value === null) {\n if (isRequired) {\n errors.push(`\"${key}\" is required`);\n }\n continue;\n }\n\n if (def.type === 'number') {\n if (typeof value !== 'number' || Number.isNaN(value)) {\n errors.push(`\"${key}\" must be a number`);\n continue;\n }\n if (def.min !== undefined && value < def.min) {\n errors.push(`\"${key}\" must be >= ${def.min}`);\n }\n if (def.max !== undefined && value > def.max) {\n errors.push(`\"${key}\" must be <= ${def.max}`);\n }\n } else if (def.type === 'string') {\n if (typeof value !== 'string') {\n errors.push(`\"${key}\" must be a string`);\n continue;\n }\n if (def.enum && !def.enum.includes(value)) {\n errors.push(`\"${key}\" must be one of: ${def.enum.join(', ')}`);\n }\n } else if (def.type === 'boolean') {\n if (typeof value !== 'boolean') {\n errors.push(`\"${key}\" must be a boolean`);\n }\n } else if (def.type === 'array') {\n if (!Array.isArray(value)) {\n errors.push(`\"${key}\" must be an array`);\n }\n } else if (def.type === 'object') {\n if (typeof value !== 'object' || Array.isArray(value)) {\n errors.push(`\"${key}\" must be an object`);\n }\n }\n }\n\n return errors.length > 0 ? { valid: false, errors } : { valid: true };\n }\n\n static number(value: unknown, opts?: { min?: number; max?: number }): boolean {\n if (typeof value !== 'number' || Number.isNaN(value)) return false;\n if (opts?.min !== undefined && value < opts.min) return false;\n if (opts?.max !== undefined && value > opts.max) return false;\n return true;\n }\n\n static string(value: unknown, opts?: { enum?: readonly string[] }): boolean {\n if (typeof value !== 'string') return false;\n if (opts?.enum && !opts.enum.includes(value)) return false;\n return true;\n }\n\n static positiveNumber(value: unknown): boolean {\n return SchemaValidator.number(value, { min: 0 });\n }\n\n static rate(value: unknown): boolean {\n return SchemaValidator.number(value, { min: 0, max: 1 });\n }\n}\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@run-iq/plugin-sdk",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "Plugin SDK for PPE — BasePlugin, BaseModel, PluginTester",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -18,7 +18,9 @@
|
|
|
18
18
|
}
|
|
19
19
|
}
|
|
20
20
|
},
|
|
21
|
-
"files": [
|
|
21
|
+
"files": [
|
|
22
|
+
"dist"
|
|
23
|
+
],
|
|
22
24
|
"scripts": {
|
|
23
25
|
"build": "tsup",
|
|
24
26
|
"test": "vitest run",
|
|
@@ -27,7 +29,7 @@
|
|
|
27
29
|
"lint:fix": "eslint src/ tests/ --fix && prettier --write src/ tests/"
|
|
28
30
|
},
|
|
29
31
|
"peerDependencies": {
|
|
30
|
-
"@run-iq/core": "^0.1.
|
|
32
|
+
"@run-iq/core": "^0.1.3"
|
|
31
33
|
},
|
|
32
34
|
"devDependencies": {
|
|
33
35
|
"@types/node": "^20.11.0",
|