baldrick-broth
Version:
Build automation tool and task runner
115 lines (99 loc) • 3.03 kB
text/typescript
import {getProperty} from 'dot-prop';
import {type AnyDataValue, type Ctx} from './build-model.js';
import {rootId} from './id-generator.js';
import {currentTaskLogger} from './logging.js';
export const createDataId = (memoryId: string, key: string) =>
`${memoryId}::${key}`;
export const setDataValue = (
memoryId: string,
ctx: Ctx,
key: string,
value: AnyDataValue | undefined
) => {
if (ctx.data === undefined) {
throw new Error('ctx.data should have defined by now');
}
if (value === undefined) {
delete ctx.data[`${memoryId}::${key}`];
} else {
ctx.data[`${memoryId}::${key}`] = value;
}
};
export const withMemoryPrefix = (memoryId: string) => (key: string) =>
key.startsWith(`${memoryId}::`);
export const splitDataKey = (dataKey: string): [string, string] => {
const [memoryId, key] = dataKey.split('::');
if (memoryId === undefined) {
throw new Error('MemoryId should not be undefined');
}
if (key === undefined) {
throw new Error('Key should not be undefined');
}
return [memoryId, key];
};
const getSpecificDataProperty = (
memoryId: string,
valuePath: string,
value?: Record<string, AnyDataValue>
): AnyDataValue | undefined => {
if (value === undefined) {
return undefined;
}
const [data_prefix, keyName] = valuePath.split('.');
if (
data_prefix === undefined ||
data_prefix !== 'data' ||
keyName === undefined
) {
currentTaskLogger.warn(
`getDataProperty: Invalid path ${valuePath}: ${data_prefix} and ${keyName}`
);
return undefined;
}
return value[`${memoryId}::${keyName}`];
};
const getDataProperty = (
memoryId: string,
valuePath: string,
value?: Record<string, AnyDataValue>
): AnyDataValue | undefined => {
const localValue = getSpecificDataProperty(memoryId, valuePath, value);
const useLocalValue = localValue !== undefined || memoryId === rootId;
if (useLocalValue) {
return localValue;
}
return getSpecificDataProperty(rootId, valuePath, value);
};
/**
* Return the current value or otherwise fallback to root value
*/
export const getSupportedProperty = (
memoryId: string,
ctx: Ctx,
valuePath: string
): AnyDataValue | undefined => {
const isInsideData = valuePath.startsWith('data.');
const value = isInsideData
? getDataProperty(memoryId, valuePath, ctx.data)
: getProperty(ctx, valuePath);
return typeof value === 'string' ||
typeof value === 'number' ||
typeof value === 'boolean' ||
typeof value === 'object'
? value
: undefined;
};
/**
* Check if the the value would generally considered false or empty
*/
export const isFalsy = (value: unknown): boolean =>
value === false ||
value === undefined ||
value === null ||
value === 0 ||
(typeof value === 'string' && value.trim().length === 0) ||
(Array.isArray(value) && value.length === 0);
/**
* Check if the the value would generally considered like having a value or true
*/
export const isTruthy = (value: unknown): boolean => !isFalsy(value);