@kubb/core 4.28.0 → 4.29.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-C1_xRkKa.cjs → chunk-CNbaEX1y.cjs} +1 -1
- package/dist/{chunk-iVr_oF3V.js → chunk-DKWOrOAv.js} +1 -1
- package/dist/fs.cjs +8 -7
- package/dist/fs.d.ts +1 -1
- package/dist/fs.js +1 -1
- package/dist/{getBarrelFiles-gRyVPFBP.js → getBarrelFiles-BBDOJ2lV.js} +20 -20
- package/dist/getBarrelFiles-BBDOJ2lV.js.map +1 -0
- package/dist/{getBarrelFiles-DCNjiX2W.cjs → getBarrelFiles-BttXy8Sp.cjs} +22 -28
- package/dist/getBarrelFiles-BttXy8Sp.cjs.map +1 -0
- package/dist/{getBarrelFiles-CHL9_Obd.d.ts → getBarrelFiles-C7gz90HF.d.ts} +5 -8
- package/dist/{getBarrelFiles-CmpI3rrq.d.cts → getBarrelFiles-DAhlPFXC.d.ts} +5 -8
- package/dist/hooks.cjs +2 -1
- package/dist/hooks.cjs.map +1 -1
- package/dist/hooks.d.ts +2 -2
- package/dist/hooks.js +1 -1
- package/dist/index.cjs +33 -211
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +5 -8
- package/dist/index.js +26 -202
- package/dist/index.js.map +1 -1
- package/dist/{transformers-B8kXgG3q.cjs → toRegExp-DGgAWZ_m.cjs} +15 -117
- package/dist/toRegExp-DGgAWZ_m.cjs.map +1 -0
- package/dist/{transformers-8ju9ixkG.js → toRegExp-DdJ1Kgbf.js} +16 -112
- package/dist/toRegExp-DdJ1Kgbf.js.map +1 -0
- package/dist/transformers.cjs +45 -36
- package/dist/transformers.cjs.map +1 -0
- package/dist/transformers.d.ts +2 -6
- package/dist/transformers.js +26 -2
- package/dist/transformers.js.map +1 -0
- package/dist/{types-Cn3Gwsf3.d.ts → types-CiePC9Y3.d.ts} +6 -11
- package/dist/{types-ulibr7zw.d.cts → types-Ciz0gIX7.d.ts} +6 -11
- package/dist/utils.cjs +36 -20
- package/dist/utils.cjs.map +1 -1
- package/dist/utils.d.ts +8 -5
- package/dist/utils.js +34 -20
- package/dist/utils.js.map +1 -1
- package/dist/write-CwpeNfTd.cjs +108 -0
- package/dist/write-CwpeNfTd.cjs.map +1 -0
- package/dist/write-DiGboRXI.js +72 -0
- package/dist/write-DiGboRXI.js.map +1 -0
- package/package.json +22 -27
- package/src/PackageManager.ts +3 -3
- package/src/fs/clean.ts +2 -2
- package/src/fs/exists.ts +10 -30
- package/src/fs/read.ts +7 -30
- package/src/fs/write.ts +38 -55
- package/src/transformers/casing.ts +22 -4
- package/src/transformers/index.ts +0 -7
- package/src/utils/FunctionParams.ts +5 -18
- package/src/utils/formatters.ts +2 -2
- package/src/utils/index.ts +1 -0
- package/src/utils/linters.ts +2 -2
- package/src/utils/tokenize.ts +23 -0
- package/dist/fs-Parec-wn.js +0 -105
- package/dist/fs-Parec-wn.js.map +0 -1
- package/dist/fs-jxNCXQUq.cjs +0 -141
- package/dist/fs-jxNCXQUq.cjs.map +0 -1
- package/dist/fs.d.cts +0 -23
- package/dist/getBarrelFiles-DCNjiX2W.cjs.map +0 -1
- package/dist/getBarrelFiles-gRyVPFBP.js.map +0 -1
- package/dist/hooks.d.cts +0 -15
- package/dist/index.d.cts +0 -119
- package/dist/transformers-8ju9ixkG.js.map +0 -1
- package/dist/transformers-B8kXgG3q.cjs.map +0 -1
- package/dist/transformers.d.cts +0 -112
- package/dist/utils.d.cts +0 -287
package/dist/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","names":["#buffer","#items","#orderItems","#addParams","item","timeout"],"sources":["../src/utils/buildJSDoc.ts","../src/utils/Cache.ts","../src/utils/checkOnlineStatus.ts","../src/utils/FunctionParams.ts","../src/utils/formatters.ts","../src/utils/getPlugins.ts","../src/utils/promise.ts","../src/utils/getConfigs.ts","../src/utils/getNestedAccessor.ts","../src/utils/linters.ts","../src/utils/renderTemplate.ts","../src/utils/serializePluginOptions.ts","../src/utils/timeout.ts"],"sourcesContent":["/**\n * Builds a JSDoc comment block with custom indentation.\n * @param comments - Array of comment strings to include in the JSDoc block\n * @param options - Configuration options for formatting\n * @returns Formatted JSDoc string or fallback string if no comments\n */\nexport function buildJSDoc(\n comments: Array<string>,\n options: {\n /**\n * String to use for indenting each line of the JSDoc comment\n * @default ' * ' (3 spaces + asterisk + space)\n */\n indent?: string\n /**\n * String to append after the closing JSDoc tag\n * @default '\\n ' (newline + 2 spaces)\n */\n suffix?: string\n /**\n * String to return when there are no comments\n * @default ' ' (2 spaces)\n */\n fallback?: string\n } = {},\n): string {\n const { indent = ' * ', suffix = '\\n ', fallback = ' ' } = options\n\n if (comments.length === 0) {\n return fallback\n }\n\n return `/**\\n${comments.map((c) => `${indent}${c}`).join('\\n')}\\n */${suffix}`\n}\n","export class Cache<T> {\n #buffer = new Map<string, T>()\n\n async get(key: string): Promise<T | null> {\n return this.#buffer.get(key) ?? null\n }\n\n async set(key: string, value: T): Promise<void> {\n this.#buffer.set(key, value)\n }\n\n async delete(key: string): Promise<void> {\n this.#buffer.delete(key)\n }\n\n async clear(): Promise<void> {\n this.#buffer.clear()\n }\n\n async keys(): Promise<string[]> {\n return [...this.#buffer.keys()]\n }\n\n async values(): Promise<T[]> {\n return [...this.#buffer.values()]\n }\n\n async flush(): Promise<void> {\n // No-op for base cache\n }\n}\n","import dns from 'node:dns'\n\n/**\n * Check if the system has internet connectivity\n * Uses DNS lookup to well-known stable domains as a lightweight connectivity test\n */\nexport async function isOnline(): Promise<boolean> {\n const testDomains = [\n 'dns.google.com', // Google Public DNS\n 'cloudflare.com', // Cloudflare\n 'one.one.one.one', // Cloudflare DNS\n ]\n\n for (const domain of testDomains) {\n try {\n await dns.promises.resolve(domain)\n return true\n } catch {\n // Try next domain\n }\n }\n\n return false\n}\n\n/**\n * Execute a function only if online, otherwise silently skip\n */\nexport async function executeIfOnline<T>(fn: () => Promise<T>): Promise<T | null> {\n const online = await isOnline()\n if (!online) {\n return null\n }\n\n try {\n return await fn()\n } catch {\n return null\n }\n}\n","import { orderBy } from 'natural-orderby'\n\nimport { camelCase } from '../transformers/casing.ts'\n\ntype FunctionParamsASTWithoutType = {\n name?: string\n type?: string\n /**\n * @default true\n */\n required?: boolean\n /**\n * @default true\n */\n enabled?: boolean\n default?: string\n}\n\ntype FunctionParamsASTWithType = {\n name?: never\n type: string\n /**\n * @default true\n */\n required?: boolean\n /**\n * @default true\n */\n enabled?: boolean\n default?: string\n}\n/**\n * @deprecated\n */\nexport type FunctionParamsAST = FunctionParamsASTWithoutType | FunctionParamsASTWithType\n\n/**\n * @deprecated\n */\nexport class FunctionParams {\n #items: Array<FunctionParamsAST | FunctionParamsAST[]> = []\n constructor() {\n return this\n }\n\n get items(): FunctionParamsAST[] {\n return this.#items.flat()\n }\n\n add(item: FunctionParamsAST | Array<FunctionParamsAST | FunctionParamsAST[] | undefined> | undefined): FunctionParams {\n if (!item) {\n return this\n }\n\n if (Array.isArray(item)) {\n item.filter(Boolean).forEach((it) => {\n this.#items.push(it)\n })\n return this\n }\n this.#items.push(item)\n\n return this\n }\n static #orderItems(items: Array<FunctionParamsAST | FunctionParamsAST[]>) {\n return orderBy(\n items.filter(Boolean),\n [\n (v) => {\n if (Array.isArray(v)) {\n return undefined\n }\n return !v.default\n },\n (v) => {\n if (Array.isArray(v)) {\n return undefined\n }\n return v.required ?? true\n },\n ],\n ['desc', 'desc'],\n )\n }\n\n static #addParams(acc: string[], item: FunctionParamsAST) {\n const { enabled = true, name, type, required = true, ...rest } = item\n\n if (!enabled) {\n return acc\n }\n\n if (!name) {\n // when name is not se we uses TypeScript generics\n acc.push(`${type}${rest.default ? ` = ${rest.default}` : ''}`)\n\n return acc\n }\n // TODO check whey we still need the camelcase here\n const parameterName = name.startsWith('{') ? name : camelCase(name)\n\n if (type) {\n if (required) {\n acc.push(`${parameterName}: ${type}${rest.default ? ` = ${rest.default}` : ''}`)\n } else {\n acc.push(`${parameterName}?: ${type}`)\n }\n } else {\n acc.push(`${parameterName}`)\n }\n\n return acc\n }\n\n static toObject(items: FunctionParamsAST[]): FunctionParamsAST {\n let type: string[] = []\n let name: string[] = []\n\n const enabled = items.every((item) => item.enabled) ? items.at(0)?.enabled : true\n const required = items.every((item) => item.required) ?? true\n\n items.forEach((item) => {\n name = FunctionParams.#addParams(name, { ...item, type: undefined })\n if (items.some((item) => item.type)) {\n type = FunctionParams.#addParams(type, item)\n }\n })\n\n return {\n name: `{ ${name.join(', ')} }`,\n type: type.length ? `{ ${type.join('; ')} }` : undefined,\n enabled,\n required,\n }\n }\n\n toObject(): FunctionParamsAST {\n const items = FunctionParams.#orderItems(this.#items).flat()\n\n return FunctionParams.toObject(items)\n }\n\n static toString(items: (FunctionParamsAST | FunctionParamsAST[])[]): string {\n const sortedData = FunctionParams.#orderItems(items)\n\n return sortedData\n .reduce((acc, item) => {\n if (Array.isArray(item)) {\n if (item.length <= 0) {\n return acc\n }\n const subItems = FunctionParams.#orderItems(item) as FunctionParamsAST[]\n const objectItem = FunctionParams.toObject(subItems)\n\n return FunctionParams.#addParams(acc, objectItem)\n }\n\n return FunctionParams.#addParams(acc, item)\n }, [] as string[])\n .join(', ')\n }\n\n toString(): string {\n const items = FunctionParams.#orderItems(this.#items)\n\n return FunctionParams.toString(items)\n }\n}\n","import { execaCommand } from 'execa'\n\nexport const formatters = {\n prettier: {\n command: 'prettier',\n args: (outputPath: string) => ['--ignore-unknown', '--write', outputPath],\n errorMessage: 'Prettier not found',\n },\n biome: {\n command: 'biome',\n args: (outputPath: string) => ['format', '--write', outputPath],\n errorMessage: 'Biome not found',\n },\n oxfmt: {\n command: 'oxfmt',\n args: (outputPath: string) => [outputPath],\n errorMessage: 'Oxfmt not found',\n },\n} as const\n\ntype Formatter = keyof typeof formatters\n\n/**\n * Check if a formatter command is available in the system.\n *\n * @param formatter - The formatter to check ('biome', 'prettier', or 'oxfmt')\n * @returns Promise that resolves to true if the formatter is available, false otherwise\n *\n * @remarks\n * This function checks availability by running `<formatter> --version` command.\n * All supported formatters (biome, prettier, oxfmt) implement the --version flag.\n */\nasync function isFormatterAvailable(formatter: Formatter): Promise<boolean> {\n try {\n // Try to get the version of the formatter to check if it's installed\n await execaCommand(`${formatter} --version`, { stdio: 'ignore' })\n return true\n } catch {\n return false\n }\n}\n\n/**\n * Detect which formatter is available in the system.\n *\n * @returns Promise that resolves to the first available formatter or undefined if none are found\n *\n * @remarks\n * Checks in order of preference: biome, oxfmt, prettier.\n * Uses the `--version` flag to detect if each formatter command is available.\n * This is a reliable method as all supported formatters implement this flag.\n *\n * @example\n * ```typescript\n * const formatter = await detectFormatter()\n * if (formatter) {\n * console.log(`Using ${formatter} for formatting`)\n * } else {\n * console.log('No formatter found')\n * }\n * ```\n */\nexport async function detectFormatter(): Promise<Formatter | undefined> {\n const formatters: Formatter[] = ['biome', 'oxfmt', 'prettier']\n\n for (const formatter of formatters) {\n if (await isFormatterAvailable(formatter)) {\n return formatter\n }\n }\n\n return undefined\n}\n","import type { UserConfig } from '../types.ts'\n\nfunction isJSONPlugins(plugins: UserConfig['plugins']) {\n return !!(plugins as any)?.some((plugin: any) => {\n return Array.isArray(plugin) && typeof plugin?.at(0) === 'string'\n })\n}\n\nfunction isObjectPlugins(plugins: UserConfig['plugins']): plugins is any {\n return plugins instanceof Object && !Array.isArray(plugins)\n}\n\nexport function getPlugins(plugins: UserConfig['plugins']): Promise<UserConfig['plugins']> {\n if (isObjectPlugins(plugins)) {\n throw new Error('Object plugins are not supported anymore, best to use http://kubb.dev/getting-started/configure#json')\n }\n\n if (isJSONPlugins(plugins)) {\n throw new Error('JSON plugins are not supported anymore, best to use http://kubb.dev/getting-started/configure#json')\n }\n\n return Promise.resolve(plugins)\n}\n","import type { PossiblePromise } from './types.ts'\n\nexport function isPromise<T>(result: PossiblePromise<T>): result is Promise<T> {\n return !!result && typeof (result as Promise<unknown>)?.then === 'function'\n}\n\nexport function isPromiseFulfilledResult<T = unknown>(result: PromiseSettledResult<unknown>): result is PromiseFulfilledResult<T> {\n return result.status === 'fulfilled'\n}\n\nexport function isPromiseRejectedResult<T>(result: PromiseSettledResult<unknown>): result is Omit<PromiseRejectedResult, 'reason'> & { reason: T } {\n return result.status === 'rejected'\n}\n","import type { CLIOptions, defineConfig } from '../config.ts'\nimport type { Config, UserConfig } from '../types.ts'\nimport { getPlugins } from './getPlugins.ts'\nimport { isPromise } from './promise.ts'\n\n/**\n * Converting UserConfig to Config Array without a change in the object beside the JSON convert.\n */\nexport async function getConfigs(config: ReturnType<typeof defineConfig> | UserConfig, args: CLIOptions): Promise<Array<Config>> {\n let kubbUserConfig = Promise.resolve(config) as Promise<UserConfig | Array<UserConfig>>\n\n // for ts or js files\n if (typeof config === 'function') {\n const possiblePromise = config(args as CLIOptions)\n if (isPromise(possiblePromise)) {\n kubbUserConfig = possiblePromise\n }\n kubbUserConfig = Promise.resolve(possiblePromise)\n }\n\n let JSONConfig = await kubbUserConfig\n\n if (!Array.isArray(JSONConfig)) {\n JSONConfig = [JSONConfig]\n }\n\n const results: Array<Config> = []\n\n for (const item of JSONConfig) {\n const plugins = item.plugins ? await getPlugins(item.plugins) : undefined\n\n results.push({\n ...item,\n plugins,\n } as Config)\n }\n\n return results\n}\n","/**\n * Converts a param path (string with dot notation or array of strings) to a JavaScript accessor expression.\n * @param param - The param path, e.g., 'pagination.next.id' or ['pagination', 'next', 'id']\n * @param accessor - The base accessor, e.g., 'lastPage' or 'firstPage'\n * @returns A JavaScript accessor expression, e.g., \"lastPage?.['pagination']?.['next']?.['id']\", or undefined if param is empty\n *\n * @example\n * ```ts\n * getNestedAccessor('pagination.next.id', 'lastPage')\n * // returns: \"lastPage?.['pagination']?.['next']?.['id']\"\n *\n * getNestedAccessor(['pagination', 'next', 'id'], 'lastPage')\n * // returns: \"lastPage?.['pagination']?.['next']?.['id']\"\n *\n * getNestedAccessor('', 'lastPage')\n * // returns: undefined\n * ```\n */\nexport function getNestedAccessor(param: string | string[], accessor: string): string | undefined {\n const parts = Array.isArray(param) ? param : param.split('.')\n if (parts.length === 0 || (parts.length === 1 && parts[0] === '')) {\n return undefined\n }\n return parts.reduce((acc, part) => `${acc}?.['${part}']`, accessor)\n}\n","import { execaCommand } from 'execa'\n\nexport const linters = {\n eslint: {\n command: 'eslint',\n args: (outputPath: string) => [outputPath, '--fix'],\n errorMessage: 'Eslint not found',\n },\n biome: {\n command: 'biome',\n args: (outputPath: string) => ['lint', '--fix', outputPath],\n errorMessage: 'Biome not found',\n },\n oxlint: {\n command: 'oxlint',\n args: (outputPath: string) => ['--fix', outputPath],\n errorMessage: 'Oxlint not found',\n },\n} as const\n\ntype Linter = keyof typeof linters\n\nasync function isLinterAvailable(linter: Linter): Promise<boolean> {\n try {\n await execaCommand(`${linter} --version`, { stdio: 'ignore' })\n return true\n } catch {\n return false\n }\n}\n\nexport async function detectLinter(): Promise<Linter | undefined> {\n const linters: Linter[] = ['biome', 'oxlint', 'eslint']\n\n for (const linter of linters) {\n if (await isLinterAvailable(linter)) {\n return linter\n }\n }\n\n return undefined\n}\n","export function renderTemplate<TData extends Record<string, unknown> = Record<string, unknown>>(template: string, data: TData | undefined = undefined): string {\n if (!data || !Object.keys(data).length) {\n return template.replace(/{{(.*?)}}/g, '')\n }\n\n const matches = template.match(/{{(.*?)}}/g)\n\n return (\n matches?.reduce((prev, curr) => {\n const index = curr.split(/{{|}}/).filter(Boolean)[0]?.trim()\n if (index === undefined) {\n return prev\n }\n const value = data[index]\n\n if (value === undefined) {\n return prev\n }\n\n return prev\n .replace(curr, () => {\n if (typeof value === 'boolean') {\n return `${value.toString()}` || 'false'\n }\n\n return (value as string) || ''\n })\n .trim()\n }, template) || ''\n )\n}\n","/**\n * Serialize plugin options for safe JSON transport.\n * Strips functions, symbols, and undefined values recursively.\n */\nexport function serializePluginOptions(options: unknown): unknown {\n if (options === null || options === undefined) {\n return {}\n }\n if (typeof options !== 'object') {\n return options\n }\n if (Array.isArray(options)) {\n return options.map(serializePluginOptions)\n }\n\n const serialized: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(options)) {\n if (typeof value === 'function' || typeof value === 'symbol' || value === undefined) {\n continue\n }\n if (typeof value === 'object' && value !== null) {\n serialized[key] = serializePluginOptions(value)\n } else {\n serialized[key] = value\n }\n }\n return serialized\n}\n","export async function timeout(ms: number): Promise<unknown> {\n return new Promise((resolve) => {\n const timeout = setTimeout(() => {\n resolve(timeout)\n }, ms)\n }).then((timeout) => {\n clearTimeout(timeout as NodeJS.Timeout)\n\n return true\n })\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"utils.js","names":["#buffer","#items","#orderItems","#addParams"],"sources":["../src/utils/buildJSDoc.ts","../src/utils/Cache.ts","../src/utils/checkOnlineStatus.ts","../src/utils/FunctionParams.ts","../src/utils/formatters.ts","../src/utils/getPlugins.ts","../src/utils/promise.ts","../src/utils/getConfigs.ts","../src/utils/getNestedAccessor.ts","../src/utils/linters.ts","../src/utils/renderTemplate.ts","../src/utils/serializePluginOptions.ts","../src/utils/timeout.ts","../src/utils/tokenize.ts"],"sourcesContent":["/**\n * Builds a JSDoc comment block with custom indentation.\n * @param comments - Array of comment strings to include in the JSDoc block\n * @param options - Configuration options for formatting\n * @returns Formatted JSDoc string or fallback string if no comments\n */\nexport function buildJSDoc(\n comments: Array<string>,\n options: {\n /**\n * String to use for indenting each line of the JSDoc comment\n * @default ' * ' (3 spaces + asterisk + space)\n */\n indent?: string\n /**\n * String to append after the closing JSDoc tag\n * @default '\\n ' (newline + 2 spaces)\n */\n suffix?: string\n /**\n * String to return when there are no comments\n * @default ' ' (2 spaces)\n */\n fallback?: string\n } = {},\n): string {\n const { indent = ' * ', suffix = '\\n ', fallback = ' ' } = options\n\n if (comments.length === 0) {\n return fallback\n }\n\n return `/**\\n${comments.map((c) => `${indent}${c}`).join('\\n')}\\n */${suffix}`\n}\n","export class Cache<T> {\n #buffer = new Map<string, T>()\n\n async get(key: string): Promise<T | null> {\n return this.#buffer.get(key) ?? null\n }\n\n async set(key: string, value: T): Promise<void> {\n this.#buffer.set(key, value)\n }\n\n async delete(key: string): Promise<void> {\n this.#buffer.delete(key)\n }\n\n async clear(): Promise<void> {\n this.#buffer.clear()\n }\n\n async keys(): Promise<string[]> {\n return [...this.#buffer.keys()]\n }\n\n async values(): Promise<T[]> {\n return [...this.#buffer.values()]\n }\n\n async flush(): Promise<void> {\n // No-op for base cache\n }\n}\n","import dns from 'node:dns'\n\n/**\n * Check if the system has internet connectivity\n * Uses DNS lookup to well-known stable domains as a lightweight connectivity test\n */\nexport async function isOnline(): Promise<boolean> {\n const testDomains = [\n 'dns.google.com', // Google Public DNS\n 'cloudflare.com', // Cloudflare\n 'one.one.one.one', // Cloudflare DNS\n ]\n\n for (const domain of testDomains) {\n try {\n await dns.promises.resolve(domain)\n return true\n } catch {\n // Try next domain\n }\n }\n\n return false\n}\n\n/**\n * Execute a function only if online, otherwise silently skip\n */\nexport async function executeIfOnline<T>(fn: () => Promise<T>): Promise<T | null> {\n const online = await isOnline()\n if (!online) {\n return null\n }\n\n try {\n return await fn()\n } catch {\n return null\n }\n}\n","import { sortBy } from 'remeda'\nimport { camelCase } from '../transformers/casing.ts'\n\ntype FunctionParamsASTWithoutType = {\n name?: string\n type?: string\n /**\n * @default true\n */\n required?: boolean\n /**\n * @default true\n */\n enabled?: boolean\n default?: string\n}\n\ntype FunctionParamsASTWithType = {\n name?: never\n type: string\n /**\n * @default true\n */\n required?: boolean\n /**\n * @default true\n */\n enabled?: boolean\n default?: string\n}\n/**\n * @deprecated\n */\nexport type FunctionParamsAST = FunctionParamsASTWithoutType | FunctionParamsASTWithType\n\n/**\n * @deprecated\n */\nexport class FunctionParams {\n #items: Array<FunctionParamsAST | FunctionParamsAST[]> = []\n constructor() {\n return this\n }\n\n get items(): FunctionParamsAST[] {\n return this.#items.flat()\n }\n\n add(item: FunctionParamsAST | Array<FunctionParamsAST | FunctionParamsAST[] | undefined> | undefined): FunctionParams {\n if (!item) {\n return this\n }\n\n if (Array.isArray(item)) {\n item.filter(Boolean).forEach((it) => {\n this.#items.push(it)\n })\n return this\n }\n this.#items.push(item)\n\n return this\n }\n static #orderItems(items: Array<FunctionParamsAST | FunctionParamsAST[]>) {\n return sortBy(\n items.filter(Boolean),\n [(item) => Array.isArray(item), 'desc'], // arrays (rest params) first\n [(item) => !Array.isArray(item) && (item as FunctionParamsAST).default !== undefined, 'asc'], // no-default before has-default\n [(item) => Array.isArray(item) || ((item as FunctionParamsAST).required ?? true), 'desc'], // required before optional\n )\n }\n\n static #addParams(acc: string[], item: FunctionParamsAST) {\n const { enabled = true, name, type, required = true, ...rest } = item\n\n if (!enabled) {\n return acc\n }\n\n if (!name) {\n // when name is not se we uses TypeScript generics\n acc.push(`${type}${rest.default ? ` = ${rest.default}` : ''}`)\n\n return acc\n }\n // TODO check whey we still need the camelcase here\n const parameterName = name.startsWith('{') ? name : camelCase(name)\n\n if (type) {\n if (required) {\n acc.push(`${parameterName}: ${type}${rest.default ? ` = ${rest.default}` : ''}`)\n } else {\n acc.push(`${parameterName}?: ${type}`)\n }\n } else {\n acc.push(`${parameterName}`)\n }\n\n return acc\n }\n\n static toObject(items: FunctionParamsAST[]): FunctionParamsAST {\n let type: string[] = []\n let name: string[] = []\n\n const enabled = items.every((item) => item.enabled) ? items.at(0)?.enabled : true\n const required = items.every((item) => item.required) ?? true\n\n items.forEach((item) => {\n name = FunctionParams.#addParams(name, { ...item, type: undefined })\n if (items.some((item) => item.type)) {\n type = FunctionParams.#addParams(type, item)\n }\n })\n\n return {\n name: `{ ${name.join(', ')} }`,\n type: type.length ? `{ ${type.join('; ')} }` : undefined,\n enabled,\n required,\n }\n }\n\n toObject(): FunctionParamsAST {\n const items = FunctionParams.#orderItems(this.#items).flat()\n\n return FunctionParams.toObject(items)\n }\n\n static toString(items: (FunctionParamsAST | FunctionParamsAST[])[]): string {\n const sortedData = FunctionParams.#orderItems(items)\n\n return sortedData\n .reduce((acc, item) => {\n if (Array.isArray(item)) {\n if (item.length <= 0) {\n return acc\n }\n const subItems = FunctionParams.#orderItems(item) as FunctionParamsAST[]\n const objectItem = FunctionParams.toObject(subItems)\n\n return FunctionParams.#addParams(acc, objectItem)\n }\n\n return FunctionParams.#addParams(acc, item)\n }, [] as string[])\n .join(', ')\n }\n\n toString(): string {\n const items = FunctionParams.#orderItems(this.#items)\n\n return FunctionParams.toString(items)\n }\n}\n","import { x } from 'tinyexec'\n\nexport const formatters = {\n prettier: {\n command: 'prettier',\n args: (outputPath: string) => ['--ignore-unknown', '--write', outputPath],\n errorMessage: 'Prettier not found',\n },\n biome: {\n command: 'biome',\n args: (outputPath: string) => ['format', '--write', outputPath],\n errorMessage: 'Biome not found',\n },\n oxfmt: {\n command: 'oxfmt',\n args: (outputPath: string) => [outputPath],\n errorMessage: 'Oxfmt not found',\n },\n} as const\n\ntype Formatter = keyof typeof formatters\n\n/**\n * Check if a formatter command is available in the system.\n *\n * @param formatter - The formatter to check ('biome', 'prettier', or 'oxfmt')\n * @returns Promise that resolves to true if the formatter is available, false otherwise\n *\n * @remarks\n * This function checks availability by running `<formatter> --version` command.\n * All supported formatters (biome, prettier, oxfmt) implement the --version flag.\n */\nasync function isFormatterAvailable(formatter: Formatter): Promise<boolean> {\n try {\n // Try to get the version of the formatter to check if it's installed\n await x(formatter, ['--version'], { nodeOptions: { stdio: 'ignore' } })\n return true\n } catch {\n return false\n }\n}\n\n/**\n * Detect which formatter is available in the system.\n *\n * @returns Promise that resolves to the first available formatter or undefined if none are found\n *\n * @remarks\n * Checks in order of preference: biome, oxfmt, prettier.\n * Uses the `--version` flag to detect if each formatter command is available.\n * This is a reliable method as all supported formatters implement this flag.\n *\n * @example\n * ```typescript\n * const formatter = await detectFormatter()\n * if (formatter) {\n * console.log(`Using ${formatter} for formatting`)\n * } else {\n * console.log('No formatter found')\n * }\n * ```\n */\nexport async function detectFormatter(): Promise<Formatter | undefined> {\n const formatters: Formatter[] = ['biome', 'oxfmt', 'prettier']\n\n for (const formatter of formatters) {\n if (await isFormatterAvailable(formatter)) {\n return formatter\n }\n }\n\n return undefined\n}\n","import type { UserConfig } from '../types.ts'\n\nfunction isJSONPlugins(plugins: UserConfig['plugins']) {\n return !!(plugins as any)?.some((plugin: any) => {\n return Array.isArray(plugin) && typeof plugin?.at(0) === 'string'\n })\n}\n\nfunction isObjectPlugins(plugins: UserConfig['plugins']): plugins is any {\n return plugins instanceof Object && !Array.isArray(plugins)\n}\n\nexport function getPlugins(plugins: UserConfig['plugins']): Promise<UserConfig['plugins']> {\n if (isObjectPlugins(plugins)) {\n throw new Error('Object plugins are not supported anymore, best to use http://kubb.dev/getting-started/configure#json')\n }\n\n if (isJSONPlugins(plugins)) {\n throw new Error('JSON plugins are not supported anymore, best to use http://kubb.dev/getting-started/configure#json')\n }\n\n return Promise.resolve(plugins)\n}\n","import type { PossiblePromise } from './types.ts'\n\nexport function isPromise<T>(result: PossiblePromise<T>): result is Promise<T> {\n return !!result && typeof (result as Promise<unknown>)?.then === 'function'\n}\n\nexport function isPromiseFulfilledResult<T = unknown>(result: PromiseSettledResult<unknown>): result is PromiseFulfilledResult<T> {\n return result.status === 'fulfilled'\n}\n\nexport function isPromiseRejectedResult<T>(result: PromiseSettledResult<unknown>): result is Omit<PromiseRejectedResult, 'reason'> & { reason: T } {\n return result.status === 'rejected'\n}\n","import type { CLIOptions, defineConfig } from '../config.ts'\nimport type { Config, UserConfig } from '../types.ts'\nimport { getPlugins } from './getPlugins.ts'\nimport { isPromise } from './promise.ts'\n\n/**\n * Converting UserConfig to Config Array without a change in the object beside the JSON convert.\n */\nexport async function getConfigs(config: ReturnType<typeof defineConfig> | UserConfig, args: CLIOptions): Promise<Array<Config>> {\n let kubbUserConfig = Promise.resolve(config) as Promise<UserConfig | Array<UserConfig>>\n\n // for ts or js files\n if (typeof config === 'function') {\n const possiblePromise = config(args as CLIOptions)\n if (isPromise(possiblePromise)) {\n kubbUserConfig = possiblePromise\n }\n kubbUserConfig = Promise.resolve(possiblePromise)\n }\n\n let JSONConfig = await kubbUserConfig\n\n if (!Array.isArray(JSONConfig)) {\n JSONConfig = [JSONConfig]\n }\n\n const results: Array<Config> = []\n\n for (const item of JSONConfig) {\n const plugins = item.plugins ? await getPlugins(item.plugins) : undefined\n\n results.push({\n ...item,\n plugins,\n } as Config)\n }\n\n return results\n}\n","/**\n * Converts a param path (string with dot notation or array of strings) to a JavaScript accessor expression.\n * @param param - The param path, e.g., 'pagination.next.id' or ['pagination', 'next', 'id']\n * @param accessor - The base accessor, e.g., 'lastPage' or 'firstPage'\n * @returns A JavaScript accessor expression, e.g., \"lastPage?.['pagination']?.['next']?.['id']\", or undefined if param is empty\n *\n * @example\n * ```ts\n * getNestedAccessor('pagination.next.id', 'lastPage')\n * // returns: \"lastPage?.['pagination']?.['next']?.['id']\"\n *\n * getNestedAccessor(['pagination', 'next', 'id'], 'lastPage')\n * // returns: \"lastPage?.['pagination']?.['next']?.['id']\"\n *\n * getNestedAccessor('', 'lastPage')\n * // returns: undefined\n * ```\n */\nexport function getNestedAccessor(param: string | string[], accessor: string): string | undefined {\n const parts = Array.isArray(param) ? param : param.split('.')\n if (parts.length === 0 || (parts.length === 1 && parts[0] === '')) {\n return undefined\n }\n return parts.reduce((acc, part) => `${acc}?.['${part}']`, accessor)\n}\n","import { x } from 'tinyexec'\n\nexport const linters = {\n eslint: {\n command: 'eslint',\n args: (outputPath: string) => [outputPath, '--fix'],\n errorMessage: 'Eslint not found',\n },\n biome: {\n command: 'biome',\n args: (outputPath: string) => ['lint', '--fix', outputPath],\n errorMessage: 'Biome not found',\n },\n oxlint: {\n command: 'oxlint',\n args: (outputPath: string) => ['--fix', outputPath],\n errorMessage: 'Oxlint not found',\n },\n} as const\n\ntype Linter = keyof typeof linters\n\nasync function isLinterAvailable(linter: Linter): Promise<boolean> {\n try {\n await x(linter, ['--version'], { nodeOptions: { stdio: 'ignore' } })\n return true\n } catch {\n return false\n }\n}\n\nexport async function detectLinter(): Promise<Linter | undefined> {\n const linters: Linter[] = ['biome', 'oxlint', 'eslint']\n\n for (const linter of linters) {\n if (await isLinterAvailable(linter)) {\n return linter\n }\n }\n\n return undefined\n}\n","export function renderTemplate<TData extends Record<string, unknown> = Record<string, unknown>>(template: string, data: TData | undefined = undefined): string {\n if (!data || !Object.keys(data).length) {\n return template.replace(/{{(.*?)}}/g, '')\n }\n\n const matches = template.match(/{{(.*?)}}/g)\n\n return (\n matches?.reduce((prev, curr) => {\n const index = curr.split(/{{|}}/).filter(Boolean)[0]?.trim()\n if (index === undefined) {\n return prev\n }\n const value = data[index]\n\n if (value === undefined) {\n return prev\n }\n\n return prev\n .replace(curr, () => {\n if (typeof value === 'boolean') {\n return `${value.toString()}` || 'false'\n }\n\n return (value as string) || ''\n })\n .trim()\n }, template) || ''\n )\n}\n","/**\n * Serialize plugin options for safe JSON transport.\n * Strips functions, symbols, and undefined values recursively.\n */\nexport function serializePluginOptions(options: unknown): unknown {\n if (options === null || options === undefined) {\n return {}\n }\n if (typeof options !== 'object') {\n return options\n }\n if (Array.isArray(options)) {\n return options.map(serializePluginOptions)\n }\n\n const serialized: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(options)) {\n if (typeof value === 'function' || typeof value === 'symbol' || value === undefined) {\n continue\n }\n if (typeof value === 'object' && value !== null) {\n serialized[key] = serializePluginOptions(value)\n } else {\n serialized[key] = value\n }\n }\n return serialized\n}\n","export async function timeout(ms: number): Promise<unknown> {\n return new Promise((resolve) => {\n const timeout = setTimeout(() => {\n resolve(timeout)\n }, ms)\n }).then((timeout) => {\n clearTimeout(timeout as NodeJS.Timeout)\n\n return true\n })\n}\n","/** Shell-like tokenizer: splits a command string respecting single/double quotes. */\nexport function tokenize(command: string): string[] {\n const args: string[] = []\n let current = ''\n let quote = ''\n for (const ch of command) {\n if (quote) {\n if (ch === quote) quote = ''\n else current += ch\n } else if (ch === '\"' || ch === \"'\") {\n quote = ch\n } else if (ch === ' ' || ch === '\\t') {\n if (current) {\n args.push(current)\n current = ''\n }\n } else {\n current += ch\n }\n }\n if (current) args.push(current)\n return args\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
const require_chunk = require('./chunk-CNbaEX1y.cjs');
|
|
2
|
+
let node_path = require("node:path");
|
|
3
|
+
let node_fs_promises = require("node:fs/promises");
|
|
4
|
+
let node_fs = require("node:fs");
|
|
5
|
+
node_fs = require_chunk.__toESM(node_fs);
|
|
6
|
+
|
|
7
|
+
//#region src/fs/clean.ts
|
|
8
|
+
async function clean(path) {
|
|
9
|
+
return (0, node_fs_promises.rm)(path, {
|
|
10
|
+
recursive: true,
|
|
11
|
+
force: true
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
//#endregion
|
|
16
|
+
//#region src/fs/exists.ts
|
|
17
|
+
async function exists(path) {
|
|
18
|
+
if (typeof Bun !== "undefined") return Bun.file(path).exists();
|
|
19
|
+
return (0, node_fs_promises.access)(path).then(() => true, () => false);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
//#endregion
|
|
23
|
+
//#region src/fs/read.ts
|
|
24
|
+
async function read(path) {
|
|
25
|
+
if (typeof Bun !== "undefined") return Bun.file(path).text();
|
|
26
|
+
return (0, node_fs_promises.readFile)(path, { encoding: "utf8" });
|
|
27
|
+
}
|
|
28
|
+
function readSync(path) {
|
|
29
|
+
return (0, node_fs.readFileSync)(path, { encoding: "utf8" });
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
//#endregion
|
|
33
|
+
//#region src/fs/utils.ts
|
|
34
|
+
function slash(path, platform = "linux") {
|
|
35
|
+
const isWindowsPath = /^\\\\\?\\/.test(path);
|
|
36
|
+
const normalizedPath = (0, node_path.normalize)(path);
|
|
37
|
+
if (["linux", "mac"].includes(platform) && !isWindowsPath) return normalizedPath.replaceAll(/\\/g, "/").replace("../", "");
|
|
38
|
+
return normalizedPath.replaceAll(/\\/g, "/").replace("../", "");
|
|
39
|
+
}
|
|
40
|
+
function getRelativePath(rootDir, filePath, platform = "linux") {
|
|
41
|
+
if (!rootDir || !filePath) throw new Error(`Root and file should be filled in when retrieving the relativePath, ${rootDir || ""} ${filePath || ""}`);
|
|
42
|
+
const slashedPath = slash((0, node_path.relative)(rootDir, filePath), platform);
|
|
43
|
+
if (slashedPath.startsWith("../")) return slashedPath;
|
|
44
|
+
return `./${slashedPath}`;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
//#endregion
|
|
48
|
+
//#region src/fs/write.ts
|
|
49
|
+
async function write(path, data, options = {}) {
|
|
50
|
+
if (data.trim() === "") return;
|
|
51
|
+
const resolved = (0, node_path.resolve)(path);
|
|
52
|
+
if (typeof Bun !== "undefined") {
|
|
53
|
+
const file = Bun.file(resolved);
|
|
54
|
+
if ((await file.exists() ? await file.text() : null) === data.trim()) return;
|
|
55
|
+
await Bun.write(resolved, data.trim());
|
|
56
|
+
return data.trim();
|
|
57
|
+
}
|
|
58
|
+
try {
|
|
59
|
+
if ((await (0, node_fs_promises.readFile)(resolved, { encoding: "utf-8" }))?.toString() === data.trim()) return;
|
|
60
|
+
} catch (_err) {}
|
|
61
|
+
await (0, node_fs_promises.mkdir)((0, node_path.dirname)(resolved), { recursive: true });
|
|
62
|
+
await (0, node_fs_promises.writeFile)(resolved, data.trim(), { encoding: "utf-8" });
|
|
63
|
+
if (options.sanity) {
|
|
64
|
+
const savedData = await (0, node_fs_promises.readFile)(resolved, { encoding: "utf-8" });
|
|
65
|
+
if (savedData?.toString() !== data.trim()) throw new Error(`Sanity check failed for ${path}\n\nData[${data.length}]:\n${data}\n\nSaved[${savedData.length}]:\n${savedData}\n`);
|
|
66
|
+
return savedData;
|
|
67
|
+
}
|
|
68
|
+
return data.trim();
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
//#endregion
|
|
72
|
+
Object.defineProperty(exports, 'clean', {
|
|
73
|
+
enumerable: true,
|
|
74
|
+
get: function () {
|
|
75
|
+
return clean;
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
Object.defineProperty(exports, 'exists', {
|
|
79
|
+
enumerable: true,
|
|
80
|
+
get: function () {
|
|
81
|
+
return exists;
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
Object.defineProperty(exports, 'getRelativePath', {
|
|
85
|
+
enumerable: true,
|
|
86
|
+
get: function () {
|
|
87
|
+
return getRelativePath;
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
Object.defineProperty(exports, 'read', {
|
|
91
|
+
enumerable: true,
|
|
92
|
+
get: function () {
|
|
93
|
+
return read;
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
Object.defineProperty(exports, 'readSync', {
|
|
97
|
+
enumerable: true,
|
|
98
|
+
get: function () {
|
|
99
|
+
return readSync;
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
Object.defineProperty(exports, 'write', {
|
|
103
|
+
enumerable: true,
|
|
104
|
+
get: function () {
|
|
105
|
+
return write;
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
//# sourceMappingURL=write-CwpeNfTd.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"write-CwpeNfTd.cjs","names":[],"sources":["../src/fs/clean.ts","../src/fs/exists.ts","../src/fs/read.ts","../src/fs/utils.ts","../src/fs/write.ts"],"sourcesContent":["import { rm } from 'node:fs/promises'\n\nexport async function clean(path: string): Promise<void> {\n return rm(path, { recursive: true, force: true })\n}\n","import fs from 'node:fs'\nimport { access } from 'node:fs/promises'\n\nexport async function exists(path: string): Promise<boolean> {\n if (typeof Bun !== 'undefined') {\n return Bun.file(path).exists()\n }\n return access(path).then(\n () => true,\n () => false,\n )\n}\n\nexport function existsSync(path: string): boolean {\n return fs.existsSync(path)\n}\n","import { readFileSync } from 'node:fs'\nimport { readFile } from 'node:fs/promises'\n\nexport async function read(path: string): Promise<string> {\n if (typeof Bun !== 'undefined') {\n return Bun.file(path).text()\n }\n return readFile(path, { encoding: 'utf8' })\n}\n\nexport function readSync(path: string): string {\n return readFileSync(path, { encoding: 'utf8' })\n}\n","import { normalize, relative } from 'node:path'\n\nfunction slash(path: string, platform: 'windows' | 'mac' | 'linux' = 'linux') {\n const isWindowsPath = /^\\\\\\\\\\?\\\\/.test(path)\n const normalizedPath = normalize(path)\n\n if (['linux', 'mac'].includes(platform) && !isWindowsPath) {\n // linux and mac\n return normalizedPath.replaceAll(/\\\\/g, '/').replace('../', '')\n }\n\n // windows\n return normalizedPath.replaceAll(/\\\\/g, '/').replace('../', '')\n}\n\nexport function getRelativePath(rootDir?: string | null, filePath?: string | null, platform: 'windows' | 'mac' | 'linux' = 'linux'): string {\n if (!rootDir || !filePath) {\n throw new Error(`Root and file should be filled in when retrieving the relativePath, ${rootDir || ''} ${filePath || ''}`)\n }\n\n const relativePath = relative(rootDir, filePath)\n\n // On Windows, paths are separated with a \"\\\"\n // However, web browsers use \"/\" no matter the platform\n const slashedPath = slash(relativePath, platform)\n\n if (slashedPath.startsWith('../')) {\n return slashedPath\n }\n\n return `./${slashedPath}`\n}\n","import { mkdir, readFile, writeFile } from 'node:fs/promises'\nimport { dirname, resolve } from 'node:path'\n\ntype Options = { sanity?: boolean }\n\nexport async function write(path: string, data: string, options: Options = {}): Promise<string | undefined> {\n if (data.trim() === '') {\n return undefined\n }\n\n const resolved = resolve(path)\n\n if (typeof Bun !== 'undefined') {\n const file = Bun.file(resolved)\n const oldContent = (await file.exists()) ? await file.text() : null\n if (oldContent === data.trim()) {\n return undefined\n }\n await Bun.write(resolved, data.trim())\n return data.trim()\n }\n\n try {\n const oldContent = await readFile(resolved, { encoding: 'utf-8' })\n if (oldContent?.toString() === data.trim()) {\n return undefined\n }\n } catch (_err) {\n /* file doesn't exist yet */\n }\n\n await mkdir(dirname(resolved), { recursive: true })\n await writeFile(resolved, data.trim(), { encoding: 'utf-8' })\n\n if (options.sanity) {\n const savedData = await readFile(resolved, { encoding: 'utf-8' })\n\n if (savedData?.toString() !== data.trim()) {\n throw new Error(`Sanity check failed for ${path}\\n\\nData[${data.length}]:\\n${data}\\n\\nSaved[${savedData.length}]:\\n${savedData}\\n`)\n }\n\n return savedData\n }\n\n return data.trim()\n}\n"],"mappings":";;;;;;;AAEA,eAAsB,MAAM,MAA6B;AACvD,iCAAU,MAAM;EAAE,WAAW;EAAM,OAAO;EAAM,CAAC;;;;;ACAnD,eAAsB,OAAO,MAAgC;AAC3D,KAAI,OAAO,QAAQ,YACjB,QAAO,IAAI,KAAK,KAAK,CAAC,QAAQ;AAEhC,qCAAc,KAAK,CAAC,WACZ,YACA,MACP;;;;;ACPH,eAAsB,KAAK,MAA+B;AACxD,KAAI,OAAO,QAAQ,YACjB,QAAO,IAAI,KAAK,KAAK,CAAC,MAAM;AAE9B,uCAAgB,MAAM,EAAE,UAAU,QAAQ,CAAC;;AAG7C,SAAgB,SAAS,MAAsB;AAC7C,kCAAoB,MAAM,EAAE,UAAU,QAAQ,CAAC;;;;;ACTjD,SAAS,MAAM,MAAc,WAAwC,SAAS;CAC5E,MAAM,gBAAgB,YAAY,KAAK,KAAK;CAC5C,MAAM,0CAA2B,KAAK;AAEtC,KAAI,CAAC,SAAS,MAAM,CAAC,SAAS,SAAS,IAAI,CAAC,cAE1C,QAAO,eAAe,WAAW,OAAO,IAAI,CAAC,QAAQ,OAAO,GAAG;AAIjE,QAAO,eAAe,WAAW,OAAO,IAAI,CAAC,QAAQ,OAAO,GAAG;;AAGjE,SAAgB,gBAAgB,SAAyB,UAA0B,WAAwC,SAAiB;AAC1I,KAAI,CAAC,WAAW,CAAC,SACf,OAAM,IAAI,MAAM,uEAAuE,WAAW,GAAG,GAAG,YAAY,KAAK;CAO3H,MAAM,cAAc,8BAJU,SAAS,SAAS,EAIR,SAAS;AAEjD,KAAI,YAAY,WAAW,MAAM,CAC/B,QAAO;AAGT,QAAO,KAAK;;;;;ACzBd,eAAsB,MAAM,MAAc,MAAc,UAAmB,EAAE,EAA+B;AAC1G,KAAI,KAAK,MAAM,KAAK,GAClB;CAGF,MAAM,kCAAmB,KAAK;AAE9B,KAAI,OAAO,QAAQ,aAAa;EAC9B,MAAM,OAAO,IAAI,KAAK,SAAS;AAE/B,OADoB,MAAM,KAAK,QAAQ,GAAI,MAAM,KAAK,MAAM,GAAG,UAC5C,KAAK,MAAM,CAC5B;AAEF,QAAM,IAAI,MAAM,UAAU,KAAK,MAAM,CAAC;AACtC,SAAO,KAAK,MAAM;;AAGpB,KAAI;AAEF,OADmB,qCAAe,UAAU,EAAE,UAAU,SAAS,CAAC,GAClD,UAAU,KAAK,KAAK,MAAM,CACxC;UAEK,MAAM;AAIf,0DAAoB,SAAS,EAAE,EAAE,WAAW,MAAM,CAAC;AACnD,uCAAgB,UAAU,KAAK,MAAM,EAAE,EAAE,UAAU,SAAS,CAAC;AAE7D,KAAI,QAAQ,QAAQ;EAClB,MAAM,YAAY,qCAAe,UAAU,EAAE,UAAU,SAAS,CAAC;AAEjE,MAAI,WAAW,UAAU,KAAK,KAAK,MAAM,CACvC,OAAM,IAAI,MAAM,2BAA2B,KAAK,WAAW,KAAK,OAAO,MAAM,KAAK,YAAY,UAAU,OAAO,MAAM,UAAU,IAAI;AAGrI,SAAO;;AAGT,QAAO,KAAK,MAAM"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { t as __name } from "./chunk-DKWOrOAv.js";
|
|
2
|
+
import { dirname, normalize, relative, resolve } from "node:path";
|
|
3
|
+
import { access, mkdir, readFile, rm, writeFile } from "node:fs/promises";
|
|
4
|
+
import { readFileSync } from "node:fs";
|
|
5
|
+
|
|
6
|
+
//#region src/fs/clean.ts
|
|
7
|
+
async function clean(path) {
|
|
8
|
+
return rm(path, {
|
|
9
|
+
recursive: true,
|
|
10
|
+
force: true
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
//#endregion
|
|
15
|
+
//#region src/fs/exists.ts
|
|
16
|
+
async function exists(path) {
|
|
17
|
+
if (typeof Bun !== "undefined") return Bun.file(path).exists();
|
|
18
|
+
return access(path).then(() => true, () => false);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
//#endregion
|
|
22
|
+
//#region src/fs/read.ts
|
|
23
|
+
async function read(path) {
|
|
24
|
+
if (typeof Bun !== "undefined") return Bun.file(path).text();
|
|
25
|
+
return readFile(path, { encoding: "utf8" });
|
|
26
|
+
}
|
|
27
|
+
function readSync(path) {
|
|
28
|
+
return readFileSync(path, { encoding: "utf8" });
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
//#endregion
|
|
32
|
+
//#region src/fs/utils.ts
|
|
33
|
+
function slash(path, platform = "linux") {
|
|
34
|
+
const isWindowsPath = /^\\\\\?\\/.test(path);
|
|
35
|
+
const normalizedPath = normalize(path);
|
|
36
|
+
if (["linux", "mac"].includes(platform) && !isWindowsPath) return normalizedPath.replaceAll(/\\/g, "/").replace("../", "");
|
|
37
|
+
return normalizedPath.replaceAll(/\\/g, "/").replace("../", "");
|
|
38
|
+
}
|
|
39
|
+
function getRelativePath(rootDir, filePath, platform = "linux") {
|
|
40
|
+
if (!rootDir || !filePath) throw new Error(`Root and file should be filled in when retrieving the relativePath, ${rootDir || ""} ${filePath || ""}`);
|
|
41
|
+
const slashedPath = slash(relative(rootDir, filePath), platform);
|
|
42
|
+
if (slashedPath.startsWith("../")) return slashedPath;
|
|
43
|
+
return `./${slashedPath}`;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
//#endregion
|
|
47
|
+
//#region src/fs/write.ts
|
|
48
|
+
async function write(path, data, options = {}) {
|
|
49
|
+
if (data.trim() === "") return;
|
|
50
|
+
const resolved = resolve(path);
|
|
51
|
+
if (typeof Bun !== "undefined") {
|
|
52
|
+
const file = Bun.file(resolved);
|
|
53
|
+
if ((await file.exists() ? await file.text() : null) === data.trim()) return;
|
|
54
|
+
await Bun.write(resolved, data.trim());
|
|
55
|
+
return data.trim();
|
|
56
|
+
}
|
|
57
|
+
try {
|
|
58
|
+
if ((await readFile(resolved, { encoding: "utf-8" }))?.toString() === data.trim()) return;
|
|
59
|
+
} catch (_err) {}
|
|
60
|
+
await mkdir(dirname(resolved), { recursive: true });
|
|
61
|
+
await writeFile(resolved, data.trim(), { encoding: "utf-8" });
|
|
62
|
+
if (options.sanity) {
|
|
63
|
+
const savedData = await readFile(resolved, { encoding: "utf-8" });
|
|
64
|
+
if (savedData?.toString() !== data.trim()) throw new Error(`Sanity check failed for ${path}\n\nData[${data.length}]:\n${data}\n\nSaved[${savedData.length}]:\n${savedData}\n`);
|
|
65
|
+
return savedData;
|
|
66
|
+
}
|
|
67
|
+
return data.trim();
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
//#endregion
|
|
71
|
+
export { exists as a, readSync as i, getRelativePath as n, clean as o, read as r, write as t };
|
|
72
|
+
//# sourceMappingURL=write-DiGboRXI.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"write-DiGboRXI.js","names":[],"sources":["../src/fs/clean.ts","../src/fs/exists.ts","../src/fs/read.ts","../src/fs/utils.ts","../src/fs/write.ts"],"sourcesContent":["import { rm } from 'node:fs/promises'\n\nexport async function clean(path: string): Promise<void> {\n return rm(path, { recursive: true, force: true })\n}\n","import fs from 'node:fs'\nimport { access } from 'node:fs/promises'\n\nexport async function exists(path: string): Promise<boolean> {\n if (typeof Bun !== 'undefined') {\n return Bun.file(path).exists()\n }\n return access(path).then(\n () => true,\n () => false,\n )\n}\n\nexport function existsSync(path: string): boolean {\n return fs.existsSync(path)\n}\n","import { readFileSync } from 'node:fs'\nimport { readFile } from 'node:fs/promises'\n\nexport async function read(path: string): Promise<string> {\n if (typeof Bun !== 'undefined') {\n return Bun.file(path).text()\n }\n return readFile(path, { encoding: 'utf8' })\n}\n\nexport function readSync(path: string): string {\n return readFileSync(path, { encoding: 'utf8' })\n}\n","import { normalize, relative } from 'node:path'\n\nfunction slash(path: string, platform: 'windows' | 'mac' | 'linux' = 'linux') {\n const isWindowsPath = /^\\\\\\\\\\?\\\\/.test(path)\n const normalizedPath = normalize(path)\n\n if (['linux', 'mac'].includes(platform) && !isWindowsPath) {\n // linux and mac\n return normalizedPath.replaceAll(/\\\\/g, '/').replace('../', '')\n }\n\n // windows\n return normalizedPath.replaceAll(/\\\\/g, '/').replace('../', '')\n}\n\nexport function getRelativePath(rootDir?: string | null, filePath?: string | null, platform: 'windows' | 'mac' | 'linux' = 'linux'): string {\n if (!rootDir || !filePath) {\n throw new Error(`Root and file should be filled in when retrieving the relativePath, ${rootDir || ''} ${filePath || ''}`)\n }\n\n const relativePath = relative(rootDir, filePath)\n\n // On Windows, paths are separated with a \"\\\"\n // However, web browsers use \"/\" no matter the platform\n const slashedPath = slash(relativePath, platform)\n\n if (slashedPath.startsWith('../')) {\n return slashedPath\n }\n\n return `./${slashedPath}`\n}\n","import { mkdir, readFile, writeFile } from 'node:fs/promises'\nimport { dirname, resolve } from 'node:path'\n\ntype Options = { sanity?: boolean }\n\nexport async function write(path: string, data: string, options: Options = {}): Promise<string | undefined> {\n if (data.trim() === '') {\n return undefined\n }\n\n const resolved = resolve(path)\n\n if (typeof Bun !== 'undefined') {\n const file = Bun.file(resolved)\n const oldContent = (await file.exists()) ? await file.text() : null\n if (oldContent === data.trim()) {\n return undefined\n }\n await Bun.write(resolved, data.trim())\n return data.trim()\n }\n\n try {\n const oldContent = await readFile(resolved, { encoding: 'utf-8' })\n if (oldContent?.toString() === data.trim()) {\n return undefined\n }\n } catch (_err) {\n /* file doesn't exist yet */\n }\n\n await mkdir(dirname(resolved), { recursive: true })\n await writeFile(resolved, data.trim(), { encoding: 'utf-8' })\n\n if (options.sanity) {\n const savedData = await readFile(resolved, { encoding: 'utf-8' })\n\n if (savedData?.toString() !== data.trim()) {\n throw new Error(`Sanity check failed for ${path}\\n\\nData[${data.length}]:\\n${data}\\n\\nSaved[${savedData.length}]:\\n${savedData}\\n`)\n }\n\n return savedData\n }\n\n return data.trim()\n}\n"],"mappings":";;;;;;AAEA,eAAsB,MAAM,MAA6B;AACvD,QAAO,GAAG,MAAM;EAAE,WAAW;EAAM,OAAO;EAAM,CAAC;;;;;ACAnD,eAAsB,OAAO,MAAgC;AAC3D,KAAI,OAAO,QAAQ,YACjB,QAAO,IAAI,KAAK,KAAK,CAAC,QAAQ;AAEhC,QAAO,OAAO,KAAK,CAAC,WACZ,YACA,MACP;;;;;ACPH,eAAsB,KAAK,MAA+B;AACxD,KAAI,OAAO,QAAQ,YACjB,QAAO,IAAI,KAAK,KAAK,CAAC,MAAM;AAE9B,QAAO,SAAS,MAAM,EAAE,UAAU,QAAQ,CAAC;;AAG7C,SAAgB,SAAS,MAAsB;AAC7C,QAAO,aAAa,MAAM,EAAE,UAAU,QAAQ,CAAC;;;;;ACTjD,SAAS,MAAM,MAAc,WAAwC,SAAS;CAC5E,MAAM,gBAAgB,YAAY,KAAK,KAAK;CAC5C,MAAM,iBAAiB,UAAU,KAAK;AAEtC,KAAI,CAAC,SAAS,MAAM,CAAC,SAAS,SAAS,IAAI,CAAC,cAE1C,QAAO,eAAe,WAAW,OAAO,IAAI,CAAC,QAAQ,OAAO,GAAG;AAIjE,QAAO,eAAe,WAAW,OAAO,IAAI,CAAC,QAAQ,OAAO,GAAG;;AAGjE,SAAgB,gBAAgB,SAAyB,UAA0B,WAAwC,SAAiB;AAC1I,KAAI,CAAC,WAAW,CAAC,SACf,OAAM,IAAI,MAAM,uEAAuE,WAAW,GAAG,GAAG,YAAY,KAAK;CAO3H,MAAM,cAAc,MAJC,SAAS,SAAS,SAAS,EAIR,SAAS;AAEjD,KAAI,YAAY,WAAW,MAAM,CAC/B,QAAO;AAGT,QAAO,KAAK;;;;;ACzBd,eAAsB,MAAM,MAAc,MAAc,UAAmB,EAAE,EAA+B;AAC1G,KAAI,KAAK,MAAM,KAAK,GAClB;CAGF,MAAM,WAAW,QAAQ,KAAK;AAE9B,KAAI,OAAO,QAAQ,aAAa;EAC9B,MAAM,OAAO,IAAI,KAAK,SAAS;AAE/B,OADoB,MAAM,KAAK,QAAQ,GAAI,MAAM,KAAK,MAAM,GAAG,UAC5C,KAAK,MAAM,CAC5B;AAEF,QAAM,IAAI,MAAM,UAAU,KAAK,MAAM,CAAC;AACtC,SAAO,KAAK,MAAM;;AAGpB,KAAI;AAEF,OADmB,MAAM,SAAS,UAAU,EAAE,UAAU,SAAS,CAAC,GAClD,UAAU,KAAK,KAAK,MAAM,CACxC;UAEK,MAAM;AAIf,OAAM,MAAM,QAAQ,SAAS,EAAE,EAAE,WAAW,MAAM,CAAC;AACnD,OAAM,UAAU,UAAU,KAAK,MAAM,EAAE,EAAE,UAAU,SAAS,CAAC;AAE7D,KAAI,QAAQ,QAAQ;EAClB,MAAM,YAAY,MAAM,SAAS,UAAU,EAAE,UAAU,SAAS,CAAC;AAEjE,MAAI,WAAW,UAAU,KAAK,KAAK,MAAM,CACvC,OAAM,IAAI,MAAM,2BAA2B,KAAK,WAAW,KAAK,OAAO,MAAM,KAAK,YAAY,UAAU,OAAO,MAAM,UAAU,IAAI;AAGrI,SAAO;;AAGT,QAAO,KAAK,MAAM"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kubb/core",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.29.0",
|
|
4
4
|
"description": "Core functionality for Kubb's plugin-based code generation system, providing the foundation for transforming OpenAPI specifications.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"typescript",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
],
|
|
20
20
|
"repository": {
|
|
21
21
|
"type": "git",
|
|
22
|
-
"url": "https://github.com/kubb-labs/kubb.git",
|
|
22
|
+
"url": "git+https://github.com/kubb-labs/kubb.git",
|
|
23
23
|
"directory": "packages/core"
|
|
24
24
|
},
|
|
25
25
|
"license": "MIT",
|
|
@@ -28,30 +28,28 @@
|
|
|
28
28
|
"type": "module",
|
|
29
29
|
"exports": {
|
|
30
30
|
".": {
|
|
31
|
-
"
|
|
32
|
-
"
|
|
31
|
+
"import": "./dist/index.js",
|
|
32
|
+
"require": "./dist/index.cjs"
|
|
33
33
|
},
|
|
34
34
|
"./fs": {
|
|
35
|
-
"
|
|
36
|
-
"
|
|
35
|
+
"import": "./dist/fs.js",
|
|
36
|
+
"require": "./dist/fs.cjs"
|
|
37
37
|
},
|
|
38
38
|
"./hooks": {
|
|
39
|
-
"
|
|
40
|
-
"
|
|
39
|
+
"import": "./dist/hooks.js",
|
|
40
|
+
"require": "./dist/hooks.cjs"
|
|
41
41
|
},
|
|
42
42
|
"./transformers": {
|
|
43
|
-
"
|
|
44
|
-
"
|
|
43
|
+
"import": "./dist/transformers.js",
|
|
44
|
+
"require": "./dist/transformers.cjs"
|
|
45
45
|
},
|
|
46
46
|
"./utils": {
|
|
47
|
-
"
|
|
48
|
-
"
|
|
47
|
+
"import": "./dist/utils.js",
|
|
48
|
+
"require": "./dist/utils.cjs"
|
|
49
49
|
},
|
|
50
50
|
"./package.json": "./package.json"
|
|
51
51
|
},
|
|
52
|
-
"
|
|
53
|
-
"module": "./dist/index.js",
|
|
54
|
-
"types": "./dist/index.d.cts",
|
|
52
|
+
"types": "./dist/index.d.ts",
|
|
55
53
|
"typesVersions": {
|
|
56
54
|
"*": {
|
|
57
55
|
"utils": [
|
|
@@ -86,24 +84,19 @@
|
|
|
86
84
|
}
|
|
87
85
|
],
|
|
88
86
|
"dependencies": {
|
|
89
|
-
"@kubb/react-fabric": "0.
|
|
90
|
-
"
|
|
91
|
-
"execa": "^9.6.1",
|
|
92
|
-
"find-up": "^7.0.0",
|
|
93
|
-
"fs-extra": "^11.3.3",
|
|
87
|
+
"@kubb/react-fabric": "0.13.1",
|
|
88
|
+
"empathic": "^2.0.0",
|
|
94
89
|
"jiti": "2.5.1",
|
|
95
|
-
"js-runtime": "^0.0.8",
|
|
96
|
-
"natural-orderby": "^5.0.0",
|
|
97
|
-
"p-limit": "^7.3.0",
|
|
98
90
|
"remeda": "^2.33.6",
|
|
99
|
-
"semver": "^7.7.4"
|
|
91
|
+
"semver": "^7.7.4",
|
|
92
|
+
"tinyexec": "^1.0.2"
|
|
100
93
|
},
|
|
101
94
|
"devDependencies": {
|
|
102
|
-
"@types/
|
|
103
|
-
"
|
|
95
|
+
"@types/semver": "^7.7.1",
|
|
96
|
+
"p-limit": "^7.3.0"
|
|
104
97
|
},
|
|
105
98
|
"peerDependencies": {
|
|
106
|
-
"@kubb/react-fabric": "0.
|
|
99
|
+
"@kubb/react-fabric": "0.13.0"
|
|
107
100
|
},
|
|
108
101
|
"engines": {
|
|
109
102
|
"node": ">=20"
|
|
@@ -112,6 +105,8 @@
|
|
|
112
105
|
"access": "public",
|
|
113
106
|
"registry": "https://registry.npmjs.org/"
|
|
114
107
|
},
|
|
108
|
+
"main": "./dist/index.cjs",
|
|
109
|
+
"module": "./dist/index.js",
|
|
115
110
|
"scripts": {
|
|
116
111
|
"build": "tsdown && size-limit",
|
|
117
112
|
"clean": "npx rimraf ./dist",
|
package/src/PackageManager.ts
CHANGED
|
@@ -2,7 +2,7 @@ import mod from 'node:module'
|
|
|
2
2
|
import os from 'node:os'
|
|
3
3
|
import { pathToFileURL } from 'node:url'
|
|
4
4
|
|
|
5
|
-
import
|
|
5
|
+
import * as pkg from 'empathic/package'
|
|
6
6
|
import { coerce, satisfies } from 'semver'
|
|
7
7
|
|
|
8
8
|
import { read, readSync } from './fs/index.ts'
|
|
@@ -75,7 +75,7 @@ export class PackageManager {
|
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
async getPackageJSON(): Promise<PackageJSON | undefined> {
|
|
78
|
-
const pkgPath =
|
|
78
|
+
const pkgPath = pkg.up({
|
|
79
79
|
cwd: this.#cwd,
|
|
80
80
|
})
|
|
81
81
|
if (!pkgPath) {
|
|
@@ -88,7 +88,7 @@ export class PackageManager {
|
|
|
88
88
|
}
|
|
89
89
|
|
|
90
90
|
getPackageJSONSync(): PackageJSON | undefined {
|
|
91
|
-
const pkgPath =
|
|
91
|
+
const pkgPath = pkg.up({
|
|
92
92
|
cwd: this.#cwd,
|
|
93
93
|
})
|
|
94
94
|
if (!pkgPath) {
|
package/src/fs/clean.ts
CHANGED
package/src/fs/exists.ts
CHANGED
|
@@ -1,36 +1,16 @@
|
|
|
1
|
-
import fs from 'fs
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
const reader = switcher(
|
|
5
|
-
{
|
|
6
|
-
node: async (path: string) => {
|
|
7
|
-
return fs.pathExists(path)
|
|
8
|
-
},
|
|
9
|
-
bun: async (path: string) => {
|
|
10
|
-
const file = Bun.file(path)
|
|
11
|
-
|
|
12
|
-
return file.exists()
|
|
13
|
-
},
|
|
14
|
-
},
|
|
15
|
-
'node',
|
|
16
|
-
)
|
|
17
|
-
|
|
18
|
-
const syncReader = switcher(
|
|
19
|
-
{
|
|
20
|
-
node: (path: string) => {
|
|
21
|
-
return fs.pathExistsSync(path)
|
|
22
|
-
},
|
|
23
|
-
bun: () => {
|
|
24
|
-
throw new Error('Bun cannot read sync')
|
|
25
|
-
},
|
|
26
|
-
},
|
|
27
|
-
'node',
|
|
28
|
-
)
|
|
1
|
+
import fs from 'node:fs'
|
|
2
|
+
import { access } from 'node:fs/promises'
|
|
29
3
|
|
|
30
4
|
export async function exists(path: string): Promise<boolean> {
|
|
31
|
-
|
|
5
|
+
if (typeof Bun !== 'undefined') {
|
|
6
|
+
return Bun.file(path).exists()
|
|
7
|
+
}
|
|
8
|
+
return access(path).then(
|
|
9
|
+
() => true,
|
|
10
|
+
() => false,
|
|
11
|
+
)
|
|
32
12
|
}
|
|
33
13
|
|
|
34
14
|
export function existsSync(path: string): boolean {
|
|
35
|
-
return
|
|
15
|
+
return fs.existsSync(path)
|
|
36
16
|
}
|
package/src/fs/read.ts
CHANGED
|
@@ -1,36 +1,13 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
const reader = switcher(
|
|
5
|
-
{
|
|
6
|
-
node: async (path: string) => {
|
|
7
|
-
return fs.readFile(path, { encoding: 'utf8' })
|
|
8
|
-
},
|
|
9
|
-
bun: async (path: string) => {
|
|
10
|
-
const file = Bun.file(path)
|
|
11
|
-
|
|
12
|
-
return file.text()
|
|
13
|
-
},
|
|
14
|
-
},
|
|
15
|
-
'node',
|
|
16
|
-
)
|
|
17
|
-
|
|
18
|
-
const syncReader = switcher(
|
|
19
|
-
{
|
|
20
|
-
node: (path: string) => {
|
|
21
|
-
return fs.readFileSync(path, { encoding: 'utf8' })
|
|
22
|
-
},
|
|
23
|
-
bun: () => {
|
|
24
|
-
throw new Error('Bun cannot read sync')
|
|
25
|
-
},
|
|
26
|
-
},
|
|
27
|
-
'node',
|
|
28
|
-
)
|
|
1
|
+
import { readFileSync } from 'node:fs'
|
|
2
|
+
import { readFile } from 'node:fs/promises'
|
|
29
3
|
|
|
30
4
|
export async function read(path: string): Promise<string> {
|
|
31
|
-
|
|
5
|
+
if (typeof Bun !== 'undefined') {
|
|
6
|
+
return Bun.file(path).text()
|
|
7
|
+
}
|
|
8
|
+
return readFile(path, { encoding: 'utf8' })
|
|
32
9
|
}
|
|
33
10
|
|
|
34
11
|
export function readSync(path: string): string {
|
|
35
|
-
return
|
|
12
|
+
return readFileSync(path, { encoding: 'utf8' })
|
|
36
13
|
}
|
package/src/fs/write.ts
CHANGED
|
@@ -1,63 +1,46 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
import fs from 'fs-extra'
|
|
4
|
-
import { switcher } from 'js-runtime'
|
|
1
|
+
import { mkdir, readFile, writeFile } from 'node:fs/promises'
|
|
2
|
+
import { dirname, resolve } from 'node:path'
|
|
5
3
|
|
|
6
4
|
type Options = { sanity?: boolean }
|
|
7
5
|
|
|
8
|
-
const writer = switcher(
|
|
9
|
-
{
|
|
10
|
-
node: async (path: string, data: string, { sanity }: Options) => {
|
|
11
|
-
try {
|
|
12
|
-
const oldContent = await fs.readFile(resolve(path), {
|
|
13
|
-
encoding: 'utf-8',
|
|
14
|
-
})
|
|
15
|
-
if (oldContent?.toString() === data?.toString()) {
|
|
16
|
-
return
|
|
17
|
-
}
|
|
18
|
-
} catch (_err) {
|
|
19
|
-
/* empty */
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
await fs.outputFile(resolve(path), data, { encoding: 'utf-8' })
|
|
23
|
-
|
|
24
|
-
if (sanity) {
|
|
25
|
-
const savedData = await fs.readFile(resolve(path), {
|
|
26
|
-
encoding: 'utf-8',
|
|
27
|
-
})
|
|
28
|
-
|
|
29
|
-
if (savedData?.toString() !== data?.toString()) {
|
|
30
|
-
throw new Error(`Sanity check failed for ${path}\n\nData[${data.length}]:\n${data}\n\nSaved[${savedData.length}]:\n${savedData}\n`)
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
return savedData
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
return data
|
|
37
|
-
},
|
|
38
|
-
bun: async (path: string, data: string, { sanity }: Options) => {
|
|
39
|
-
await Bun.write(resolve(path), data)
|
|
40
|
-
|
|
41
|
-
if (sanity) {
|
|
42
|
-
const file = Bun.file(resolve(path))
|
|
43
|
-
const savedData = await file.text()
|
|
44
|
-
|
|
45
|
-
if (savedData?.toString() !== data?.toString()) {
|
|
46
|
-
throw new Error(`Sanity check failed for ${path}\n\nData[${data.length}]:\n${data}\n\nSaved[${savedData.length}]:\n${savedData}\n`)
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
return savedData
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
return data
|
|
53
|
-
},
|
|
54
|
-
},
|
|
55
|
-
'node',
|
|
56
|
-
)
|
|
57
|
-
|
|
58
6
|
export async function write(path: string, data: string, options: Options = {}): Promise<string | undefined> {
|
|
59
7
|
if (data.trim() === '') {
|
|
60
8
|
return undefined
|
|
61
9
|
}
|
|
62
|
-
|
|
10
|
+
|
|
11
|
+
const resolved = resolve(path)
|
|
12
|
+
|
|
13
|
+
if (typeof Bun !== 'undefined') {
|
|
14
|
+
const file = Bun.file(resolved)
|
|
15
|
+
const oldContent = (await file.exists()) ? await file.text() : null
|
|
16
|
+
if (oldContent === data.trim()) {
|
|
17
|
+
return undefined
|
|
18
|
+
}
|
|
19
|
+
await Bun.write(resolved, data.trim())
|
|
20
|
+
return data.trim()
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
try {
|
|
24
|
+
const oldContent = await readFile(resolved, { encoding: 'utf-8' })
|
|
25
|
+
if (oldContent?.toString() === data.trim()) {
|
|
26
|
+
return undefined
|
|
27
|
+
}
|
|
28
|
+
} catch (_err) {
|
|
29
|
+
/* file doesn't exist yet */
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
await mkdir(dirname(resolved), { recursive: true })
|
|
33
|
+
await writeFile(resolved, data.trim(), { encoding: 'utf-8' })
|
|
34
|
+
|
|
35
|
+
if (options.sanity) {
|
|
36
|
+
const savedData = await readFile(resolved, { encoding: 'utf-8' })
|
|
37
|
+
|
|
38
|
+
if (savedData?.toString() !== data.trim()) {
|
|
39
|
+
throw new Error(`Sanity check failed for ${path}\n\nData[${data.length}]:\n${data}\n\nSaved[${savedData.length}]:\n${savedData}\n`)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return savedData
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return data.trim()
|
|
63
46
|
}
|