Fix StartOS 0.4 TypeScript packaging to match SDK API

This commit is contained in:
MacPro
2026-04-09 15:10:44 -05:00
parent 68ec875ee7
commit 8298c083c7
3436 changed files with 867051 additions and 92 deletions
+182
View File
@@ -0,0 +1,182 @@
import { type X2jOptions, type XmlBuilderOptions } from 'fast-xml-parser';
import * as INI from 'ini';
import { z } from 'zod';
import * as T from '../../../base/lib/types';
import { PathBase } from './Volume';
/**
* Bidirectional transformers for converting between the raw file format and
* the application-level data type. Used with FileHelper factory methods.
*
* @typeParam Raw - The native type the file format parses to (e.g. `Record<string, unknown>` for JSON)
* @typeParam Transformed - The application-level type after transformation
*/
export type Transformers<Raw = unknown, Transformed = unknown, Validated extends Transformed = Transformed> = {
/** Transform raw parsed data into the application type */
onRead: (value: Raw) => Transformed;
/** Transform application data back into the raw format for writing */
onWrite: (value: Validated) => Raw;
};
type ToPath = string | {
base: PathBase;
subpath: string;
};
type Validator<_T, U> = z.ZodType<U>;
type ReadType<A> = {
once: () => Promise<A | null>;
const: (effects: T.Effects) => Promise<A | null>;
watch: (effects: T.Effects, abort?: AbortSignal) => AsyncGenerator<A | null, never, unknown>;
onChange: (effects: T.Effects, callback: (value: A | null, error?: Error) => {
cancel: boolean;
} | Promise<{
cancel: boolean;
}>) => void;
waitFor: (effects: T.Effects, pred: (value: A | null) => boolean) => Promise<A | null>;
};
/**
* @description Use this class to read/write an underlying configuration file belonging to the upstream service.
*
* These type definitions should reflect the underlying file as closely as possible. For example, if the service does not require a particular value, it should be marked as optional(), even if your package requires it.
*
* It is recommended to use onMismatch() whenever possible. This provides an escape hatch in case the user edits the file manually and accidentally sets a value to an unsupported type.
*
* Officially supported file types are json, yaml, and toml. Other files types can use "raw"
*
* Choose between officially supported file formats (), or a custom format (raw).
*
* @example
* Below are a few examples
*
* ```
* import { matches, FileHelper } from '@start9labs/start-sdk'
* const { arrayOf, boolean, literal, literals, object, natural, string } = matches
*
* export const jsonFile = FileHelper.json('./inputSpec.json', object({
* passwords: arrayOf(string).onMismatch([])
* type: literals('private', 'public').optional().onMismatch(undefined)
* }))
*
* export const tomlFile = FileHelper.toml('./inputSpec.toml', object({
* url: literal('https://start9.com').onMismatch('https://start9.com')
* public: boolean.onMismatch(true)
* }))
*
* export const yamlFile = FileHelper.yaml('./inputSpec.yml', object({
* name: string.optional().onMismatch(undefined)
* age: natural.optional().onMismatch(undefined)
* }))
*
* export const bitcoinConfFile = FileHelper.raw(
* './service.conf',
* (obj: CustomType) => customConvertObjToFormattedString(obj),
* (str) => customParseStringToTypedObj(str),
* )
* ```
*/
export declare class FileHelper<A> {
readonly path: string;
readonly writeData: (dataIn: A) => string;
readonly readData: (stringValue: string) => unknown;
readonly validate: (value: unknown) => A;
private consts;
protected constructor(path: string, writeData: (dataIn: A) => string, readData: (stringValue: string) => unknown, validate: (value: unknown) => A);
private writeFileRaw;
/**
* Accepts structured data and overwrites the existing file on disk.
*/
private writeFile;
private readFileRaw;
private readFile;
/**
* Reads the file from disk and converts it to structured data.
*/
private readOnce;
private createFileWatchable;
/**
* Create a reactive reader for this file.
*
* Returns an object with multiple read strategies:
* - `once()` - Read the file once and return the parsed value
* - `const(effects)` - Read once but re-read when the file changes (for use with constRetry)
* - `watch(effects)` - Async generator yielding new values on each file change
* - `onChange(effects, callback)` - Fire a callback on each file change
* - `waitFor(effects, predicate)` - Block until the file value satisfies a predicate
*
* @param map - Optional transform function applied after validation
* @param eq - Optional equality function to deduplicate watch emissions
*/
read(): ReadType<A>;
read<B>(map: (value: A) => B, eq?: (left: B | null, right: B | null) => boolean): ReadType<B>;
/**
* Accepts full structured data and overwrites the existing file on disk if it exists.
*/
write(effects: T.Effects, data: T.AllowReadonly<A> | A, options?: {
allowWriteAfterConst?: boolean;
}): Promise<null>;
/**
* Accepts partial structured data and performs a merge with the existing file on disk.
*/
merge(effects: T.Effects, data: T.AllowReadonly<T.DeepPartial<A>>, options?: {
allowWriteAfterConst?: boolean;
}): Promise<null>;
/**
* We wanted to be able to have a fileHelper, and just modify the path later in time.
* Like one behavior of another dependency or something similar.
*/
withPath(path: ToPath): FileHelper<A>;
/**
* Create a File Helper for an arbitrary file type.
*
* Provide custom functions for translating data to/from the file format.
*/
static raw<A>(path: ToPath, toFile: (dataIn: A) => string, fromFile: (rawData: string) => unknown, validate: (data: unknown) => A): FileHelper<A>;
private static rawTransformed;
/**
* Create a File Helper for a text file
*/
static string(path: ToPath): FileHelper<string>;
static string<A extends string>(path: ToPath, shape: Validator<string, A>): FileHelper<A>;
static string<A extends Transformed, Transformed = string>(path: ToPath, shape: Validator<Transformed, A>, transformers: Transformers<string, Transformed, A>): FileHelper<A>;
/**
* Create a File Helper for a .json file.
*/
static json<A>(path: ToPath, shape: Validator<unknown, A>): FileHelper<A>;
static json<A extends Transformed, Transformed = unknown>(path: ToPath, shape: Validator<unknown, A>, transformers: Transformers<unknown, Transformed, A>): FileHelper<A>;
/**
* Create a File Helper for a .yaml file
*/
static yaml<A extends Record<string, unknown>>(path: ToPath, shape: Validator<Record<string, unknown>, A>): FileHelper<A>;
static yaml<A extends Transformed, Transformed = Record<string, unknown>>(path: ToPath, shape: Validator<Transformed, A>, transformers: Transformers<Record<string, unknown>, Transformed, A>): FileHelper<A>;
/**
* Create a File Helper for a .toml file
*/
static toml<A extends Record<string, unknown>>(path: ToPath, shape: Validator<Record<string, unknown>, A>): FileHelper<A>;
static toml<A extends Transformed, Transformed = Record<string, unknown>>(path: ToPath, shape: Validator<Transformed, A>, transformers: Transformers<Record<string, unknown>, Transformed, A>): FileHelper<A>;
/**
* Create a File Helper for a .ini file.
*
* Supports optional encode/decode options and custom transformers.
*/
static ini<A extends Record<string, unknown>>(path: ToPath, shape: Validator<Record<string, unknown>, A>, options?: INI.EncodeOptions & INI.DecodeOptions): FileHelper<A>;
static ini<A extends Transformed, Transformed = Record<string, unknown>>(path: ToPath, shape: Validator<Transformed, A>, options: INI.EncodeOptions & INI.DecodeOptions, transformers: Transformers<Record<string, unknown>, Transformed, A>): FileHelper<A>;
/**
* Create a File Helper for a .env file (KEY=VALUE format, one per line).
*
* Lines starting with `#` are treated as comments and ignored on read.
*/
static env<A extends Record<string, string>>(path: ToPath, shape: Validator<Record<string, string>, A>): FileHelper<A>;
static env<A extends Transformed, Transformed = Record<string, string>>(path: ToPath, shape: Validator<Transformed, A>, transformers: Transformers<Record<string, string>, Transformed, A>): FileHelper<A>;
/**
* Create a File Helper for an .xml file.
*
* Supports optional parser/builder options from `fast-xml-parser`.
*/
static xml<A extends Record<string, unknown>>(path: ToPath, shape: Validator<Record<string, unknown>, A>, options?: {
parser?: X2jOptions;
builder?: XmlBuilderOptions;
}): FileHelper<A>;
static xml<A extends Transformed, Transformed = Record<string, unknown>>(path: ToPath, shape: Validator<Transformed, A>, options: {
parser?: X2jOptions;
builder?: XmlBuilderOptions;
}, transformers: Transformers<Record<string, unknown>, Transformed, A>): FileHelper<A>;
}
export default FileHelper;