Problem: the hexagonal refactor churns the backend tree for nine more phases; the UI delivery stack (web/ SPA, cmd/desktop Wails wrapper, compose/web image) must move to its own repo first so doc/layout rewrites land once on a backend-only tree. Change: - New repo git.hubris.network/dtoro/oikos-web (v0.33.0): web/, desktop/ (updateURL repointed to oikos-web releases), compose/, own CI (web + desktop jobs), own deploy script (CI-green gate, TOCTOU guard, version-tagged images, prune-to-3), own webhook receiver on :9798 + launchd unit, own compose project publishing the same 8091:80. - Cutover executed on mac-mini in order: oikos stack's web service stopped+removed, oikos-web project brought up on 8091; outer Caddy untouched (targets the published port) — serving + Authentik flow + /wails 404 quirk verified post-cutover. - Stripped from oikos: web/, cmd/desktop/, compose/web/, desktop CI workflow, ci.yml web job, Makefile ui/desktop/desktop-package/install targets, the compose web service, oikos-web from deploy.sh's fallback prune list; wails + go-keyring dropped from go.mod, vendor synced. - README / CONTRIBUTING / AGENTS.md / .agents dev+operations docs now point at the new repo; mbse + mascot design docs carry a path note. Risk: production SPA serving depends on the new pipeline now; rollback is versioned-image re-up of the old web service from a pre-split checkout (port 8091). Desktop builds installed before the split still check dtoro/oikos releases — one manual reinstall, noted in the oikos-web release notes. Verification: go vet, make test (race), make generate-check, golangci (no new findings; baseline down 400→365); post-cutover curls — localhost:8091 200, /wails/runtime.js 404, outer Caddy 302 Authentik.
155 lines
5.0 KiB
TypeScript
155 lines
5.0 KiB
TypeScript
/// <reference types="node" />
|
|
import * as nativeFs from "fs";
|
|
import picomatch from "picomatch";
|
|
|
|
//#region src/api/aborter.d.ts
|
|
/**
|
|
* AbortController is not supported on Node 14 so we use this until we can drop
|
|
* support for Node 14.
|
|
*/
|
|
declare class Aborter {
|
|
aborted: boolean;
|
|
abort(): void;
|
|
}
|
|
//#endregion
|
|
//#region src/api/queue.d.ts
|
|
type OnQueueEmptyCallback = (error: Error | null, output: WalkerState) => void;
|
|
/**
|
|
* This is a custom stateless queue to track concurrent async fs calls.
|
|
* It increments a counter whenever a call is queued and decrements it
|
|
* as soon as it completes. When the counter hits 0, it calls onQueueEmpty.
|
|
*/
|
|
declare class Queue {
|
|
private onQueueEmpty?;
|
|
count: number;
|
|
constructor(onQueueEmpty?: OnQueueEmptyCallback | undefined);
|
|
enqueue(): number;
|
|
dequeue(error: Error | null, output: WalkerState): void;
|
|
}
|
|
//#endregion
|
|
//#region src/types.d.ts
|
|
type Counts = {
|
|
files: number;
|
|
directories: number;
|
|
/**
|
|
* @deprecated use `directories` instead. Will be removed in v7.0.
|
|
*/
|
|
dirs: number;
|
|
};
|
|
type Group = {
|
|
directory: string;
|
|
files: string[];
|
|
/**
|
|
* @deprecated use `directory` instead. Will be removed in v7.0.
|
|
*/
|
|
dir: string;
|
|
};
|
|
type GroupOutput = Group[];
|
|
type OnlyCountsOutput = Counts;
|
|
type PathsOutput = string[];
|
|
type Output = OnlyCountsOutput | PathsOutput | GroupOutput;
|
|
type FSLike = {
|
|
readdir: typeof nativeFs.readdir;
|
|
readdirSync: typeof nativeFs.readdirSync;
|
|
realpath: typeof nativeFs.realpath;
|
|
realpathSync: typeof nativeFs.realpathSync;
|
|
stat: typeof nativeFs.stat;
|
|
statSync: typeof nativeFs.statSync;
|
|
};
|
|
type WalkerState = {
|
|
root: string;
|
|
paths: string[];
|
|
groups: Group[];
|
|
counts: Counts;
|
|
options: Options;
|
|
queue: Queue;
|
|
controller: Aborter;
|
|
fs: FSLike;
|
|
symlinks: Map<string, string>;
|
|
visited: string[];
|
|
};
|
|
type ResultCallback<TOutput extends Output> = (error: Error | null, output: TOutput) => void;
|
|
type FilterPredicate = (path: string, isDirectory: boolean) => boolean;
|
|
type ExcludePredicate = (dirName: string, dirPath: string) => boolean;
|
|
type PathSeparator = "/" | "\\";
|
|
type Options<TGlobFunction = unknown> = {
|
|
includeBasePath?: boolean;
|
|
includeDirs?: boolean;
|
|
normalizePath?: boolean;
|
|
maxDepth: number;
|
|
maxFiles?: number;
|
|
resolvePaths?: boolean;
|
|
suppressErrors: boolean;
|
|
group?: boolean;
|
|
onlyCounts?: boolean;
|
|
filters: FilterPredicate[];
|
|
resolveSymlinks?: boolean;
|
|
useRealPaths?: boolean;
|
|
excludeFiles?: boolean;
|
|
excludeSymlinks?: boolean;
|
|
exclude?: ExcludePredicate;
|
|
relativePaths?: boolean;
|
|
pathSeparator: PathSeparator;
|
|
signal?: AbortSignal;
|
|
globFunction?: TGlobFunction;
|
|
fs?: FSLike;
|
|
};
|
|
type GlobMatcher = (test: string) => boolean;
|
|
type GlobFunction = (glob: string | string[], ...params: unknown[]) => GlobMatcher;
|
|
type GlobParams<T> = T extends ((globs: string | string[], ...params: infer TParams extends unknown[]) => GlobMatcher) ? TParams : [];
|
|
//#endregion
|
|
//#region src/builder/api-builder.d.ts
|
|
declare class APIBuilder<TReturnType extends Output> {
|
|
private readonly root;
|
|
private readonly options;
|
|
constructor(root: string, options: Options);
|
|
withPromise(): Promise<TReturnType>;
|
|
withCallback(cb: ResultCallback<TReturnType>): void;
|
|
sync(): TReturnType;
|
|
}
|
|
//#endregion
|
|
//#region src/builder/index.d.ts
|
|
declare class Builder<TReturnType extends Output = PathsOutput, TGlobFunction = typeof picomatch> {
|
|
private readonly globCache;
|
|
private options;
|
|
private globFunction?;
|
|
constructor(options?: Partial<Options<TGlobFunction>>);
|
|
group(): Builder<GroupOutput, TGlobFunction>;
|
|
withPathSeparator(separator: "/" | "\\"): this;
|
|
withBasePath(): this;
|
|
withRelativePaths(): this;
|
|
withDirs(): this;
|
|
withMaxDepth(depth: number): this;
|
|
withMaxFiles(limit: number): this;
|
|
withFullPaths(): this;
|
|
withErrors(): this;
|
|
withSymlinks({
|
|
resolvePaths
|
|
}?: {
|
|
resolvePaths?: boolean | undefined;
|
|
}): this;
|
|
withAbortSignal(signal: AbortSignal): this;
|
|
normalize(): this;
|
|
filter(predicate: FilterPredicate): this;
|
|
onlyDirs(): this;
|
|
exclude(predicate: ExcludePredicate): this;
|
|
onlyCounts(): Builder<OnlyCountsOutput, TGlobFunction>;
|
|
crawl(root?: string): APIBuilder<TReturnType>;
|
|
withGlobFunction<TFunc>(fn: TFunc): Builder<TReturnType, TFunc>;
|
|
/**
|
|
* @deprecated Pass options using the constructor instead:
|
|
* ```ts
|
|
* new fdir(options).crawl("/path/to/root");
|
|
* ```
|
|
* This method will be removed in v7.0
|
|
*/
|
|
crawlWithOptions(root: string, options: Partial<Options<TGlobFunction>>): APIBuilder<TReturnType>;
|
|
glob(...patterns: string[]): Builder<TReturnType, TGlobFunction>;
|
|
globWithOptions(patterns: string[]): Builder<TReturnType, TGlobFunction>;
|
|
globWithOptions(patterns: string[], ...options: GlobParams<TGlobFunction>): Builder<TReturnType, TGlobFunction>;
|
|
}
|
|
//#endregion
|
|
//#region src/index.d.ts
|
|
type Fdir = typeof Builder;
|
|
//#endregion
|
|
export { Counts, ExcludePredicate, FSLike, Fdir, FilterPredicate, GlobFunction, GlobMatcher, GlobParams, Group, GroupOutput, OnlyCountsOutput, Options, Output, PathSeparator, PathsOutput, ResultCallback, WalkerState, Builder as fdir }; |