@hot-updater/plugin-core
Version:
React Native OTA solution for self-hosted
395 lines (394 loc) • 14.1 kB
TypeScript
import { Bundle, Bundle as Bundle$1, Platform, Platform as Platform$1 } from "@hot-updater/core";
//#region src/log.d.ts
declare const log: {
normal: (message: string | number | null | undefined) => void;
success: (message: string | number | null | undefined) => void;
info: (message: string | number | null | undefined) => void;
error: (message: string | number | null | undefined) => void;
warn: (message: string | number | null | undefined) => void;
debug: (message: string | number | null | undefined) => void;
};
//#endregion
//#region src/cwd.d.ts
declare const getCwd: () => string;
//#endregion
//#region src/types/utils.d.ts
type Primitive = null | undefined | string | number | boolean | symbol | bigint;
type BuiltIns = Primitive | void | Date | RegExp;
type ExcludeUndefined<T> = Exclude<T, undefined>;
type HasMultipleCallSignatures<T extends (...arguments_: any[]) => unknown> = T extends {
(...arguments_: infer A): unknown;
(...arguments_: infer B): unknown;
} ? B extends A ? A extends B ? false : true : true : false;
type RequiredDeep<T, E extends ExcludeUndefined<T> = ExcludeUndefined<T>> = E extends BuiltIns ? E : E extends Map<infer KeyType, infer ValueType> ? Map<RequiredDeep<KeyType>, RequiredDeep<ValueType>> : E extends Set<infer ItemType> ? Set<RequiredDeep<ItemType>> : E extends ReadonlyMap<infer KeyType, infer ValueType> ? ReadonlyMap<RequiredDeep<KeyType>, RequiredDeep<ValueType>> : E extends ReadonlySet<infer ItemType> ? ReadonlySet<RequiredDeep<ItemType>> : E extends WeakMap<infer KeyType, infer ValueType> ? WeakMap<RequiredDeep<KeyType>, RequiredDeep<ValueType>> : E extends WeakSet<infer ItemType> ? WeakSet<RequiredDeep<ItemType>> : E extends Promise<infer ValueType> ? Promise<RequiredDeep<ValueType>> : E extends ((...arguments_: any[]) => unknown) ? {} extends RequiredObjectDeep<E> ? E : HasMultipleCallSignatures<E> extends true ? E : ((...arguments_: Parameters<E>) => ReturnType<E>) & RequiredObjectDeep<E> : E extends object ? E extends Array<infer ItemType> ? ItemType[] extends E ? Array<RequiredDeep<ItemType>> : RequiredObjectDeep<E> : RequiredObjectDeep<E> : unknown;
type RequiredObjectDeep<ObjectType extends object> = { [KeyType in keyof ObjectType]-?: RequiredDeep<ObjectType[KeyType]> };
//#endregion
//#region src/types/index.d.ts
interface BasePluginArgs {
cwd: string;
}
interface PaginationInfo {
total: number;
hasNextPage: boolean;
hasPreviousPage: boolean;
currentPage: number;
totalPages: number;
}
interface BuildPluginConfig {
outDir?: string;
}
interface DatabasePlugin {
getChannels: () => Promise<string[]>;
getBundleById: (bundleId: string) => Promise<Bundle$1 | null>;
getBundles: (options: {
where?: {
channel?: string;
platform?: string;
};
limit: number;
offset: number;
}) => Promise<{
data: Bundle$1[];
pagination: PaginationInfo;
}>;
updateBundle: (targetBundleId: string, newBundle: Partial<Bundle$1>) => Promise<void>;
appendBundle: (insertBundle: Bundle$1) => Promise<void>;
commitBundle: () => Promise<void>;
onUnmount?: () => Promise<void>;
name: string;
deleteBundle: (deleteBundle: Bundle$1) => Promise<void>;
}
interface DatabasePluginHooks {
onDatabaseUpdated?: () => Promise<void>;
}
interface BuildPlugin {
nativeBuild?: {
prebuild?: (args: {
platform: Platform$1;
}) => Promise<void>;
postbuild?: (args: {
platform: Platform$1;
}) => Promise<void>;
};
build: (args: {
platform: Platform$1;
}) => Promise<{
buildPath: string;
bundleId: string;
stdout: string | null;
}>;
name: string;
}
interface NativeBuildArgs {
/**
* Android specific configuration.
*/
android?: {
/**
* Android application module build variant.
*
* @example Debug, Release
* @default Release
*/
variant?: string;
/**
* Artifact type.
*
* If `true`, the generated artifact type is `.aab`.
* If `flase`, the generated artifact type is `apk`.
*
* @default true
*/
aab?: boolean;
/**
* Android application module name.
*
* @default app
*/
appModuleName?: string;
};
}
interface StoragePlugin {
uploadBundle: (bundleId: string, bundlePath: string) => Promise<{
storageUri: string;
}>;
deleteBundle: (bundleId: string) => Promise<{
storageUri: string;
}>;
name: string;
}
interface StoragePluginHooks {
onStorageUploaded?: () => Promise<void>;
}
type ConfigInput = {
/**
* The channel used when building the native app.
* Used to replace __HOT_UPDATER_CHANNEL at build time.
*
* @deprecated Use the `hot-updater channel create` command to create a channel.
*/
releaseChannel?: string;
/**
* The strategy used to update the app.
*
* If `fingerprint`, the bundle will be updated if the fingerprint of the app is changed.
* If `app-version`, the bundle will be updated if the target app version is valid.
*
* @default "fingerprint"
*/
updateStrategy?: "fingerprint" | "appVersion";
/**
* The fingerprint configuration.
*/
fingerprint?: {
/**
* The extra sources to be included in the fingerprint.
*/
extraSources?: string[];
/**
* The paths to be ignored in the fingerprint.
*/
ignorePaths?: string[];
/**
* When debug mode is enabled, more detailed information will be exposed in fingerprint.json.
*/
debug?: boolean;
};
console?: {
/**
* Git repository URL
* If git commit hash exists in console, it allows viewing commit history from the git repository
*/
gitUrl?: string;
/**
* Console port
* @default 1422
*/
port?: number;
};
nativeBuild?: NativeBuildArgs;
build: (args: BasePluginArgs) => Promise<BuildPlugin> | BuildPlugin;
storage: (args: BasePluginArgs) => Promise<StoragePlugin> | StoragePlugin;
database: (args: BasePluginArgs) => Promise<DatabasePlugin> | DatabasePlugin;
};
//#endregion
//#region src/loadConfig.d.ts
type HotUpdaterConfigOptions = {
platform: Platform;
channel: string;
} | null;
type ConfigResponse = RequiredDeep<ConfigInput>;
declare const loadConfig: (options: HotUpdaterConfigOptions) => Promise<ConfigResponse>;
declare const loadConfigSync: (options: HotUpdaterConfigOptions) => ConfigResponse;
//#endregion
//#region src/copyDirToTmp.d.ts
declare const copyDirToTmp: (dir: string, childDirname?: string) => Promise<{
tmpDir: string;
removeTmpDir: () => Promise<void>;
}>;
//#endregion
//#region src/createDatabasePlugin.d.ts
interface BaseDatabaseUtils {
cwd: string;
}
interface AbstractDatabasePlugin<TContext = object> {
getContext?: () => TContext;
getBundleById: (context: TContext, bundleId: string) => Promise<Bundle$1 | null>;
getBundles: (context: TContext, options: {
where?: {
channel?: string;
platform?: string;
};
limit: number;
offset: number;
}) => Promise<{
data: Bundle$1[];
pagination: PaginationInfo;
}>;
getChannels: (context: TContext) => Promise<string[]>;
onUnmount?: (context: TContext) => void;
commitBundle: (context: TContext, {
changedSets
}: {
changedSets: {
operation: "insert" | "update" | "delete";
data: Bundle$1;
}[];
}) => Promise<void>;
}
/**
* Creates a database plugin with the given implementation.
*
* @example
* ```ts
* const myDatabasePlugin = createDatabasePlugin("myDatabase", {
* getContext: () => ({
* // Your database client or connection
* dbClient: createDbClient()
* }),
* async getBundleById(context, bundleId) {
* // Implementation to get a bundle by ID using context.dbClient
* return bundle;
* },
* async getBundles(context, options) {
* // Implementation to get bundles with options using context.dbClient
* return bundles;
* },
* async getChannels(context) {
* // Implementation to get available channels using context.dbClient
* return channels;
* },
* async commitBundle(context, { changedSets }) {
* // Implementation to commit changed bundles using context.dbClient
* }
* });
* ```
*
* @param name - The name of the database plugin
* @param abstractPlugin - A plugin implementation with context support
* @param hooks - Optional hooks for plugin lifecycle events
* @returns A function that creates a database plugin instance
*/
declare function createDatabasePlugin<TContext = object>(name: string, abstractPlugin: AbstractDatabasePlugin<TContext>, hooks?: DatabasePluginHooks): (options: BasePluginArgs) => DatabasePlugin;
//#endregion
//#region src/banner.d.ts
declare const link: (url: string) => string;
declare const banner: (version?: string) => string;
declare const printBanner: (version?: string) => void;
//#endregion
//#region src/transformTemplate.d.ts
type ExtractPlaceholders<T extends string> = T extends `${infer _Start}%%${infer Key}%%${infer Rest}` ? Key | ExtractPlaceholders<Rest> : never;
type TransformTemplateArgs<T extends string> = { [Key in ExtractPlaceholders<T>]: string };
/**
* Replaces placeholders in the format %%key%% in a template string with values from the values object.
* Uses generic type T to automatically infer placeholder keys from the template string to ensure type safety.
*
* @example
* const str = "Hello %%name%%, you are %%age%% years old."
* const result = transformTemplate(str, { name: "John", age: "20" })
* // Result: "Hello John, you are 20 years old."
*/
declare function transformTemplate<T extends string>(templateString: T, values: TransformTemplateArgs<T>): string;
//#endregion
//#region src/transformEnv.d.ts
declare const transformEnv: <T extends Record<string, string>>(filename: string, env: T) => string;
//#endregion
//#region src/makeEnv.d.ts
type EnvVarValue = string | {
comment: string;
value: string;
};
declare const makeEnv: (newEnvVars: Record<string, EnvVarValue>, filePath?: string) => Promise<string>;
//#endregion
//#region src/createZip.d.ts
declare const createZipTargetFiles: ({
outfile,
targetFiles
}: {
targetFiles: {
path: string;
name: string;
}[];
outfile: string;
}) => Promise<string>;
declare const createZip: ({
outfile,
targetDir,
excludeExts
}: {
targetDir: string;
outfile: string;
excludeExts?: string[];
}) => Promise<string>;
//#endregion
//#region src/createBlobDatabasePlugin.d.ts
/**
*
* @param name - The name of the database plugin
* @param listObjects - Function to list objects in the storage
* @param loadObject - Function to load an JSON object from the storage
* @param uploadObject - Function to upload an JSON object to the storage
* @param deleteObject - Function to delete an object from the storage
* @param invalidatePaths - Function to invalidate paths in the CDN
* @param hooks - Optional hooks for additional functionality - see createDatabasePlugin
* @returns
*/
declare const createBlobDatabasePlugin: <TContext = object>({
name,
getContext,
listObjects,
loadObject,
uploadObject,
deleteObject,
invalidatePaths,
hooks,
apiBasePath
}: {
name: string;
getContext: () => TContext;
listObjects: (context: TContext, prefix: string) => Promise<string[]>;
loadObject: <T>(context: TContext, key: string) => Promise<T | null>;
uploadObject: <T>(context: TContext, key: string, data: T) => Promise<void>;
deleteObject: (context: TContext, key: string) => Promise<void>;
invalidatePaths: (context: TContext, paths: string[]) => Promise<void>;
hooks?: DatabasePluginHooks;
apiBasePath: string;
}) => (options: BasePluginArgs) => DatabasePlugin;
//#endregion
//#region src/ConfigBuilder.d.ts
type BuildType = "bare" | "rnef" | "expo";
type ImportInfo = {
pkg: string;
named?: string[];
defaultOrNamespace?: string;
sideEffect?: boolean;
};
type ProviderConfig = {
imports: ImportInfo[];
configString: string;
};
interface IConfigBuilder {
/** Sets the build type ('bare' or 'rnef' or 'expo') and adds necessary build imports. */
setBuildType(buildType: BuildType): this;
/** Sets the storage configuration and adds its required imports. */
setStorage(storageConfig: ProviderConfig): this;
/** Sets the database configuration and adds its required imports. */
setDatabase(databaseConfig: ProviderConfig): this;
/** Sets the intermediate code block to be placed between imports and defineConfig. */
setIntermediateCode(code: string): this;
/** Assembles and returns the final configuration string. */
getResult(): string;
}
declare class ConfigBuilder implements IConfigBuilder {
private buildType;
private storageInfo;
private databaseInfo;
private intermediateCode;
private collectedImports;
constructor();
addImport(info: ImportInfo): this;
private addImports;
private generateImportStatements;
private generateBuildConfigString;
setBuildType(buildType: BuildType): this;
setStorage(storageConfig: ProviderConfig): this;
setDatabase(databaseConfig: ProviderConfig): this;
setIntermediateCode(code: string): this;
getResult(): string;
}
//#endregion
//#region src/calculatePagination.d.ts
interface PaginationOptions {
limit: number;
offset: number;
}
interface PaginatedResult {
data: Bundle[];
pagination: PaginationInfo;
}
/**
* Calculate pagination information based on total count, limit, and offset
*/
declare function calculatePagination(total: number, options: PaginationOptions): PaginationInfo;
//#endregion
export { AbstractDatabasePlugin, BaseDatabaseUtils, BasePluginArgs, BuildPlugin, BuildPluginConfig, BuildType, BuiltIns, Bundle, ConfigBuilder, ConfigInput, ConfigResponse, DatabasePlugin, DatabasePluginHooks, HasMultipleCallSignatures, HotUpdaterConfigOptions, IConfigBuilder, ImportInfo, NativeBuildArgs, PaginatedResult, PaginationInfo, PaginationOptions, Platform, Primitive, ProviderConfig, RequiredDeep, StoragePlugin, StoragePluginHooks, banner, calculatePagination, copyDirToTmp, createBlobDatabasePlugin, createDatabasePlugin, createZip, createZipTargetFiles, getCwd, link, loadConfig, loadConfigSync, log, makeEnv, printBanner, transformEnv, transformTemplate };