@kurone-kito/sea-builder 0.20.0 → 0.20.1-alpha.2

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.
@@ -1 +1 @@
1
- {"version":3,"file":"builder.mjs","sources":["../src/tasks/createBuildTask.mts","../src/tasks/createCacheTask.mts","../src/tasks/createSeaTask.mts","../src/tasks/normalizeBuildOptions.mts","../src/utils/toSemver.mts","../src/utils/resolveNodeVersion.mts","../src/listr2/createBuildTasks.mts","../src/utils/parseArgs.mts","../src/utils/usage.mts","../src/builder.mts"],"sourcesContent":["import type { execa as concretedExeca } from 'execa';\nimport type { Task } from './createTaskFactory.mjs';\n\n/**\n * Create a Listr task for building the project.\n * @param execa The implementation of `execa` to use for running commands.\n * @returns Listr task object.\n */\nexport const createBuildTask = (execa: typeof concretedExeca): Task => ({\n title: 'Build',\n task: () => execa('pnpm', ['run', 'build'], { stdio: 'inherit' }),\n});\n","import { createListrCacheTasks } from '../listr2/createCacheTasks.mjs';\nimport type { CacheOptions } from './createCacheTasks.mjs';\nimport type { Task } from './createTaskFactory.mjs';\n\n/**\n * Create a Listr task for caching Node.js archives.\n * @param opts Options for cache creation including targets.\n * @returns Listr task object.\n */\nexport const createCacheTask = (opts: CacheOptions): Task => ({\n title: 'Download the Node.js archives',\n task: () => createListrCacheTasks(opts).run(),\n});\n","import type { execa as concretedExeca } from 'execa';\nimport { XSEA_PREFIX_ARGS } from '../constants.mts';\nimport type { Task } from './createTaskFactory.mjs';\n\n/**\n * Create a Listr task for linking the SEA binary.\n * @param execa The implementation of `execa` to use for running commands.\n * @param targets Target platform strings.\n * @param basename Output file base name.\n * @returns Listr task object.\n */\nexport const createSeaTask = (\n execa: typeof concretedExeca,\n targets: readonly string[],\n basename: string,\n): Task => {\n const additionalArgs = targets.flatMap((t) => ['-t', t]);\n const args = [...XSEA_PREFIX_ARGS, `sea/${basename}`, ...additionalArgs];\n return {\n title: 'Linking the SEA binary',\n task: () => execa('pnpm', args, { stdio: 'inherit' }),\n };\n};\n","import { existsSync as concretedExistsSync } from 'node:fs';\nimport { mkdir as concretedMkdir } from 'node:fs/promises';\nimport { execa as concretedExeca } from 'execa';\nimport type { BuildTasksOptions } from '../listr2/createBuildTasks.mjs';\nimport type { NormalizedCacheOptions } from './normalizeCacheOptions.mjs';\nimport { normalizeCacheOptions } from './normalizeCacheOptions.mjs';\n\n/** Type definition for options accepted by {@link createBuildTasks}. */\nexport interface NormalizedBuildOptions extends NormalizedCacheOptions {\n /** Output file base name. */\n readonly basename: string;\n\n /** `execa` implementation. */\n readonly execa: typeof concretedExeca;\n}\n\n/**\n * Normalize build options for use in tasks.\n * @param options Options to normalize.\n * @returns Normalized build options.\n */\nexport const normalizeBuildOptions = async (\n options: BuildTasksOptions,\n): Promise<NormalizedBuildOptions> => {\n const { basename, execa = concretedExeca, ...cacheOpts } = options;\n const normalized = normalizeCacheOptions({\n arch: cacheOpts.arch,\n download: cacheOpts.download,\n existsSync: cacheOpts.existsSync ?? concretedExistsSync,\n mkdir: cacheOpts.mkdir ?? concretedMkdir,\n nodeVersion: cacheOpts.nodeVersion,\n platform: cacheOpts.platform,\n projectRoot: cacheOpts.projectRoot,\n targets: cacheOpts.targets,\n });\n return { ...normalized, basename, execa };\n};\n","import type { MajorNodeVersion } from 'all-node-versions';\n\n/**\n * Convert a version specification to a semver range.\n * @param spec Version specification, e.g. `20`, `20.11`, `22.1.0`, etc.\n * @param versions Object containing available Node.js versions.\n * @returns Semver range string, e.g. `^20`, `~20.11`, etc.\n */\nexport const toSemver = (\n spec?: string | undefined,\n majors: readonly Pick<MajorNodeVersion, 'lts' | 'major'>[] = [],\n): string => {\n if (!spec) {\n const ver = majors.filter(({ lts }) => lts).at(-1)?.major;\n return ver ? `^${ver}` : '*';\n }\n if (/^\\d+\\.\\d+$/.test(spec)) {\n return `~${spec}`;\n }\n if (/^\\d+$/.test(spec)) {\n return `^${spec}`;\n }\n return spec;\n};\n","import allNodeVersions from 'all-node-versions';\nimport type { SemverVersion } from 'all-node-versions';\nimport { rcompare, satisfies } from 'semver';\nimport { toSemver } from './toSemver.mjs';\n\n/**\n * Resolve Node.js version from a version specification.\n * @param spec Version specification, e.g. `20`, `20.11`, `22.1.0`, etc.\n * If not specified, the latest patch version of the oldest LTS is used.\n * @returns Resolved Node.js version, e.g. `v20.12.0`.\n */\nexport const resolveNodeVersion = async (\n spec?: string | undefined,\n): Promise<`v${SemverVersion}`> => {\n const { majors, versions } = await allNodeVersions({ fetch: false });\n const range = toSemver(spec, majors);\n const resolved = versions\n .map(({ node }) => node)\n .filter((v) => satisfies(v, range))\n .sort(rcompare)[0];\n if (!resolved) {\n throw new Error(`Unsupported Node.js version: ${spec ?? ''}`);\n }\n return `v${resolved}`;\n};\n","import type { execa as concretedExeca } from 'execa';\nimport { Listr } from 'listr2';\nimport { createBuildTask } from '../tasks/createBuildTask.mjs';\nimport { createCacheTask } from '../tasks/createCacheTask.mjs';\nimport type { CacheOptions } from '../tasks/createCacheTasks.mjs';\nimport { createSeaTask } from '../tasks/createSeaTask.mjs';\nimport { normalizeBuildOptions } from '../tasks/normalizeBuildOptions.mjs';\nimport { resolveNodeVersion } from '../utils/resolveNodeVersion.mjs';\n\n/** Options accepted by {@link createBuildTasks}. */\nexport interface BuildTasksOptions extends CacheOptions {\n /** `execa` implementation. */\n readonly execa?: typeof concretedExeca | undefined;\n\n /** Output file base name. */\n readonly basename: string;\n}\n\n/**\n * Execute SEA build process.\n *\n * This function runs a series of tasks to build the project, download\n * required Node.js archives and finally generate the SEA binary.\n * @param options Options controlling the build behaviour.\n */\nexport const createBuildTasks = async (\n options: BuildTasksOptions,\n): Promise<Listr> => {\n const { arch, platform = process.platform, projectRoot } = options;\n const { basename, download, execa, existsSync, mkdir, nodeVersion, targets } =\n await normalizeBuildOptions(options);\n return new Listr([\n createBuildTask(execa),\n createCacheTask({\n arch,\n download,\n existsSync,\n mkdir,\n nodeVersion: await resolveNodeVersion(nodeVersion),\n platform,\n projectRoot,\n targets,\n }),\n createSeaTask(execa, targets, basename),\n ]);\n};\n","import type { ParseArgsConfig } from 'node:util';\nimport { parseArgs as innerParseArgs } from 'node:util';\n\n/** Type definition for parsed CLI arguments. */\nexport interface HelpParsedArgs {\n /** Indicates that help was requested. */\n readonly help: true;\n}\n\n/** Type definition for parsed CLI arguments. */\nexport interface TargetsParsedArgs {\n /** The base name for the output file. */\n readonly basename: string;\n\n /** Indicates that help was not requested. */\n readonly help: false;\n\n /** Node.js version specification. */\n readonly nodeVersion?: string | undefined;\n\n /** A list of target platforms. */\n readonly targets: readonly string[];\n}\n\n/** Static configuration for CLI argument parsing. */\nconst staticConfig = {\n allowPositionals: true,\n options: {\n help: { default: false, short: 'h', type: 'boolean' },\n node: { type: 'string' },\n targets: { type: 'string' },\n },\n} as const satisfies ParseArgsConfig;\n\n/**\n * Parse CLI arguments into options for {@link run}.\n * @param argv CLI arguments.\n * @returns Parsed values.\n */\nexport const parseArgs = (\n argv: readonly string[],\n): HelpParsedArgs | TargetsParsedArgs => {\n const {\n values,\n positionals: [basename],\n } = innerParseArgs({ ...staticConfig, args: [...argv] });\n if (values.help) {\n return { help: true };\n }\n if (!basename) {\n throw new Error('Output file base name is required');\n }\n const { node: nodeVersion, targets: rawTargets } = values;\n const targets = rawTargets?.split(',').filter(Boolean) ?? [];\n return { basename, help: false, nodeVersion, targets };\n};\n","/** Display help message. */\nexport const usage = (): void =>\n console.log(\n 'Usage: sea-builder --targets=<target>[,<target>[,...]] [--node=<version>] <output>',\n );\n","#!/usr/bin/env node --enable-source-maps\n\nimport { isNativeError } from 'node:util/types';\nimport { createBuildTasks } from './listr2/createBuildTasks.mjs';\nimport { parseArgs } from './utils/parseArgs.mjs';\nimport { runIfMain } from './utils/runIfMain.mjs';\nimport { usage } from './utils/usage.mjs';\n\n/**\n * Main function to create and run build tasks.\n * @param rawArgs The raw command line arguments passed to the script.\n */\nexport const main = async (...rawArgs: readonly string[]): Promise<void> => {\n try {\n const args = parseArgs(rawArgs);\n if (args.help) {\n usage();\n } else {\n await (await createBuildTasks(args)).run();\n }\n } catch (err) {\n if (isNativeError(err)) {\n console.error(err.message);\n }\n process.exitCode = 1;\n }\n};\n\nrunIfMain(import.meta.url, main);\n"],"names":["execa","concretedExeca","concretedExistsSync","concretedMkdir","existsSync","mkdir","innerParseArgs"],"mappings":"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"}
1
+ {"version":3,"file":"builder.mjs","sources":["../src/tasks/createBuildTask.mts","../src/tasks/createCacheTask.mts","../src/tasks/createSeaTask.mts","../src/tasks/normalizeBuildOptions.mts","../src/utils/toSemver.mts","../src/utils/resolveNodeVersion.mts","../src/listr2/createBuildTasks.mts","../src/utils/parseArgs.mts","../src/utils/usage.mts","../src/builder.mts"],"sourcesContent":["import type { execa as concretedExeca } from 'execa';\nimport type { Task } from './createTaskFactory.mjs';\n\n/**\n * Create a Listr task for building the project.\n * @param execa The implementation of `execa` to use for running commands.\n * @returns Listr task object.\n */\nexport const createBuildTask = (execa: typeof concretedExeca): Task => ({\n title: 'Build',\n task: () => execa('pnpm', ['run', 'build'], { stdio: 'inherit' }),\n});\n","import { createListrCacheTasks } from '../listr2/createCacheTasks.mjs';\nimport type { CacheOptions } from './createCacheTasks.mjs';\nimport type { Task } from './createTaskFactory.mjs';\n\n/**\n * Create a Listr task for caching Node.js archives.\n * @param opts Options for cache creation including targets.\n * @returns Listr task object.\n */\nexport const createCacheTask = (opts: CacheOptions): Task => ({\n title: 'Download the Node.js archives',\n task: () => createListrCacheTasks(opts).run(),\n});\n","import type { execa as concretedExeca } from 'execa';\nimport { XSEA_PREFIX_ARGS } from '../constants.mts';\nimport type { Task } from './createTaskFactory.mjs';\n\n/**\n * Create a Listr task for linking the SEA binary.\n * @param execa The implementation of `execa` to use for running commands.\n * @param targets Target platform strings.\n * @param basename Output file base name.\n * @returns Listr task object.\n */\nexport const createSeaTask = (\n execa: typeof concretedExeca,\n targets: readonly string[],\n basename: string,\n): Task => {\n const additionalArgs = targets.flatMap((t) => ['-t', t]);\n const args = [...XSEA_PREFIX_ARGS, `sea/${basename}`, ...additionalArgs];\n return {\n title: 'Linking the SEA binary',\n task: () => execa('pnpm', args, { stdio: 'inherit' }),\n };\n};\n","import { existsSync as concretedExistsSync } from 'node:fs';\nimport { mkdir as concretedMkdir } from 'node:fs/promises';\nimport { execa as concretedExeca } from 'execa';\nimport type { BuildTasksOptions } from '../listr2/createBuildTasks.mjs';\nimport type { NormalizedCacheOptions } from './normalizeCacheOptions.mjs';\nimport { normalizeCacheOptions } from './normalizeCacheOptions.mjs';\n\n/** Type definition for options accepted by {@link createBuildTasks}. */\nexport interface NormalizedBuildOptions extends NormalizedCacheOptions {\n /** Output file base name. */\n readonly basename: string;\n\n /** `execa` implementation. */\n readonly execa: typeof concretedExeca;\n}\n\n/**\n * Normalize build options for use in tasks.\n * @param options Options to normalize.\n * @returns Normalized build options.\n */\nexport const normalizeBuildOptions = async (\n options: BuildTasksOptions,\n): Promise<NormalizedBuildOptions> => {\n const { basename, execa = concretedExeca, ...cacheOpts } = options;\n const normalized = normalizeCacheOptions({\n arch: cacheOpts.arch,\n download: cacheOpts.download,\n existsSync: cacheOpts.existsSync ?? concretedExistsSync,\n mkdir: cacheOpts.mkdir ?? concretedMkdir,\n nodeVersion: cacheOpts.nodeVersion,\n platform: cacheOpts.platform,\n projectRoot: cacheOpts.projectRoot,\n targets: cacheOpts.targets,\n });\n return { ...normalized, basename, execa };\n};\n","import type { MajorNodeVersion } from 'all-node-versions';\n\n/**\n * Convert a version specification to a semver range.\n * @param spec Version specification, e.g. `20`, `20.11`, `22.1.0`, etc.\n * @param versions Object containing available Node.js versions.\n * @returns Semver range string, e.g. `^20`, `~20.11`, etc.\n */\nexport const toSemver = (\n spec?: string | undefined,\n majors: readonly Pick<MajorNodeVersion, 'lts' | 'major'>[] = [],\n): string => {\n if (!spec) {\n const ver = majors.filter(({ lts }) => lts).at(-1)?.major;\n return ver ? `^${ver}` : '*';\n }\n if (/^\\d+\\.\\d+$/.test(spec)) {\n return `~${spec}`;\n }\n if (/^\\d+$/.test(spec)) {\n return `^${spec}`;\n }\n return spec;\n};\n","import type { SemverVersion } from 'all-node-versions';\nimport allNodeVersions from 'all-node-versions';\nimport { rcompare, satisfies } from 'semver';\nimport { toSemver } from './toSemver.mjs';\n\n/**\n * Resolve Node.js version from a version specification.\n * @param spec Version specification, e.g. `20`, `20.11`, `22.1.0`, etc.\n * If not specified, the latest patch version of the oldest LTS is used.\n * @returns Resolved Node.js version, e.g. `v20.12.0`.\n */\nexport const resolveNodeVersion = async (\n spec?: string | undefined,\n): Promise<`v${SemverVersion}`> => {\n const { majors, versions } = await allNodeVersions({ fetch: false });\n const range = toSemver(spec, majors);\n const resolved = versions\n .map(({ node }) => node)\n .filter((v) => satisfies(v, range))\n .sort(rcompare)[0];\n if (!resolved) {\n throw new Error(`Unsupported Node.js version: ${spec ?? ''}`);\n }\n return `v${resolved}`;\n};\n","import type { execa as concretedExeca } from 'execa';\nimport { Listr } from 'listr2';\nimport { createBuildTask } from '../tasks/createBuildTask.mjs';\nimport { createCacheTask } from '../tasks/createCacheTask.mjs';\nimport type { CacheOptions } from '../tasks/createCacheTasks.mjs';\nimport { createSeaTask } from '../tasks/createSeaTask.mjs';\nimport { normalizeBuildOptions } from '../tasks/normalizeBuildOptions.mjs';\nimport { resolveNodeVersion } from '../utils/resolveNodeVersion.mjs';\n\n/** Options accepted by {@link createBuildTasks}. */\nexport interface BuildTasksOptions extends CacheOptions {\n /** `execa` implementation. */\n readonly execa?: typeof concretedExeca | undefined;\n\n /** Output file base name. */\n readonly basename: string;\n}\n\n/**\n * Execute SEA build process.\n *\n * This function runs a series of tasks to build the project, download\n * required Node.js archives and finally generate the SEA binary.\n * @param options Options controlling the build behaviour.\n */\nexport const createBuildTasks = async (\n options: BuildTasksOptions,\n): Promise<Listr> => {\n const { arch, platform = process.platform, projectRoot } = options;\n const { basename, download, execa, existsSync, mkdir, nodeVersion, targets } =\n await normalizeBuildOptions(options);\n return new Listr([\n createBuildTask(execa),\n createCacheTask({\n arch,\n download,\n existsSync,\n mkdir,\n nodeVersion: await resolveNodeVersion(nodeVersion),\n platform,\n projectRoot,\n targets,\n }),\n createSeaTask(execa, targets, basename),\n ]);\n};\n","import type { ParseArgsConfig } from 'node:util';\nimport { parseArgs as innerParseArgs } from 'node:util';\n\n/** Type definition for parsed CLI arguments. */\nexport interface HelpParsedArgs {\n /** Indicates that help was requested. */\n readonly help: true;\n}\n\n/** Type definition for parsed CLI arguments. */\nexport interface TargetsParsedArgs {\n /** The base name for the output file. */\n readonly basename: string;\n\n /** Indicates that help was not requested. */\n readonly help: false;\n\n /** Node.js version specification. */\n readonly nodeVersion?: string | undefined;\n\n /** A list of target platforms. */\n readonly targets: readonly string[];\n}\n\n/** Static configuration for CLI argument parsing. */\nconst staticConfig = {\n allowPositionals: true,\n options: {\n help: { default: false, short: 'h', type: 'boolean' },\n node: { type: 'string' },\n targets: { type: 'string' },\n },\n} as const satisfies ParseArgsConfig;\n\n/**\n * Parse CLI arguments into options for {@link run}.\n * @param argv CLI arguments.\n * @returns Parsed values.\n */\nexport const parseArgs = (\n argv: readonly string[],\n): HelpParsedArgs | TargetsParsedArgs => {\n const {\n values,\n positionals: [basename],\n } = innerParseArgs({ ...staticConfig, args: [...argv] });\n if (values.help) {\n return { help: true };\n }\n if (!basename) {\n throw new Error('Output file base name is required');\n }\n const { node: nodeVersion, targets: rawTargets } = values;\n const targets = rawTargets?.split(',').filter(Boolean) ?? [];\n return { basename, help: false, nodeVersion, targets };\n};\n","/** Display help message. */\nexport const usage = (): void =>\n console.log(\n 'Usage: sea-builder --targets=<target>[,<target>[,...]] [--node=<version>] <output>',\n );\n","#!/usr/bin/env node --enable-source-maps\n\nimport { isNativeError } from 'node:util/types';\nimport { createBuildTasks } from './listr2/createBuildTasks.mjs';\nimport { parseArgs } from './utils/parseArgs.mjs';\nimport { runIfMain } from './utils/runIfMain.mjs';\nimport { usage } from './utils/usage.mjs';\n\n/**\n * Main function to create and run build tasks.\n * @param rawArgs The raw command line arguments passed to the script.\n */\nexport const main = async (...rawArgs: readonly string[]): Promise<void> => {\n try {\n const args = parseArgs(rawArgs);\n if (args.help) {\n usage();\n } else {\n await (await createBuildTasks(args)).run();\n }\n } catch (err) {\n if (isNativeError(err)) {\n console.error(err.message);\n }\n process.exitCode = 1;\n }\n};\n\nrunIfMain(import.meta.url, main);\n"],"names":["execa","concretedExeca","concretedExistsSync","concretedMkdir","existsSync","mkdir","innerParseArgs"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"runIfMain.mjs","sources":["../src/tasks/createMetaFactory.mts","../src/tasks/createTaskFactory.mts","../src/utils/downloadArchive.mts","../src/utils/normalizeTargets.mts","../src/constants.mts","../src/utils/findProjectRoot.mts","../src/utils/resolveCacheDir.mts","../src/tasks/normalizeCacheOptions.mts","../src/tasks/createCacheTasks.mts","../src/listr2/createCacheTasks.mts","../src/utils/runIfMain.mts"],"sourcesContent":["import { join } from 'node:path';\n\n/** Metadata for a Node.js archive. */\nexport interface ArchiveMeta {\n /** Local archive path. */\n readonly archivePath: string;\n\n /** Target string such as `linux-x64`. */\n readonly target: string;\n\n /** Download URL of the archive. */\n readonly url: string;\n}\n\n/**\n * Create a function that generates metadata for a given target.\n * @param cacheDir Directory to store archives in.\n * @param nodeVersion Node.js version string.\n * @returns Function producing {@link ArchiveMeta} objects.\n */\nexport const createMetaFactory =\n (cacheDir: string, nodeVersion: string) =>\n (target: string): ArchiveMeta => {\n const ext = target.startsWith('win') ? 'zip' : 'tar.gz';\n const archive = `node-${nodeVersion}-${target}.${ext}`;\n return {\n target,\n archivePath: join(cacheDir, archive),\n url: `https://nodejs.org/dist/${nodeVersion}/${archive}`,\n };\n };\n","import type {\n existsSync as concretedExistsSync,\n mkdirSync as concretedMkdirSync,\n} from 'node:fs';\nimport type { mkdir as concretedMkdir } from 'node:fs/promises';\nimport type { DownloadFunction } from '../utils/types.mjs';\nimport type { ArchiveMeta } from './createMetaFactory.mjs';\n\n/** Type definition for a Listr task that downloads Node.js archives. */\nexport interface Task {\n /** Function that performs the download task. */\n readonly task: () => Promise<unknown>;\n\n /** Title of the task displayed in the Listr output. */\n readonly title: string;\n}\n\n/**\n * Create a function that converts metadata into a Listr task.\n * @param download File download function.\n * @param existsSync File existence check function.\n * @param mkdir Directory creation function.\n * @param cacheDir Directory for cached archives.\n * @returns Function producing Listr tasks.\n */\nexport const createTaskFactory =\n (\n download: DownloadFunction,\n existsSync: typeof concretedExistsSync,\n mkdir: typeof concretedMkdirSync | typeof concretedMkdir,\n cacheDir: string,\n ) =>\n (meta: ArchiveMeta): Task => {\n const { target: title, archivePath, url } = meta;\n return {\n task: async () => {\n await mkdir(cacheDir, { recursive: true });\n if (!existsSync(archivePath)) {\n await download(url, archivePath);\n }\n },\n title,\n };\n };\n","import { createWriteStream } from 'node:fs';\nimport { pipeline } from 'node:stream/promises';\nimport type { DownloadFunction } from './types.mjs';\n\n/**\n * Download Node.js archive.\n * @param url Source URL.\n * @param dest Destination file path.\n */\nexport const downloadArchive: DownloadFunction = async (url, dest) => {\n const response = await fetch(url);\n if (!response.body) {\n throw new Error('Response body is empty');\n }\n // @ts-expect-error\n await pipeline(response.body, createWriteStream(dest));\n};\n","/**\n * Normalize target list for SEA build.\n *\n * When {@link targets} is empty, this function falls back to the current\n * {@link platform} and {@link arch} to create a single target string.\n * @param targets Target strings such as `linux-x64`.\n * @param platform Host platform name.\n * @param arch Host architecture name.\n * @returns Normalized target array.\n */\nexport const normalizeTargets = (\n targets: readonly string[],\n platform: NodeJS.Platform,\n arch: string,\n): readonly string[] =>\n targets.length ? [...targets] : [`${platform}-${arch}` as const];\n","import { join } from 'node:path';\n\n/** Default cache directory used to store Node.js archives. */\nexport const CACHE_DIR = join('node_modules', '.cache', 'xsea');\n\n/**\n * Common prefix arguments passed to the `xsea` CLI.\n * These arguments point to the build output entry file and specify\n * the output location for the resulting SEA binary.\n */\nexport const XSEA_PREFIX_ARGS = [\n 'exec',\n 'xsea',\n 'dist/index.mjs',\n '-o',\n] as const;\n","import { dirname, join } from 'node:path';\nimport type { ExistsSync } from './types.mjs';\n\n/**\n * Find the project root by looking for package.json or node_modules.\n * @param startPath Starting directory path.\n * @param existsSync File existence check function.\n * @returns Project root directory path.\n */\nexport const findProjectRoot = (\n startPath: string,\n existsSync: ExistsSync,\n): string => {\n let currentPath = startPath;\n let parentPath = dirname(currentPath);\n\n while (currentPath !== parentPath) {\n if (\n existsSync(join(currentPath, 'package.json')) ||\n existsSync(join(currentPath, 'node_modules'))\n ) {\n return currentPath;\n }\n currentPath = parentPath;\n parentPath = dirname(currentPath);\n }\n\n // If no project root is found, fall back to the starting path\n return startPath;\n};\n","import { join } from 'node:path';\nimport { CACHE_DIR } from '../constants.mjs';\nimport { findProjectRoot } from './findProjectRoot.mjs';\nimport type { ExistsSync } from './types.mjs';\n\n/**\n * Resolve the cache directory path.\n * @param cwd Current working directory.\n * @param existsSync Implementation of {@link ExistsSync}.\n * @param projectRoot Optional project root. When omitted it will be detected.\n * @returns Path to the cache directory.\n */\nexport const resolveCacheDir = (\n cwd: string,\n existsSync: ExistsSync,\n projectRoot?: string | undefined,\n): string => join(projectRoot ?? findProjectRoot(cwd, existsSync), CACHE_DIR);\n","import { existsSync as concretedExistsSync } from 'node:fs';\nimport { mkdir as concretedMkdir } from 'node:fs/promises';\nimport type { Except, SetNonNullable } from 'type-fest';\nimport { downloadArchive } from '../utils/downloadArchive.mjs';\nimport { normalizeTargets } from '../utils/normalizeTargets.mjs';\nimport { resolveCacheDir } from '../utils/resolveCacheDir.mjs';\nimport type { CacheOptions } from './createCacheTasks.mjs';\n\n/** Type definition for options accepted by {@link normalizeCacheOptions}. */\nexport interface NormalizedCacheOptions\n extends Except<SetNonNullable<Required<CacheOptions>>, 'projectRoot'> {\n /** Directory path where Node.js archives are cached. */\n readonly cacheDir: string;\n}\n\n/**\n * Normalize cache options for use in tasks.\n * @param options Options to normalize.\n * @param cwd Current working directory. Defaults to `process.cwd()`.\n * @returns Normalized cache options.\n */\nexport const normalizeCacheOptions = (\n options: CacheOptions,\n cwd: string = process.cwd(),\n): NormalizedCacheOptions => {\n const {\n arch = process.arch,\n download = downloadArchive,\n existsSync = concretedExistsSync,\n mkdir = concretedMkdir,\n nodeVersion = `v${process.versions.node}`,\n platform = process.platform,\n projectRoot,\n targets = [],\n } = options;\n return {\n cacheDir: resolveCacheDir(cwd, existsSync, projectRoot),\n arch,\n platform,\n nodeVersion,\n targets: normalizeTargets(targets, platform, arch),\n download,\n existsSync,\n mkdir,\n };\n};\n","import type { Listr } from 'listr2';\nimport type { DownloadFunction, ExistsSync, Mkdir } from '../utils/types.mjs';\nimport { createMetaFactory } from './createMetaFactory.mjs';\nimport type { Task } from './createTaskFactory.mjs';\nimport { createTaskFactory } from './createTaskFactory.mjs';\nimport { normalizeCacheOptions } from './normalizeCacheOptions.mjs';\n\n/** Options accepted by {@link cache} and {@link createCacheTasks}. */\nexport interface CacheOptions {\n /** Architecture identifier. */\n readonly arch?: string | undefined;\n\n /** File download function used to fetch archives. */\n readonly download?: DownloadFunction | undefined;\n\n /** `fs.existsSync` implementation. */\n readonly existsSync?: ExistsSync | undefined;\n\n /** `fs.mkdir` implementation. */\n readonly mkdir?: Mkdir | undefined;\n\n /** Node.js version string. */\n readonly nodeVersion?: string | undefined;\n\n /** Platform identifier. */\n readonly platform?: NodeJS.Platform | undefined;\n\n /** Project root directory path. If not provided, will be auto-detected. */\n readonly projectRoot?: string | undefined;\n\n /** Target strings such as `linux-x64`. */\n readonly targets?: readonly string[] | undefined;\n}\n\n/**\n * Create Listr tasks for downloading Node.js archives.\n * @param options Options controlling the task generation.\n * @returns Configured {@link Listr} instance.\n */\nexport const createCacheTasks = (options: CacheOptions = {}): Task[] => {\n const { cacheDir, download, existsSync, mkdir, nodeVersion, targets } =\n normalizeCacheOptions(options);\n const metaFor = createMetaFactory(cacheDir, nodeVersion);\n const toTask = createTaskFactory(download, existsSync, mkdir, cacheDir);\n return targets.map((t) => toTask(metaFor(t)));\n};\n","import { Listr } from 'listr2';\nimport type { CacheOptions } from '../tasks/createCacheTasks.mjs';\nimport { createCacheTasks } from '../tasks/createCacheTasks.mjs';\n\n/**\n * Create Listr tasks for downloading Node.js archives.\n * @param options Options controlling the task generation.\n * @returns Configured {@link Listr} instance.\n */\nexport const createListrCacheTasks = (options: CacheOptions = {}): Listr =>\n new Listr(createCacheTasks(options), { concurrent: true });\n","import { realpathSync } from 'node:fs';\nimport { fileURLToPath } from 'node:url';\n\n/**\n * Type definition for the main function executed when the module is run\n * as a script.\n */\nexport type MainFunction = (...args: readonly string[]) => Promise<void>;\n\n/**\n * Execute the provided {@link main} function when the current module is\n * the entry point.\n * @param url Value of `import.meta.url` from the caller.\n * @param main Function executed with CLI arguments.\n */\nexport const runIfMain = (url: string, main: MainFunction): Promise<void> => {\n const [, bin = '', ...args] = process.argv;\n return realpathSync(bin) === fileURLToPath(url)\n ? main(...args)\n : Promise.resolve();\n};\n"],"names":["existsSync","mkdir","concretedExistsSync","concretedMkdir"],"mappings":"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"}
1
+ {"version":3,"file":"runIfMain.mjs","sources":["../src/tasks/createMetaFactory.mts","../src/tasks/createTaskFactory.mts","../src/utils/downloadArchive.mts","../src/utils/normalizeTargets.mts","../src/constants.mts","../src/utils/findProjectRoot.mts","../src/utils/resolveCacheDir.mts","../src/tasks/normalizeCacheOptions.mts","../src/tasks/createCacheTasks.mts","../src/listr2/createCacheTasks.mts","../src/utils/runIfMain.mts"],"sourcesContent":["import { join } from 'node:path';\n\n/** Metadata for a Node.js archive. */\nexport interface ArchiveMeta {\n /** Local archive path. */\n readonly archivePath: string;\n\n /** Target string such as `linux-x64`. */\n readonly target: string;\n\n /** Download URL of the archive. */\n readonly url: string;\n}\n\n/**\n * Create a function that generates metadata for a given target.\n * @param cacheDir Directory to store archives in.\n * @param nodeVersion Node.js version string.\n * @returns Function producing {@link ArchiveMeta} objects.\n */\nexport const createMetaFactory =\n (cacheDir: string, nodeVersion: string) =>\n (target: string): ArchiveMeta => {\n const ext = target.startsWith('win') ? 'zip' : 'tar.gz';\n const archive = `node-${nodeVersion}-${target}.${ext}`;\n return {\n target,\n archivePath: join(cacheDir, archive),\n url: `https://nodejs.org/dist/${nodeVersion}/${archive}`,\n };\n };\n","import type {\n existsSync as concretedExistsSync,\n mkdirSync as concretedMkdirSync,\n} from 'node:fs';\nimport type { mkdir as concretedMkdir } from 'node:fs/promises';\nimport type { DownloadFunction } from '../utils/types.mjs';\nimport type { ArchiveMeta } from './createMetaFactory.mjs';\n\n/** Type definition for a Listr task that downloads Node.js archives. */\nexport interface Task {\n /** Function that performs the download task. */\n readonly task: () => Promise<unknown>;\n\n /** Title of the task displayed in the Listr output. */\n readonly title: string;\n}\n\n/**\n * Create a function that converts metadata into a Listr task.\n * @param download File download function.\n * @param existsSync File existence check function.\n * @param mkdir Directory creation function.\n * @param cacheDir Directory for cached archives.\n * @returns Function producing Listr tasks.\n */\nexport const createTaskFactory =\n (\n download: DownloadFunction,\n existsSync: typeof concretedExistsSync,\n mkdir: typeof concretedMkdirSync | typeof concretedMkdir,\n cacheDir: string,\n ) =>\n (meta: ArchiveMeta): Task => {\n const { target: title, archivePath, url } = meta;\n return {\n task: async () => {\n await mkdir(cacheDir, { recursive: true });\n if (!existsSync(archivePath)) {\n await download(url, archivePath);\n }\n },\n title,\n };\n };\n","import { createWriteStream } from 'node:fs';\nimport { pipeline } from 'node:stream/promises';\nimport type { DownloadFunction } from './types.mjs';\n\n/**\n * Download Node.js archive.\n * @param url Source URL.\n * @param dest Destination file path.\n */\nexport const downloadArchive: DownloadFunction = async (url, dest) => {\n const response = await fetch(url);\n if (!response.body) {\n throw new Error('Response body is empty');\n }\n // @ts-expect-error\n await pipeline(response.body, createWriteStream(dest));\n};\n","/**\n * Normalize target list for SEA build.\n *\n * When {@link targets} is empty, this function falls back to the current\n * {@link platform} and {@link arch} to create a single target string.\n * @param targets Target strings such as `linux-x64`.\n * @param platform Host platform name.\n * @param arch Host architecture name.\n * @returns Normalized target array.\n */\nexport const normalizeTargets = (\n targets: readonly string[],\n platform: NodeJS.Platform,\n arch: string,\n): readonly string[] =>\n targets.length ? [...targets] : [`${platform}-${arch}` as const];\n","import { join } from 'node:path';\n\n/** Default cache directory used to store Node.js archives. */\nexport const CACHE_DIR = join('node_modules', '.cache', 'xsea');\n\n/**\n * Common prefix arguments passed to the `xsea` CLI.\n * These arguments point to the build output entry file and specify\n * the output location for the resulting SEA binary.\n */\nexport const XSEA_PREFIX_ARGS = [\n 'exec',\n 'xsea',\n 'dist/index.mjs',\n '-o',\n] as const;\n","import { dirname, join } from 'node:path';\nimport type { ExistsSync } from './types.mjs';\n\n/**\n * Find the project root by looking for package.json or node_modules.\n * @param startPath Starting directory path.\n * @param existsSync File existence check function.\n * @returns Project root directory path.\n */\nexport const findProjectRoot = (\n startPath: string,\n existsSync: ExistsSync,\n): string => {\n let currentPath = startPath;\n let parentPath = dirname(currentPath);\n\n while (currentPath !== parentPath) {\n if (\n existsSync(join(currentPath, 'package.json')) ||\n existsSync(join(currentPath, 'node_modules'))\n ) {\n return currentPath;\n }\n currentPath = parentPath;\n parentPath = dirname(currentPath);\n }\n\n // If no project root is found, fall back to the starting path\n return startPath;\n};\n","import { join } from 'node:path';\nimport { CACHE_DIR } from '../constants.mjs';\nimport { findProjectRoot } from './findProjectRoot.mjs';\nimport type { ExistsSync } from './types.mjs';\n\n/**\n * Resolve the cache directory path.\n * @param cwd Current working directory.\n * @param existsSync Implementation of {@link ExistsSync}.\n * @param projectRoot Optional project root. When omitted it will be detected.\n * @returns Path to the cache directory.\n */\nexport const resolveCacheDir = (\n cwd: string,\n existsSync: ExistsSync,\n projectRoot?: string | undefined,\n): string => join(projectRoot ?? findProjectRoot(cwd, existsSync), CACHE_DIR);\n","import { existsSync as concretedExistsSync } from 'node:fs';\nimport { mkdir as concretedMkdir } from 'node:fs/promises';\nimport type { Except, SetNonNullable } from 'type-fest';\nimport { downloadArchive } from '../utils/downloadArchive.mjs';\nimport { normalizeTargets } from '../utils/normalizeTargets.mjs';\nimport { resolveCacheDir } from '../utils/resolveCacheDir.mjs';\nimport type { CacheOptions } from './createCacheTasks.mjs';\n\n/** Type definition for options accepted by {@link normalizeCacheOptions}. */\nexport interface NormalizedCacheOptions\n extends Except<SetNonNullable<Required<CacheOptions>>, 'projectRoot'> {\n /** Directory path where Node.js archives are cached. */\n readonly cacheDir: string;\n}\n\n/**\n * Normalize cache options for use in tasks.\n * @param options Options to normalize.\n * @param cwd Current working directory. Defaults to `process.cwd()`.\n * @returns Normalized cache options.\n */\nexport const normalizeCacheOptions = (\n options: CacheOptions,\n cwd: string = process.cwd(),\n): NormalizedCacheOptions => {\n const {\n arch = process.arch,\n download = downloadArchive,\n existsSync = concretedExistsSync,\n mkdir = concretedMkdir,\n nodeVersion = `v${process.versions.node}`,\n platform = process.platform,\n projectRoot,\n targets = [],\n } = options;\n return {\n cacheDir: resolveCacheDir(cwd, existsSync, projectRoot),\n arch,\n platform,\n nodeVersion,\n targets: normalizeTargets(targets, platform, arch),\n download,\n existsSync,\n mkdir,\n };\n};\n","import type { Listr } from 'listr2';\nimport type { DownloadFunction, ExistsSync, Mkdir } from '../utils/types.mjs';\nimport { createMetaFactory } from './createMetaFactory.mjs';\nimport type { Task } from './createTaskFactory.mjs';\nimport { createTaskFactory } from './createTaskFactory.mjs';\nimport { normalizeCacheOptions } from './normalizeCacheOptions.mjs';\n\n/** Options accepted by {@link cache} and {@link createCacheTasks}. */\nexport interface CacheOptions {\n /** Architecture identifier. */\n readonly arch?: string | undefined;\n\n /** File download function used to fetch archives. */\n readonly download?: DownloadFunction | undefined;\n\n /** `fs.existsSync` implementation. */\n readonly existsSync?: ExistsSync | undefined;\n\n /** `fs.mkdir` implementation. */\n readonly mkdir?: Mkdir | undefined;\n\n /** Node.js version string. */\n readonly nodeVersion?: string | undefined;\n\n /** Platform identifier. */\n readonly platform?: NodeJS.Platform | undefined;\n\n /** Project root directory path. If not provided, will be auto-detected. */\n readonly projectRoot?: string | undefined;\n\n /** Target strings such as `linux-x64`. */\n readonly targets?: readonly string[] | undefined;\n}\n\n/**\n * Create Listr tasks for downloading Node.js archives.\n * @param options Options controlling the task generation.\n * @returns Configured {@link Listr} instance.\n */\nexport const createCacheTasks = (options: CacheOptions = {}): Task[] => {\n const { cacheDir, download, existsSync, mkdir, nodeVersion, targets } =\n normalizeCacheOptions(options);\n const metaFor = createMetaFactory(cacheDir, nodeVersion);\n const toTask = createTaskFactory(download, existsSync, mkdir, cacheDir);\n return targets.map((t) => toTask(metaFor(t)));\n};\n","import { Listr } from 'listr2';\nimport type { CacheOptions } from '../tasks/createCacheTasks.mjs';\nimport { createCacheTasks } from '../tasks/createCacheTasks.mjs';\n\n/**\n * Create Listr tasks for downloading Node.js archives.\n * @param options Options controlling the task generation.\n * @returns Configured {@link Listr} instance.\n */\nexport const createListrCacheTasks = (options: CacheOptions = {}): Listr =>\n new Listr(createCacheTasks(options), { concurrent: true });\n","import { realpathSync } from 'node:fs';\nimport { fileURLToPath } from 'node:url';\n\n/**\n * Type definition for the main function executed when the module is run\n * as a script.\n */\nexport type MainFunction = (...args: readonly string[]) => Promise<void>;\n\n/**\n * Execute the provided {@link main} function when the current module is\n * the entry point.\n * @param url Value of `import.meta.url` from the caller.\n * @param main Function executed with CLI arguments.\n */\nexport const runIfMain = (url: string, main: MainFunction): Promise<void> => {\n const [, bin = '', ...args] = process.argv;\n return realpathSync(bin) === fileURLToPath(url)\n ? main(...args)\n : Promise.resolve();\n};\n"],"names":["existsSync","mkdir","concretedExistsSync","concretedMkdir"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kurone-kito/sea-builder",
3
- "version": "0.20.0",
3
+ "version": "0.20.1-alpha.2",
4
4
  "description": "The Single Executable App (SEA) builder for the Node.js",
5
5
  "keywords": [
6
6
  "sea",
@@ -28,22 +28,22 @@
28
28
  "dependencies": {
29
29
  "all-node-versions": "^13.0.1",
30
30
  "execa": "^9.6.0",
31
- "listr2": "^8.3.3",
31
+ "listr2": "^9.0.4",
32
32
  "semver": "^7.7.2"
33
33
  },
34
34
  "devDependencies": {
35
- "@types/node": "^24.0.7",
36
- "@types/semver": "^7.7.0",
35
+ "@types/node": "^24.6.1",
36
+ "@types/semver": "^7.7.1",
37
37
  "@vitest/coverage-v8": "^3.2.4",
38
- "cpy-cli": "^5.0.0",
38
+ "cpy-cli": "^6.0.0",
39
39
  "rimraf": "^6.0.1",
40
- "type-fest": "^4.41.0",
41
- "typescript": "~5.8.3",
42
- "undici": "7.11.0",
43
- "vite": "^7.0.0",
40
+ "type-fest": "^5.0.1",
41
+ "typescript": "~5.9.2",
42
+ "undici": "7.16.0",
43
+ "vite": "^7.1.6",
44
44
  "vitest": "^3.2.4",
45
- "@kurone-kito/typescript-config": "^0.20.0",
46
- "@kurone-kito/vite-lib-config": "^0.20.0"
45
+ "@kurone-kito/typescript-config": "^0.20.1-alpha.2",
46
+ "@kurone-kito/vite-lib-config": "^0.20.1-alpha.2"
47
47
  },
48
48
  "peerDependencies": {
49
49
  "xsea": "*"