@haibun/core
Advanced tools
Comparing version 1.31.4 to 1.31.7
@@ -1,1 +0,1 @@ | ||
export declare const currentVersion = "1.31.4"; | ||
export declare const currentVersion = "1.31.7"; |
@@ -1,2 +0,2 @@ | ||
export const currentVersion = '1.31.4'; | ||
export const currentVersion = '1.31.7'; | ||
//# sourceMappingURL=currentVersion.js.map |
@@ -39,2 +39,20 @@ import { Resolver } from '../phases/Resolver.js'; | ||
} | ||
export declare enum HANDLER_USAGE { | ||
EXCLUSIVE = "exclusive", | ||
FALLBACK = "fallback" | ||
} | ||
export interface IHandler { | ||
usage?: HANDLER_USAGE; | ||
handle: Function; | ||
} | ||
export interface ISourcedHandler extends IHandler { | ||
stepper: AStepper; | ||
} | ||
export type THandlers = { | ||
[handlesName: string]: IHandler; | ||
}; | ||
export interface IHasHandlers extends AStepper { | ||
handlers: THandlers; | ||
} | ||
export declare const isHasHandlers: (s: IHasHandlers) => s is IHasHandlers; | ||
export interface IHasBuilder { | ||
@@ -41,0 +59,0 @@ finalize: (workspace: WorkspaceContext) => void; |
import { currentVersion } from '../currentVersion.js'; | ||
export var HANDLER_USAGE; | ||
(function (HANDLER_USAGE) { | ||
HANDLER_USAGE["EXCLUSIVE"] = "exclusive"; | ||
HANDLER_USAGE["FALLBACK"] = "fallback"; | ||
})(HANDLER_USAGE || (HANDLER_USAGE = {})); | ||
export const isHasHandlers = (s) => s.handlers !== undefined; | ||
export class WorkspaceBuilder { | ||
@@ -3,0 +9,0 @@ name; |
@@ -10,2 +10,14 @@ import { TAnyFixme, TStepResult, TTag, TVStep } from '../defs.js'; | ||
}; | ||
export declare const SCHEMA_HISTORY_WITH_META: string; | ||
export type THistoryWithMeta = { | ||
'$schema': typeof SCHEMA_HISTORY_WITH_META; | ||
meta: { | ||
startTime: string; | ||
description: string; | ||
feature: string; | ||
startOffset: number; | ||
ok: boolean; | ||
}; | ||
logHistory: TLogHistory[]; | ||
}; | ||
export type TMessageContext = TArtifactMessageContext | TExecutorMessageContext | TTraceMessageContext | TBasicMessageContext; | ||
@@ -12,0 +24,0 @@ type TContextTopic = TArtifactRequestStepTopic | TArtifactFailureStepTopic | TExecutorResultTopic | TTraceTopic; |
@@ -1,2 +0,3 @@ | ||
export {}; | ||
import { versionedSchema } from '../defs.js'; | ||
export const SCHEMA_HISTORY_WITH_META = versionedSchema('HistoryWithMeta'); | ||
//# sourceMappingURL=logger.js.map |
import { WorldContext } from './contexts.js'; | ||
import Logger from './Logger.js'; | ||
import { run } from './run.js'; | ||
import { getOutputResult, getRunTag } from './util/index.js'; | ||
import { getRunTag } from './util/index.js'; | ||
import { getOutputResult } from './util/workspace-lib.js'; | ||
import { Timer } from './Timer.js'; | ||
@@ -6,0 +7,0 @@ export default async function runWithOptions(runOptions) { |
@@ -6,3 +6,4 @@ import { DEFAULT_DEST } from './defs.js'; | ||
import Builder from '../phases/Builder.js'; | ||
import { getSteppers, verifyExtraOptions, getRunTag, verifyRequiredOptions, createSteppers, setStepperWorlds } from './util/index.js'; | ||
import { verifyExtraOptions, getRunTag, verifyRequiredOptions, createSteppers, setStepperWorlds } from './util/index.js'; | ||
import { getSteppers } from './util/workspace-lib.js'; | ||
import { getDomains, verifyDomainsOrError } from './domain.js'; | ||
@@ -27,3 +28,3 @@ import { getFeaturesAndBackgrounds } from '../phases/collector.js'; | ||
} | ||
export async function runWith({ specl, world, features, backgrounds, addSteppers, endFeatureCallback }) { | ||
export async function runWith({ specl, world, features, backgrounds, addSteppers = [], endFeatureCallback }) { | ||
const { tag } = world; | ||
@@ -37,3 +38,3 @@ let result = undefined; | ||
const baseSteppers = await getSteppers(specl.steppers).catch((error) => errorBail('Steppers', error)); | ||
const csteppers = baseSteppers.concat(addSteppers); | ||
const csteppers = [...baseSteppers, ...addSteppers]; | ||
await verifyRequiredOptions(csteppers, world.extraOptions).catch((error) => errorBail('RequiredOptions', error)); | ||
@@ -40,0 +41,0 @@ await verifyExtraOptions(world.extraOptions, csteppers).catch((error) => errorBail('ExtraOptions', error)); |
import { DEFAULT_DEST } from '../defs.js'; | ||
import { Resolver } from '../../phases/Resolver.js'; | ||
import { DEF_PROTO_OPTIONS, runWith } from './../run.js'; | ||
import { getSteppers, getRunTag, verifyExtraOptions, getDefaultOptions, createSteppers } from './../util/index.js'; | ||
import { getRunTag, verifyExtraOptions, getDefaultOptions, createSteppers } from './../util/index.js'; | ||
import { getSteppers } from '../util/workspace-lib.js'; | ||
import { WorldContext } from '../contexts.js'; | ||
@@ -6,0 +7,0 @@ import { featureSplit, withNameType } from './../features.js'; |
@@ -1,12 +0,8 @@ | ||
/// <reference types="node" resolution-mode="require"/> | ||
import nodeFS from 'fs'; | ||
import { TNotOKActionResult, TOKActionResult, TExecutorResult, TSpecl, TWorld, TRuntime, TActionResultTopics, TActionResult, TFound, TTag, AStepper, TExtraOptions, CStepper, TTagValue, TFeatureResult, TBase } from '../defs.js'; | ||
import { TNotOKActionResult, TOKActionResult, TSpecl, TWorld, TRuntime, TActionResultTopics, TActionResult, TFound, TTag, AStepper, TExtraOptions, CStepper, TTagValue, TFeatureResult, ISourcedHandler } from '../defs.js'; | ||
type TClass = { | ||
new <T>(...args: unknown[]): T; | ||
}; | ||
export type TFileSystem = Partial<typeof nodeFS>; | ||
export declare const basesFrom: (s: any) => string[]; | ||
export declare function use(module: string): Promise<TClass>; | ||
export declare function checkModuleIsClass(re: object, module: string): void; | ||
export declare function getOutputResult(type: string | undefined, result: TExecutorResult): Promise<object | string>; | ||
export declare function actionNotOK(message: string, also?: { | ||
@@ -18,7 +14,4 @@ error?: Error; | ||
export declare function actionOK(topics?: TActionResultTopics): TOKActionResult; | ||
export declare function getStepper(s: string): Promise<CStepper>; | ||
export declare function createSteppers(steppers: CStepper[]): Promise<AStepper[]>; | ||
export declare function getSteppers(stepperNames: string[]): Promise<CStepper[]>; | ||
export declare function getDefaultOptions(): TSpecl; | ||
export declare function getConfigFromBase(bases: TBase, fs?: TFileSystem): TSpecl | null; | ||
export declare function getActionable(value: string): string; | ||
@@ -45,2 +38,3 @@ export declare function describeSteppers(steppers: AStepper[]): string; | ||
export declare function findStepper<Type>(steppers: AStepper[], name: string): Type; | ||
export declare function findHandlers<R extends ISourcedHandler>(steppers: AStepper[], handlerName: string): R[]; | ||
export declare function getFromRuntime<Type>(runtime: TRuntime, name: string): Type; | ||
@@ -47,0 +41,0 @@ export declare function applyResShouldContinue(world: TWorld, res: Partial<TActionResult>, vstep: TFound): boolean; |
@@ -1,4 +0,2 @@ | ||
import nodeFS from 'fs'; | ||
import path from 'path'; | ||
import { DEFAULT_DEST, } from '../defs.js'; | ||
import { DEFAULT_DEST, HANDLER_USAGE, } from '../defs.js'; | ||
import { Timer } from '../Timer.js'; | ||
@@ -25,14 +23,2 @@ export const basesFrom = (s) => s.split(',').map(b => b.trim()); | ||
} | ||
export async function getOutputResult(type, result) { | ||
if (type) { | ||
const loc = getModuleLocation(type); | ||
const AnOut = await use(loc); | ||
const out = new AnOut(); | ||
if (out) { | ||
const res = await out.writeOutput(result, {}); | ||
return res; | ||
} | ||
} | ||
return result; | ||
} | ||
export function actionNotOK(message, also) { | ||
@@ -48,13 +34,2 @@ return { | ||
} | ||
export async function getStepper(s) { | ||
try { | ||
const loc = getModuleLocation(s); | ||
const S = await use(loc); | ||
return S; | ||
} | ||
catch (e) { | ||
console.error(`could not use ${s}`); | ||
throw e; | ||
} | ||
} | ||
export async function createSteppers(steppers) { | ||
@@ -74,41 +49,2 @@ const allSteppers = []; | ||
} | ||
export async function getSteppers(stepperNames) { | ||
const steppers = []; | ||
for (const s of stepperNames) { | ||
try { | ||
const S = await getStepper(s); | ||
steppers.push(S); | ||
} | ||
catch (e) { | ||
console.error(`get ${s} from "${getModuleLocation(s)}" failed`, e); | ||
throw e; | ||
} | ||
} | ||
return steppers; | ||
} | ||
// workspaceRoot adapted from @nrwl/devkit | ||
const workspaceRoot = workspaceRootInner(process.cwd(), process.cwd()); | ||
function workspaceRootInner(dir, candidateRoot, fs = nodeFS) { | ||
if (path.dirname(dir) === dir) { | ||
return candidateRoot; | ||
} | ||
if (fs.existsSync(path.join(dir, 'nx.json'))) { | ||
return dir; | ||
} | ||
else if (fs.existsSync(path.join(dir, 'node_modules', 'nx', 'package.json'))) { | ||
return workspaceRootInner(path.dirname(dir), dir); | ||
} | ||
else { | ||
return workspaceRootInner(path.dirname(dir), candidateRoot); | ||
} | ||
} | ||
function getModuleLocation(name) { | ||
if (name.startsWith('~')) { | ||
return [workspaceRoot, 'node_modules', name.substr(1)].join('/'); | ||
} | ||
else if (name.match(/^[a-zA-Z].*/)) { | ||
return `../../steps/${name}`; | ||
} | ||
return path.resolve(process.cwd(), name); | ||
} | ||
export function getDefaultOptions() { | ||
@@ -121,22 +57,2 @@ return { | ||
} | ||
export function getConfigFromBase(bases, fs = nodeFS) { | ||
const found = bases.filter((b) => fs.existsSync(`${b}/config.json`)); | ||
if (found.length > 1) { | ||
console.error(`Found multiple config.json files: ${found.join(', ')}. Use --config to specify one.`); | ||
return null; | ||
} | ||
const configDir = found[0] || '.'; | ||
const f = `${configDir}/config.json`; | ||
console.info(`trying ${f}`); | ||
try { | ||
const specl = JSON.parse(fs.readFileSync(f, 'utf-8')); | ||
if (!specl.options) { | ||
specl.options = { DEST: DEFAULT_DEST }; | ||
} | ||
return specl; | ||
} | ||
catch (e) { | ||
return null; | ||
} | ||
} | ||
export function getActionable(value) { | ||
@@ -159,11 +75,11 @@ return value.replace(/#.*/, '').trim(); | ||
const extraOptions = { ...inExtraOptions }; | ||
Object.entries(extraOptions)?.map(([k, v]) => { | ||
const conc = getStepperOptionValue(k, v, csteppers); | ||
if (conc === undefined) { | ||
throw Error(`no option ${k} from ${JSON.stringify(extraOptions)}`); | ||
Object.entries(extraOptions)?.map(([option, value]) => { | ||
const foundStepper = getStepperOptionValue(option, value, csteppers); | ||
if (foundStepper === undefined) { | ||
throw Error(`unmapped option ${option} from ${JSON.stringify(extraOptions)}`); | ||
} | ||
delete extraOptions[k]; | ||
delete extraOptions[option]; | ||
}); | ||
if (Object.keys(extraOptions).length > 0) { | ||
throw Error(`no options provided for ${extraOptions}`); | ||
throw Error(`no option for ${extraOptions}`); | ||
} | ||
@@ -263,2 +179,33 @@ } | ||
} | ||
function isIHasHandlers(obj) { | ||
return obj && typeof obj.handlers === 'object'; | ||
} | ||
export function findHandlers(steppers, handlerName) { | ||
let sourcedHandlers = []; | ||
steppers.forEach(stepper => { | ||
if (isIHasHandlers(stepper)) { | ||
const handler = stepper.handlers[handlerName]; | ||
if (handler) { | ||
sourcedHandlers.push({ | ||
...handler, | ||
stepper: stepper | ||
}); | ||
} | ||
} | ||
}); | ||
const exclusiveHandlers = sourcedHandlers.filter(handler => handler.usage === HANDLER_USAGE.EXCLUSIVE); | ||
if (exclusiveHandlers.length > 0) { | ||
if (exclusiveHandlers.length > 1) { | ||
throw Error('multiple exclusive handlers'); | ||
} | ||
return exclusiveHandlers; | ||
} | ||
sourcedHandlers = sourcedHandlers.reduce((acc, item) => { | ||
if (item.usage !== 'fallback' || acc.length < 1) { | ||
acc.push(item); | ||
} | ||
return acc; | ||
}, []); | ||
return sourcedHandlers; | ||
} | ||
export function getFromRuntime(runtime, name) { | ||
@@ -265,0 +212,0 @@ return runtime[name]; |
import * as util from './index.js'; | ||
import * as TFileSystemJs from './workspace-lib.js'; | ||
import { HAIBUN_O_TESTSTEPSWITHOPTIONS_EXISTS, getDefaultWorld, testWithDefaults, getCreateSteppers, TEST_BASE } from '../test/lib.js'; | ||
@@ -6,3 +7,3 @@ import TestSteps from '../test/TestSteps.js'; | ||
import { withNameType } from '../features.js'; | ||
import { AStepper, OK } from '../defs.js'; | ||
import { AStepper, HANDLER_USAGE, OK } from '../defs.js'; | ||
describe('output', () => { | ||
@@ -16,3 +17,3 @@ it('OutputResult default', async () => { | ||
expect(result.ok).toBe(false); | ||
const output = await util.getOutputResult(undefined, result); | ||
const output = await TFileSystemJs.getOutputResult(undefined, result); | ||
expect(typeof output).toBe('object'); | ||
@@ -27,2 +28,74 @@ expect(result.featureResults?.length).toBe(2); | ||
}); | ||
describe('findHandlers', () => { | ||
const TEST_HANDLER = 'testHandler'; | ||
class TestStepper extends AStepper { | ||
// eslint-disable-next-line @typescript-eslint/ban-types | ||
steps; | ||
} | ||
it('finds handlers from classes that implement IHasHandler', () => { | ||
class TestStepperHandler extends TestStepper { | ||
handlers = { testHandler: { handle: () => undefined } }; | ||
} | ||
const found = util.findHandlers([new TestStepperHandler()], TEST_HANDLER); | ||
expect(found.length).toBe(1); | ||
expect(found[0].stepper.constructor.name).toBe('TestStepperHandler'); | ||
}); | ||
it(`does not find handlers from classes that don't implement IHasHandler`, () => { | ||
const found = util.findHandlers([new TestStepper()], TEST_HANDLER); | ||
expect(found.length).toBe(0); | ||
}); | ||
it(`finds exclusive handler`, () => { | ||
class ExclusiveTestStepperHandler extends TestStepper { | ||
handlers = { testHandler: { handle: () => undefined, usage: HANDLER_USAGE.EXCLUSIVE } }; | ||
} | ||
const found = util.findHandlers([new TestStepper(), new ExclusiveTestStepperHandler()], TEST_HANDLER); | ||
expect(found.length).toBe(1); | ||
expect(found[0].stepper.constructor.name).toBe('ExclusiveTestStepperHandler'); | ||
}); | ||
it(`throws error for duplicate exclusives`, () => { | ||
class ExclusiveTestStepperHandler extends TestStepper { | ||
handlers = { testHandler: { handle: () => undefined, usage: HANDLER_USAGE.EXCLUSIVE } }; | ||
} | ||
class ExclusiveTestStepperHandlerToo extends TestStepper { | ||
handlers = { testHandler: { handle: () => undefined, usage: HANDLER_USAGE.EXCLUSIVE } }; | ||
} | ||
expect(() => util.findHandlers([new TestStepper(), new ExclusiveTestStepperHandler(), new ExclusiveTestStepperHandlerToo()], TEST_HANDLER)).toThrow(); | ||
}); | ||
it(`removes fallback`, () => { | ||
class TestStepperHandler extends TestStepper { | ||
handlers = { testHandler: { handle: () => undefined, } }; | ||
} | ||
class FallbackTestStepperHandler extends TestStepper { | ||
handlers = { testHandler: { handle: () => undefined, usage: HANDLER_USAGE.FALLBACK } }; | ||
} | ||
const found = util.findHandlers([new TestStepperHandler(), new FallbackTestStepperHandler()], TEST_HANDLER); | ||
expect(found.length).toBe(1); | ||
expect(found[0].stepper.constructor.name).toBe('TestStepperHandler'); | ||
}); | ||
it(`keeps one fallback from mix pak`, () => { | ||
class TestStepperHandler extends TestStepper { | ||
handlers = { testHandler: { handle: () => undefined, } }; | ||
} | ||
class FallbackTestStepperHandler extends TestStepper { | ||
handlers = { testHandler: { handle: () => undefined, usage: HANDLER_USAGE.FALLBACK } }; | ||
} | ||
class FallbackTestStepperHandlerToo extends TestStepper { | ||
handlers = { testHandler: { handle: () => undefined, usage: HANDLER_USAGE.FALLBACK } }; | ||
} | ||
const found = util.findHandlers([new TestStepperHandler(), new FallbackTestStepperHandler(), new FallbackTestStepperHandlerToo()], TEST_HANDLER); | ||
expect(found.length).toBe(1); | ||
expect(found[0].stepper.constructor.name).toBe('TestStepperHandler'); | ||
}); | ||
it(`keeps first fallback from multiple fallbacks`, () => { | ||
class FallbackTestStepperHandler extends TestStepper { | ||
handlers = { testHandler: { handle: () => undefined, usage: HANDLER_USAGE.FALLBACK } }; | ||
} | ||
class FallbackTestStepperHandlerToo extends TestStepper { | ||
handlers = { testHandler: { handle: () => undefined, usage: HANDLER_USAGE.FALLBACK } }; | ||
} | ||
const found = util.findHandlers([new FallbackTestStepperHandler(), new FallbackTestStepperHandlerToo()], TEST_HANDLER); | ||
expect(found.length).toBe(1); | ||
expect(found[0].stepper.constructor.name).toBe('FallbackTestStepperHandler'); | ||
}); | ||
}); | ||
describe('findStepperFromOptions', () => { | ||
@@ -54,3 +127,3 @@ const TestOptionsStepper = class TestOptionsStepper extends AStepper { | ||
}); | ||
it.only('finds from last multiple options', async () => { | ||
it('finds from last multiple options', async () => { | ||
const ts = new TestOptionsStepper(); | ||
@@ -62,3 +135,3 @@ const steppers = await getCreateSteppers([], [TestOptionsStepper]); | ||
}); | ||
it.only('finds from first multiple options', async () => { | ||
it('finds from first multiple options', async () => { | ||
const ts = new TestOptionsStepper(); | ||
@@ -65,0 +138,0 @@ const steppers = await getCreateSteppers([], [TestOptionsStepper, TestSteps]); |
import { TBase, TFeature } from '../lib/defs.js'; | ||
import { TFileSystem } from '../lib/util/index.js'; | ||
import { TFileSystem } from '../lib/util/workspace-lib.js'; | ||
export type TFeaturesBackgrounds = { | ||
@@ -4,0 +4,0 @@ features: TFeature[]; |
@@ -43,3 +43,3 @@ import nodeFS from 'fs'; | ||
const isType = !type || file.endsWith(`.${type}`); | ||
const matchesFilter = featureFilter === undefined || featureFilter.length < 1 ? true : !!featureFilter.find((f) => file.replace(/\/.*?\/([^.*?/])/, '$1').match(f)); | ||
const matchesFilter = (featureFilter === undefined || featureFilter.every(f => f === '')) || featureFilter.length < 1 ? true : !!featureFilter.find((f) => file.replace(/\/.*?\/([^.*?/])/, '$1').match(f)); | ||
return isType && matchesFilter; | ||
@@ -46,0 +46,0 @@ } |
{ | ||
"name": "@haibun/core", | ||
"type": "module", | ||
"version": "1.31.4", | ||
"version": "1.31.7", | ||
"description": "", | ||
@@ -6,0 +6,0 @@ "author": "", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
324522
133
4506
5
1