screw-up 0.8.1 → 0.10.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/README.md +7 -244
- package/README_pack.md +63 -0
- package/dist/analyzer.d.ts +8 -0
- package/dist/analyzer.d.ts.map +1 -0
- package/dist/cli-internal.d.ts +25 -0
- package/dist/cli-internal.d.ts.map +1 -0
- package/dist/cli.cjs +736 -0
- package/dist/cli.cjs.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +735 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.cjs +30 -99
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +2 -37
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +31 -100
- package/dist/index.js.map +1 -0
- package/dist/internal-CzKyZ9wb.js +1816 -0
- package/dist/internal-CzKyZ9wb.js.map +1 -0
- package/dist/internal-Dli6fSLz.cjs +1832 -0
- package/dist/internal-Dli6fSLz.cjs.map +1 -0
- package/dist/internal.d.ts +17 -26
- package/dist/internal.d.ts.map +1 -1
- package/dist/types.d.ts +60 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/vite-plugin.d.ts +17 -0
- package/dist/vite-plugin.d.ts.map +1 -0
- package/package.json +37 -8
- package/LICENSE +0 -21
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sources":["../node_modules/tar-vern/dist/index.js","../src/cli-internal.ts","../src/cli.ts"],"sourcesContent":["/*!\n * name: tar-vern\n * version: 0.3.0\n * description: Tape archiver library for Typescript\n * author: Kouji Matsui (@kekyo@mi.kekyo.net)\n * license: MIT\n * repository.url: https://github.com/kekyo/tar-vern.git\n */\nimport { Readable } from \"stream\";\nimport { createGzip } from \"zlib\";\nimport { createReadStream, createWriteStream } from \"fs\";\nimport { stat } from \"fs/promises\";\nconst getUName = (candidateName, candidateId, reflectStat) => {\n return candidateName ?? (reflectStat === \"all\" ? candidateId.toString() : \"root\");\n};\nconst getBuffer = (data) => {\n return Buffer.isBuffer(data) ? data : Buffer.from(data, \"utf8\");\n};\nconst createDirectoryItem = async (path, reflectStat, options) => {\n const rs = reflectStat ?? \"none\";\n if (rs !== \"none\" && options?.directoryPath) {\n const stats = await stat(options.directoryPath);\n const mode = options?.mode ?? stats.mode;\n const uid = options?.uid ?? stats.uid;\n const gid = options?.gid ?? stats.gid;\n const date = options?.date ?? stats.mtime;\n const uname = getUName(options?.uname, stats.uid, rs);\n const gname = getUName(options?.gname, stats.gid, rs);\n return {\n kind: \"directory\",\n path,\n mode,\n uname,\n gname,\n uid,\n gid,\n date\n };\n } else {\n const mode = options?.mode ?? 493;\n const uid = options?.uid ?? 0;\n const gid = options?.gid ?? 0;\n const date = options?.date ?? /* @__PURE__ */ new Date();\n const uname = getUName(options?.uname, void 0, rs);\n const gname = getUName(options?.gname, void 0, rs);\n return {\n kind: \"directory\",\n path,\n mode,\n uname,\n gname,\n uid,\n gid,\n date\n };\n }\n};\nconst createFileItem = async (path, content, options) => {\n const mode = options?.mode ?? 420;\n const uid = options?.uid ?? 0;\n const gid = options?.gid ?? 0;\n const date = options?.date ?? /* @__PURE__ */ new Date();\n const uname = options?.uname ?? \"root\";\n const gname = options?.gname ?? \"root\";\n return {\n kind: \"file\",\n path,\n mode,\n uname,\n gname,\n uid,\n gid,\n date,\n content\n };\n};\nconst createReadableFileItem = async (path, readable, options) => {\n const mode = options?.mode ?? 420;\n const uid = options?.uid ?? 0;\n const gid = options?.gid ?? 0;\n const date = options?.date ?? /* @__PURE__ */ new Date();\n const uname = options?.uname ?? \"root\";\n const gname = options?.gname ?? \"root\";\n let length = options?.length;\n if (!length) {\n const chunks = [];\n length = 0;\n for await (const chunk of readable) {\n const buffer = getBuffer(chunk);\n chunks.push(buffer);\n length += buffer.length;\n }\n return {\n kind: \"file\",\n path,\n mode,\n uname,\n gname,\n uid,\n gid,\n date,\n content: {\n kind: \"readable\",\n length,\n readable: Readable.from(chunks)\n }\n };\n } else {\n return {\n kind: \"file\",\n path,\n mode,\n uname,\n gname,\n uid,\n gid,\n date,\n content: {\n kind: \"readable\",\n length,\n readable\n }\n };\n }\n};\nconst createGeneratorFileItem = async (path, generator, options) => {\n const mode = options?.mode ?? 420;\n const uid = options?.uid ?? 0;\n const gid = options?.gid ?? 0;\n const date = options?.date ?? /* @__PURE__ */ new Date();\n const uname = options?.uname ?? \"root\";\n const gname = options?.gname ?? \"root\";\n let length = options?.length;\n if (!length) {\n const chunks = [];\n length = 0;\n for await (const chunk of generator) {\n const buffer = getBuffer(chunk);\n chunks.push(buffer);\n length += buffer.length;\n }\n return {\n kind: \"file\",\n path,\n mode,\n uname,\n gname,\n uid,\n gid,\n date,\n content: {\n kind: \"readable\",\n length,\n readable: Readable.from(chunks)\n }\n };\n } else {\n return {\n kind: \"file\",\n path,\n mode,\n uname,\n gname,\n uid,\n gid,\n date,\n content: {\n kind: \"generator\",\n length,\n generator\n }\n };\n }\n};\nconst createReadFileItem = async (path, filePath, reflectStat, options) => {\n const rs = reflectStat ?? \"exceptName\";\n const stats = await stat(filePath);\n const reader = createReadStream(filePath);\n const mode = options?.mode ?? (rs !== \"none\" ? stats.mode : void 0);\n const uid = options?.uid ?? (rs !== \"none\" ? stats.uid : void 0);\n const gid = options?.gid ?? (rs !== \"none\" ? stats.gid : void 0);\n const date = options?.date ?? (rs !== \"none\" ? stats.mtime : void 0);\n const uname = getUName(options?.uname, stats.uid, rs);\n const gname = getUName(options?.gname, stats.gid, rs);\n return await createReadableFileItem(path, reader, {\n length: stats.size,\n mode,\n uname,\n gname,\n uid,\n gid,\n date\n });\n};\nconst storeReaderToFile = (reader, path) => {\n const writer = createWriteStream(path);\n reader.pipe(writer);\n return new Promise((res, rej) => {\n writer.on(\"finish\", res);\n writer.on(\"error\", rej);\n reader.on(\"error\", rej);\n });\n};\nconst utf8ByteLength = (str) => {\n return Buffer.byteLength(str, \"utf8\");\n};\nconst truncateUtf8Safe = (str, maxBytes) => {\n let total = 0;\n let i = 0;\n while (i < str.length) {\n const codePoint = str.codePointAt(i);\n const char = String.fromCodePoint(codePoint);\n const charBytes = Buffer.byteLength(char, \"utf8\");\n if (total + charBytes > maxBytes) break;\n total += charBytes;\n i += char.length;\n }\n return str.slice(0, i);\n};\nconst MAX_NAME = 100;\nconst MAX_PREFIX = 155;\nconst splitPath = (path) => {\n if (utf8ByteLength(path) <= MAX_NAME) {\n return { prefix: \"\", name: path };\n }\n const parts = path.split(\"/\");\n let name = parts.pop() ?? \"\";\n let prefix = parts.join(\"/\");\n if (utf8ByteLength(name) > MAX_NAME) {\n name = truncateUtf8Safe(name, MAX_NAME);\n }\n while (utf8ByteLength(prefix) > MAX_PREFIX) {\n prefix = truncateUtf8Safe(prefix, MAX_PREFIX);\n }\n return { prefix, name };\n};\nconst getOctalBytes = (value, length) => {\n const str = value.toString(8).padStart(length - 1, \"0\") + \"\\0\";\n return Buffer.from(str, \"ascii\");\n};\nconst getPaddedBytes = (buffer) => {\n const extra = buffer.length % 512;\n if (extra === 0) {\n return buffer;\n } else {\n return Buffer.concat([buffer, Buffer.alloc(512 - extra, 0)]);\n }\n};\nconst terminatorBytes = Buffer.alloc(1024, 0);\nconst createTarHeader = (type, path, size, mode, uname, gname, uid, gid, date) => {\n const buffer = Buffer.alloc(512, 0);\n const { name, prefix } = splitPath(path);\n buffer.write(name, 0, 100, \"utf8\");\n getOctalBytes(mode & 4095, 8).copy(buffer, 100);\n getOctalBytes(uid, 8).copy(buffer, 108);\n getOctalBytes(gid, 8).copy(buffer, 116);\n getOctalBytes(size, 12).copy(buffer, 124);\n getOctalBytes(Math.floor(date.getTime() / 1e3), 12).copy(buffer, 136);\n Buffer.from(\" \", \"ascii\").copy(buffer, 148);\n if (type === \"file\") {\n buffer.write(\"0\", 156, 1, \"ascii\");\n } else {\n buffer.write(\"5\", 156, 1, \"ascii\");\n }\n buffer.write(\"ustar\\0\", 257, 6, \"ascii\");\n buffer.write(\"00\", 263, 2, \"ascii\");\n buffer.write(uname, 265, 32, \"utf8\");\n buffer.write(gname, 297, 32, \"utf8\");\n buffer.write(prefix, 345, 155, \"utf8\");\n let sum = 0;\n for (let i = 0; i < 512; i++) {\n sum += buffer[i];\n }\n getOctalBytes(sum, 8).copy(buffer, 148);\n return buffer;\n};\nconst createTarPacker = (entryItemGenerator, compressionType, signal) => {\n const entryItemIterator = async function* () {\n for await (const entryItem of entryItemGenerator) {\n signal?.throwIfAborted();\n switch (entryItem.kind) {\n // Entry is a file\n case \"file\": {\n const entryItemContent = entryItem.content;\n if (typeof entryItemContent === \"string\" || Buffer.isBuffer(entryItemContent)) {\n const contentBytes = getBuffer(entryItemContent);\n const tarHeaderBytes = createTarHeader(\n \"file\",\n entryItem.path,\n contentBytes.length,\n entryItem.mode,\n entryItem.uname,\n entryItem.gname,\n entryItem.uid,\n entryItem.gid,\n entryItem.date\n );\n yield tarHeaderBytes;\n const totalPaddedContentBytes = getPaddedBytes(contentBytes);\n yield totalPaddedContentBytes;\n } else {\n const tarHeaderBytes = createTarHeader(\n \"file\",\n entryItem.path,\n entryItemContent.length,\n entryItem.mode,\n entryItem.uname,\n entryItem.gname,\n entryItem.uid,\n entryItem.gid,\n entryItem.date\n );\n yield tarHeaderBytes;\n let position = 0;\n switch (entryItemContent.kind) {\n // Content is a generator\n case \"generator\": {\n for await (const contentBytes of entryItemContent.generator) {\n signal?.throwIfAborted();\n yield contentBytes;\n position += contentBytes.length;\n }\n break;\n }\n // Content is a readable stream\n case \"readable\": {\n for await (const content of entryItemContent.readable) {\n signal?.throwIfAborted();\n const contentBytes = getBuffer(content);\n yield contentBytes;\n position += contentBytes.length;\n }\n break;\n }\n }\n if (position % 512 !== 0) {\n signal?.throwIfAborted();\n yield Buffer.alloc(512 - position % 512, 0);\n }\n }\n break;\n }\n // Entry is a directory\n case \"directory\": {\n const tarHeaderBytes = createTarHeader(\n \"directory\",\n entryItem.path,\n 0,\n entryItem.mode,\n entryItem.uname,\n entryItem.gname,\n entryItem.uid,\n entryItem.gid,\n entryItem.date\n );\n yield tarHeaderBytes;\n break;\n }\n }\n }\n yield terminatorBytes;\n };\n const ct = compressionType ?? \"none\";\n switch (ct) {\n // No compression\n case \"none\": {\n return Readable.from(entryItemIterator());\n }\n // Gzip compression\n case \"gzip\": {\n const gzipStream = createGzip({ level: 9 });\n const entryItemStream = Readable.from(entryItemIterator());\n entryItemStream.pipe(gzipStream);\n return gzipStream;\n }\n }\n};\nexport {\n createDirectoryItem,\n createFileItem,\n createGeneratorFileItem,\n createReadFileItem,\n createReadableFileItem,\n createTarPacker,\n getBuffer,\n storeReaderToFile\n};\n//# sourceMappingURL=index.js.map\n","// screw-up - Easy package metadata inserter on Vite plugin\n// Copyright (c) Kouji Matsui (@kekyo@mi.kekyo.net)\n// Under MIT.\n// https://github.com/kekyo/screw-up/\n\nimport { resolve } from 'path';\nimport { glob } from 'glob';\nimport { existsSync } from 'fs';\nimport { mkdir, lstat } from 'fs/promises';\nimport { createTarPacker, createReadFileItem, createFileItem, storeReaderToFile } from 'tar-vern';\nimport { resolveRawPackageJsonObject, PackageResolutionResult } from './internal.js';\n\n//////////////////////////////////////////////////////////////////////////////////\n\n/**\n * Create pack entry generator that collects and yields entries on-demand\n * @param targetDir - Target directory to pack\n * @param resolvedPackageJson - Resolved package.json object\n * @param readmeReplacementPath - Optional path to replacement README file\n * @returns Pack entry generator\n */\nconst createPackEntryGenerator = async function* (targetDir: string, resolvedPackageJson: any, readmeReplacementPath: string | undefined) {\n // First yield package.json content\n const packageJsonContent = JSON.stringify(resolvedPackageJson, null, 2);\n yield await createFileItem('package/package.json', packageJsonContent);\n\n // Get distribution files in package.json\n const distributionFileGlobs = resolvedPackageJson?.files as string[] ?? ['**/*'];\n \n // Convert directory patterns to recursive patterns (like npm pack does)\n const packingFilePaths = (await Promise.all(\n distributionFileGlobs.map(async (pattern) => {\n const fullPath = resolve(targetDir, pattern);\n try {\n if (existsSync(fullPath) && (await lstat(fullPath)).isDirectory()) {\n return await glob(`${pattern}/**/*`, { cwd: targetDir });\n }\n return await glob(pattern, { cwd: targetDir });\n } catch (error) {\n // If there's an error accessing the path, treat as glob pattern\n return await glob(pattern, { cwd: targetDir });\n }\n }))).flat();\n\n // Yield target packing files\n for (const packingFilePath of packingFilePaths) {\n // Except package.json (already yielded)\n if (packingFilePath !== 'package.json') {\n // Is file regular?\n const fullPath = resolve(targetDir, packingFilePath);\n const stat = await lstat(fullPath);\n if (stat.isFile()) {\n // Handle README.md replacement\n if (packingFilePath === 'README.md' && readmeReplacementPath) {\n // Use replacement file but keep README.md as the archive entry name\n yield await createReadFileItem('package/README.md', readmeReplacementPath);\n } else {\n // Yield regular file\n yield await createReadFileItem(`package/${packingFilePath}`, fullPath);\n }\n }\n }\n }\n\n // Handle case where README.md doesn't exist in files but we have a replacement\n if (readmeReplacementPath && !packingFilePaths.includes('README.md')) {\n // Add README.md to the archive using replacement file\n yield await createReadFileItem('package/README.md', readmeReplacementPath);\n }\n};\n\n\n/**\n * Pack assets into a tar archive\n * @param targetDir - Target directory to pack\n * @param outputDir - Output directory to write the tarball\n * @param checkWorkingDirectoryStatus - Check working directory status\n * @param inheritableFields - Package metadata fields that should be inherited from parent\n * @param readmeReplacementPath - Optional path to replacement README file\n * @returns Package metadata (package.json) or undefined if failed\n */\nexport const packAssets = async (\n targetDir: string,\n outputDir: string,\n checkWorkingDirectoryStatus: boolean,\n inheritableFields: Set<string>,\n readmeReplacementPath: string | undefined) : Promise<any> => {\n // Check if target directory exists\n if (!existsSync(targetDir)) {\n return undefined;\n }\n\n // Resolve package metadata with source tracking\n let result: PackageResolutionResult;\n try {\n result = await resolveRawPackageJsonObject(\n targetDir, checkWorkingDirectoryStatus,\n inheritableFields);\n } catch (error) {\n // If package.json cannot be read (e.g., file doesn't exist), return undefined\n // This matches npm pack behavior which requires package.json\n return undefined;\n }\n\n const { packageJson: resolvedPackageJson, sourceMap } = result;\n\n // Check if package is private\n if (resolvedPackageJson?.private) {\n return undefined;\n }\n\n // Determine README replacement path\n // Priority: CLI option > package.json.readme > none\n let finalReadmeReplacementPath = readmeReplacementPath;\n if (!finalReadmeReplacementPath && resolvedPackageJson?.readme) {\n // Get the correct base directory for readme field\n const readmeSourceDir = sourceMap.get('readme') ?? targetDir;\n const packageReadmePath = resolve(readmeSourceDir, resolvedPackageJson.readme);\n if (existsSync(packageReadmePath)) {\n finalReadmeReplacementPath = packageReadmePath;\n }\n }\n\n // Validate README replacement path before creating generator\n if (finalReadmeReplacementPath && !existsSync(finalReadmeReplacementPath)) {\n throw new Error(`README replacement file not found: ${finalReadmeReplacementPath}`);\n }\n\n // Get package name\n const outputFileName = `${resolvedPackageJson?.name?.replace('/', '-') ?? \"package\"}-${resolvedPackageJson?.version ?? \"0.0.0\"}.tgz`;\n\n // Ensure output directory exists\n if (!existsSync(outputDir)) {\n await mkdir(outputDir, { recursive: true });\n }\n\n // Create tar packer with generator and gzip compression\n const packer = createTarPacker(\n createPackEntryGenerator(targetDir, resolvedPackageJson, finalReadmeReplacementPath),\n 'gzip');\n\n // Write compressed tar archive to file\n const outputFile = resolve(outputDir, outputFileName);\n await storeReaderToFile(packer, outputFile);\n\n return resolvedPackageJson;\n};\n\n/**\n * Get computed package.json object\n * @param targetDir - Target directory to resolve package metadata\n * @param checkWorkingDirectoryStatus - Check working directory status\n * @param inheritableFields - Package metadata fields that should be inherited from parent\n * @returns Computed package.json object or undefined if failed\n */\nexport const getComputedPackageJsonObject = async (\n targetDir: string,\n checkWorkingDirectoryStatus: boolean,\n inheritableFields: Set<string>) : Promise<any> => {\n // Check if target directory exists\n if (!existsSync(targetDir)) {\n return undefined;\n }\n\n // Resolve package metadata\n const result = await resolveRawPackageJsonObject(\n targetDir, checkWorkingDirectoryStatus,\n inheritableFields);\n return result.packageJson;\n};\n\n//////////////////////////////////////////////////////////////////////////////////\n\nexport interface ParsedArgs {\n command?: string;\n positional: string[];\n options: Record<string, string | boolean>;\n}\n\nexport const parseArgs = (argv: string[]): ParsedArgs => {\n const args = argv.slice(2); // Remove 'node' and script path\n const result: ParsedArgs = {\n positional: [],\n options: {}\n };\n\n if (args.length === 0) {\n return result;\n }\n\n // Don't treat options as command\n if (args[0].startsWith('-')) {\n let i = 0;\n while (i < args.length) {\n const arg = args[i];\n\n if (arg.startsWith('--')) {\n const optionName = arg.slice(2);\n const nextArg = args[i + 1];\n\n if (nextArg !== undefined && !nextArg.startsWith('-')) {\n result.options[optionName] = nextArg;\n i += 2;\n } else {\n result.options[optionName] = true;\n i += 1;\n }\n } else if (arg.startsWith('-')) {\n const optionName = arg.slice(1);\n result.options[optionName] = true;\n i += 1;\n } else {\n result.positional.push(arg);\n i += 1;\n }\n }\n return result;\n }\n\n result.command = args[0];\n let i = 1;\n\n while (i < args.length) {\n const arg = args[i];\n\n if (arg.startsWith('--')) {\n const optionName = arg.slice(2);\n const nextArg = args[i + 1];\n\n if (nextArg !== undefined && !nextArg.startsWith('-')) {\n result.options[optionName] = nextArg;\n i += 2;\n } else {\n result.options[optionName] = true;\n i += 1;\n }\n } else if (arg.startsWith('-')) {\n const optionName = arg.slice(1);\n result.options[optionName] = true;\n i += 1;\n } else {\n result.positional.push(arg);\n i += 1;\n }\n }\n\n return result;\n};\n","#!/usr/bin/env node\n\n// screw-up - Easy package metadata inserter on Vite plugin\n// Copyright (c) Kouji Matsui (@kekyo@mi.kekyo.net)\n// Under MIT.\n// https://github.com/kekyo/screw-up/\n\nimport { join, resolve } from 'path';\nimport { existsSync } from 'fs';\nimport { mkdtemp, rm, stat } from 'fs/promises';\nimport { spawn } from 'child_process';\nimport { packAssets, parseArgs, ParsedArgs, getComputedPackageJsonObject } from './cli-internal.js';\n\ndeclare const __VERSION__: string;\ndeclare const __AUTHOR__: string;\ndeclare const __REPOSITORY_URL__: string;\ndeclare const __LICENSE__: string;\n\n// Package metadata fields that should be inherited from parent\nconst defaultInheritableFields = new Set([\n 'version',\n 'description', \n 'author',\n 'license',\n 'repository',\n 'keywords',\n 'homepage',\n 'bugs',\n 'readme'\n]);\n\n// Parse inheritable fields from CLI option string\nconst parseInheritableFields = (inheritableFieldsOption: string | boolean | undefined): Set<string> => {\n if (typeof inheritableFieldsOption !== 'string') {\n return defaultInheritableFields;\n }\n if (!inheritableFieldsOption.trim()) {\n return new Set(); // Empty set for empty string (no inheritance)\n }\n return new Set(inheritableFieldsOption.split(',').map(field => field.trim()).filter(field => field.length > 0));\n};\n\n//////////////////////////////////////////////////////////////////////////////////\n\nconst showHelp = () => {\n console.log(`screw-up - Easy package metadata inserter CLI [${__VERSION__}]\nCopyright (c) ${__AUTHOR__}\nRepository: ${__REPOSITORY_URL__}\nLicense: ${__LICENSE__}\n\nUsage: screw-up <command> [options]\n\nCommands:\n pack [directory] Pack the project into a tar archive\n publish [directory|package.tgz] Publish the project\n dump [directory] Dump computed package.json as JSON\n\nOptions:\n -h, --help Show help\n\nPack Options:\n --pack-destination <path> Directory to write the tarball\n --readme <path> Replace README.md with specified file\n --inheritable-fields <list> Comma-separated list of fields to inherit from parent (default: version,description,author,license,repository,keywords,homepage,bugs,readme)\n --no-wds Do not check working directory status to increase version\n\nPublish Options:\n All npm publish options are supported (e.g., --dry-run, --tag, --access, --registry)\n\nExamples:\n screw-up pack # Pack current directory\n screw-up pack ./my-project # Pack specific directory\n screw-up pack --pack-destination ./dist # Pack to specific output directory\n screw-up pack --readme ./README_pack.md # Pack with custom README\n screw-up publish # Publish current directory\n screw-up publish ./my-project # Publish specific directory\n screw-up publish package.tgz # Publish existing tarball\n screw-up publish --dry-run --tag beta # Publish with npm options\n`);\n};\n\nconst showPackHelp = () => {\n console.log(`Usage: screw-up pack [options] [directory]\n\nPack the project into a tar archive\n\nArguments:\n directory Directory to pack (default: current directory)\n\nOptions:\n --pack-destination <path> Directory to write the tarball\n --readme <path> Replace README.md with specified file\n --inheritable-fields <list> Comma-separated list of fields to inherit from parent\n --no-wds Do not check working directory status to increase version\n -h, --help Show help for pack command\n`);\n};\n\nconst showPublishHelp = () => {\n console.log(`Usage: screw-up publish [options] [directory|package.tgz]\n\nPublish the project\n\nArguments:\n directory|package.tgz Directory to pack and publish, or existing tarball to publish\n\nOptions:\n All npm publish options are supported, including:\n --dry-run Perform a dry run\n --tag <tag> Tag for the published version\n --access <access> Access level (public or restricted)\n --registry <registry> Registry URL\n -h, --help Show help for publish command\n\nExamples:\n screw-up publish # Publish current directory\n screw-up publish ./my-project # Publish specific directory\n screw-up publish package.tgz # Publish existing tarball\n screw-up publish --dry-run --tag beta # Publish with options\n`);\n};\n\n//////////////////////////////////////////////////////////////////////////////////\n\nconst packCommand = async (args: ParsedArgs) => {\n if (args.options.help || args.options.h) {\n showPackHelp();\n return;\n }\n\n const directory = args.positional[0];\n const packDestination = args.options['pack-destination'] as string;\n const readmeOption = args.options['readme'] as string;\n const inheritableFieldsOption = args.options['inheritable-fields'] as string;\n const checkWorkingDirectoryStatus = args.options['no-wds'] ? false : true;\n\n const targetDir = resolve(directory ?? process.cwd());\n const outputDir = packDestination ? resolve(packDestination) : process.cwd();\n const readmeReplacementPath = readmeOption ? resolve(readmeOption) : undefined;\n \n // Parse inheritable fields from CLI option or use defaults\n const inheritableFields = parseInheritableFields(inheritableFieldsOption);\n\n console.log(`[screw-up/cli]: pack: Creating archive of ${targetDir}...`);\n\n try {\n const metadata = await packAssets(\n targetDir, outputDir, checkWorkingDirectoryStatus, inheritableFields, readmeReplacementPath);\n if (metadata) {\n console.log(`[screw-up/cli]: pack: Archive created successfully: ${outputDir}`);\n } else {\n console.error(`[screw-up/cli]: pack: Unable to find any files to pack: ${targetDir}`);\n process.exit(1);\n }\n } catch (error) {\n console.error('[screw-up/cli]: pack: Failed to create archive:', error);\n process.exit(1);\n }\n};\n\n//////////////////////////////////////////////////////////////////////////////////\n\nconst publishCommand = async (args: ParsedArgs) => {\n if (args.options.help || args.options.h) {\n showPublishHelp();\n return;\n }\n\n const runNpmPublish = async (tarballPath: string, npmOptions: string[]) => {\n console.log(`[screw-up/cli]: publish: Publishing ${tarballPath} to npm...`);\n \n const publishArgs = ['publish', tarballPath, ...npmOptions];\n \n // For testing: log the command that would be executed\n if (process.env.SCREW_UP_TEST_MODE === 'true') {\n console.log(`[screw-up/cli]: TEST_MODE: Would execute: npm ${publishArgs.join(' ')}`);\n console.log(`[screw-up/cli]: TEST_MODE: Tarball path: ${tarballPath}`);\n console.log(`[screw-up/cli]: TEST_MODE: Options: ${npmOptions.join(' ')}`);\n console.log(`[screw-up/cli]: publish: Successfully published ${tarballPath}`);\n return;\n }\n \n const npmProcess = spawn('npm', publishArgs, { stdio: 'inherit' });\n \n return new Promise<void>((resolve, reject) => {\n npmProcess.on('close', (code) => {\n if (code === 0) {\n console.log(`[screw-up/cli]: publish: Successfully published ${tarballPath}`);\n resolve();\n } else {\n reject(new Error(`npm publish failed with exit code ${code}`));\n }\n });\n npmProcess.on('error', reject);\n });\n };\n\n const path = args.positional[0];\n const inheritableFieldsOption = args.options['inheritable-fields'] as string;\n const checkWorkingDirectoryStatus = args.options['no-wds'] ? false : true;\n\n // Parse inheritable fields from CLI option or use defaults\n const inheritableFields = parseInheritableFields(inheritableFieldsOption);\n\n // Convert parsed options to npm options\n const npmOptions: string[] = [];\n Object.entries(args.options).forEach(([key, value]) => {\n if (key === 'help' || key === 'h' || key === 'no-wds' || key === 'inheritable-fields') return; // Skip help, no-wds, and inheritable-fields options\n\n if (value === true) {\n npmOptions.push(`--${key}`);\n } else {\n npmOptions.push(`--${key}`, value as string);\n }\n });\n\n try {\n if (!path) {\n // No argument provided - generate tarball from current directory and publish\n const targetDir = process.cwd();\n const outputDir = await mkdtemp('screw-up-publish-');\n\n console.log(`[screw-up/cli]: publish: Creating archive of ${targetDir}...`);\n\n try {\n const metadata = await packAssets(\n targetDir, outputDir, checkWorkingDirectoryStatus, inheritableFields, undefined);\n if (metadata) {\n const archiveName = `${metadata.name}-${metadata.version}.tgz`;\n const archivePath = join(outputDir, archiveName);\n await runNpmPublish(archivePath, npmOptions);\n } else {\n console.error(`[screw-up/cli]: publish: Unable to find any files to pack: ${targetDir}`);\n process.exit(1);\n }\n } finally {\n await rm(outputDir, { recursive: true, force: true });\n }\n } else if (existsSync(path)) {\n const pathStat = await stat(path);\n \n if (pathStat.isFile() && (path.endsWith('.tgz') || path.endsWith('.tar.gz'))) {\n // Argument is a tarball file - publish directly\n await runNpmPublish(resolve(path), npmOptions);\n } else if (pathStat.isDirectory()) {\n // Argument is a directory - generate tarball from directory and publish\n const targetDir = resolve(path);\n const outputDir = await mkdtemp('screw-up-publish-');\n\n console.log(`[screw-up/cli]: publish: Creating archive of ${targetDir}...`);\n\n try {\n const metadata = await packAssets(\n targetDir, outputDir, checkWorkingDirectoryStatus, inheritableFields, undefined);\n if (metadata) {\n const archiveName = `${metadata.name}-${metadata.version}.tgz`;\n const archivePath = join(outputDir, archiveName);\n await runNpmPublish(archivePath, npmOptions);\n } else {\n console.error(`[screw-up/cli]: publish: Unable to find any files to pack: ${targetDir}`);\n process.exit(1);\n }\n } finally {\n await rm(outputDir, { recursive: true, force: true });\n }\n } else {\n console.error(`[screw-up/cli]: publish: Invalid path - must be a directory or .tgz/.tar.gz file: ${path}`);\n process.exit(1);\n }\n } else {\n console.error(`[screw-up/cli]: publish: Path does not exist: ${path}`);\n process.exit(1);\n }\n } catch (error) {\n console.error('[screw-up/cli]: publish: Failed to publish:', error);\n process.exit(1);\n }\n};\n\nconst showDumpHelp = () => {\n console.log(`Usage: screw-up dump [options] [directory]\n\nDump computed package.json as JSON\n\nArguments:\n directory Directory to dump package.json from (default: current directory)\n\nOptions:\n --inheritable-fields <list> Comma-separated list of fields to inherit from parent\n --no-wds Do not check working directory status to increase version\n -h, --help Show help for dump command\n`);\n};\n\n//////////////////////////////////////////////////////////////////////////////////\n\nconst dumpCommand = async (args: ParsedArgs) => {\n if (args.options.help || args.options.h) {\n showDumpHelp();\n return;\n }\n\n const directory = args.positional[0];\n const inheritableFieldsOption = args.options['inheritable-fields'] as string;\n const checkWorkingDirectoryStatus = args.options['no-wds'] ? false : true;\n\n // Parse inheritable fields from CLI option or use defaults\n const inheritableFields = parseInheritableFields(inheritableFieldsOption);\n\n const targetDir = resolve(directory ?? process.cwd());\n\n try {\n const computedPackageJson = await getComputedPackageJsonObject(\n targetDir, checkWorkingDirectoryStatus, inheritableFields);\n if (computedPackageJson) {\n console.log(JSON.stringify(computedPackageJson, null, 2));\n } else {\n console.error(`[screw-up/cli]: dump: Unable to read package.json from: ${targetDir}`);\n process.exit(1);\n }\n } catch (error) {\n console.error('[screw-up/cli]: dump: Failed to dump package.json:', error);\n process.exit(1);\n }\n};\n\n//////////////////////////////////////////////////////////////////////////////////\n\nconst main = async () => {\n const args = parseArgs(process.argv);\n\n // Handle global help or when no command is provided\n if (args.options.help || args.options.h || !args.command || \n args.command === 'help' || args.command === '--help') {\n showHelp();\n return;\n }\n\n switch (args.command) {\n case 'pack':\n await packCommand(args);\n break;\n case 'publish':\n await publishCommand(args);\n break;\n case 'dump':\n await dumpCommand(args);\n break;\n default:\n console.error(`Unknown command: ${args.command}`);\n console.error('Run \"screw-up --help\" for usage information.');\n process.exit(1);\n }\n};\n\nmain().catch((error) => {\n console.error('CLI error:', error);\n process.exit(1);\n});\n"],"names":["stat","i","npmOptions","resolve"],"mappings":"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","x_google_ignoreList":[0]}
|
package/dist/index.cjs
CHANGED
|
@@ -1,85 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
const promises = require("fs/promises");
|
|
3
3
|
const path = require("path");
|
|
4
|
-
const
|
|
5
|
-
const flattenObject = (obj, prefix, map) => {
|
|
6
|
-
for (const [key, value] of Object.entries(obj)) {
|
|
7
|
-
if (!value)
|
|
8
|
-
continue;
|
|
9
|
-
const fullKey = prefix ? `${prefix}.${key}` : key;
|
|
10
|
-
if (typeof value === "string") {
|
|
11
|
-
map[fullKey] = value;
|
|
12
|
-
} else if (Array.isArray(value)) {
|
|
13
|
-
map[fullKey] = value.map((v) => String(v)).join(",");
|
|
14
|
-
} else if (typeof value === "object") {
|
|
15
|
-
flattenObject(value, fullKey, map);
|
|
16
|
-
} else {
|
|
17
|
-
map[fullKey] = String(value);
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
};
|
|
21
|
-
const readPackageMetadata = async (packagePath) => {
|
|
22
|
-
try {
|
|
23
|
-
const content = await promises.readFile(packagePath, "utf-8");
|
|
24
|
-
const json = JSON.parse(content);
|
|
25
|
-
const map = {};
|
|
26
|
-
flattenObject(json, "", map);
|
|
27
|
-
return map;
|
|
28
|
-
} catch (error) {
|
|
29
|
-
console.warn(`Failed to read package.json from ${packagePath}:`, error);
|
|
30
|
-
return {};
|
|
31
|
-
}
|
|
32
|
-
};
|
|
33
|
-
const findWorkspaceRoot = async (startPath) => {
|
|
34
|
-
let currentPath = startPath;
|
|
35
|
-
while (currentPath !== path.dirname(currentPath)) {
|
|
36
|
-
const packageJsonPath = path.join(currentPath, "package.json");
|
|
37
|
-
if (fs.existsSync(packageJsonPath)) {
|
|
38
|
-
try {
|
|
39
|
-
const content = await promises.readFile(packageJsonPath, "utf-8");
|
|
40
|
-
const packageJson = JSON.parse(content);
|
|
41
|
-
if (packageJson.workspaces || fs.existsSync(path.join(currentPath, "pnpm-workspace.yaml")) || fs.existsSync(path.join(currentPath, "lerna.json"))) {
|
|
42
|
-
return currentPath;
|
|
43
|
-
}
|
|
44
|
-
} catch (error) {
|
|
45
|
-
console.warn(`Failed to parse package.json at ${packageJsonPath}:`, error);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
currentPath = path.dirname(currentPath);
|
|
49
|
-
}
|
|
50
|
-
return void 0;
|
|
51
|
-
};
|
|
52
|
-
const mergePackageMetadata = (parentMetadata, childMetadata) => {
|
|
53
|
-
const merged = {};
|
|
54
|
-
for (const key in parentMetadata) {
|
|
55
|
-
const value = parentMetadata[key];
|
|
56
|
-
if (value !== void 0) {
|
|
57
|
-
merged[key] = value;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
for (const key in childMetadata) {
|
|
61
|
-
const value = childMetadata[key];
|
|
62
|
-
if (value !== void 0) {
|
|
63
|
-
merged[key] = value;
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
return merged;
|
|
67
|
-
};
|
|
68
|
-
const resolvePackageMetadata = async (projectRoot) => {
|
|
69
|
-
const workspaceRoot = await findWorkspaceRoot(projectRoot);
|
|
70
|
-
if (!workspaceRoot) {
|
|
71
|
-
const localPackagePath = path.join(projectRoot, "package.json");
|
|
72
|
-
return await readPackageMetadata(localPackagePath);
|
|
73
|
-
}
|
|
74
|
-
const projectPackagePath = path.join(projectRoot, "package.json");
|
|
75
|
-
const rootPackagePath = path.join(workspaceRoot, "package.json");
|
|
76
|
-
let metadata = await readPackageMetadata(rootPackagePath);
|
|
77
|
-
if (projectPackagePath !== rootPackagePath && fs.existsSync(projectPackagePath)) {
|
|
78
|
-
const projectMetadata = await readPackageMetadata(projectPackagePath);
|
|
79
|
-
metadata = mergePackageMetadata(metadata, projectMetadata);
|
|
80
|
-
}
|
|
81
|
-
return metadata;
|
|
82
|
-
};
|
|
4
|
+
const internal = require("./internal-Dli6fSLz.cjs");
|
|
83
5
|
const generateBanner = (metadata, outputKeys) => {
|
|
84
6
|
const parts = [];
|
|
85
7
|
for (const key of outputKeys) {
|
|
@@ -121,11 +43,13 @@ const generateMetadataFile = (metadata, outputKeys) => {
|
|
|
121
43
|
};
|
|
122
44
|
const screwUp = (options = {}) => {
|
|
123
45
|
const {
|
|
124
|
-
outputKeys = ["name", "version", "description", "author", "license", "repository.url"],
|
|
46
|
+
outputKeys = ["name", "version", "description", "author", "license", "repository.url", "git.commit.hash"],
|
|
125
47
|
assetFilters = ["\\.d\\.ts$"],
|
|
126
48
|
outputMetadataFile = false,
|
|
127
49
|
outputMetadataFilePath = "src/generated/packageMetadata.ts",
|
|
128
|
-
outputMetadataKeys = ["name", "version", "description", "author", "license", "repository.url"]
|
|
50
|
+
outputMetadataKeys = ["name", "version", "description", "author", "license", "repository.url", "git.commit.hash"],
|
|
51
|
+
checkWorkingDirectoryStatus = true,
|
|
52
|
+
insertMetadataBanner = true
|
|
129
53
|
} = options;
|
|
130
54
|
const assetFiltersRegex = assetFilters.map((filter) => new RegExp(filter));
|
|
131
55
|
let banner;
|
|
@@ -134,37 +58,43 @@ const screwUp = (options = {}) => {
|
|
|
134
58
|
return {
|
|
135
59
|
name: "screw-up",
|
|
136
60
|
apply: "build",
|
|
137
|
-
|
|
61
|
+
// Configuration resolved phase
|
|
62
|
+
configResolved: async (config) => {
|
|
138
63
|
projectRoot = config.root;
|
|
139
|
-
metadata = await resolvePackageMetadata(config.root);
|
|
64
|
+
metadata = await internal.resolvePackageMetadata(config.root, checkWorkingDirectoryStatus);
|
|
140
65
|
banner = generateBanner(metadata, outputKeys);
|
|
141
66
|
},
|
|
142
|
-
|
|
67
|
+
// Build start phase
|
|
68
|
+
buildStart: async () => {
|
|
143
69
|
if (outputMetadataFile) {
|
|
144
|
-
const
|
|
145
|
-
const
|
|
70
|
+
const metadataSourceContent = generateMetadataFile(metadata, outputMetadataKeys);
|
|
71
|
+
const metadataSourcePath = path.join(projectRoot, outputMetadataFilePath);
|
|
146
72
|
try {
|
|
147
|
-
await promises.mkdir(path.dirname(
|
|
148
|
-
await promises.writeFile(
|
|
73
|
+
await promises.mkdir(path.dirname(metadataSourcePath), { recursive: true });
|
|
74
|
+
await promises.writeFile(metadataSourcePath, metadataSourceContent);
|
|
149
75
|
} catch (error) {
|
|
150
|
-
console.warn(`Failed to write metadata file
|
|
76
|
+
console.warn(`[screw-up]: Failed to write metadata source file: ${metadataSourcePath}:`, error);
|
|
151
77
|
}
|
|
152
78
|
}
|
|
153
79
|
},
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
chunk
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
80
|
+
// Generate bundle phase
|
|
81
|
+
generateBundle: (_options, bundle) => {
|
|
82
|
+
if (insertMetadataBanner) {
|
|
83
|
+
for (const fileName in bundle) {
|
|
84
|
+
const chunk = bundle[fileName];
|
|
85
|
+
if (chunk.type === "chunk") {
|
|
86
|
+
chunk.code = insertBannerHeader(chunk.code, banner);
|
|
87
|
+
} else if (chunk.type === "asset" && assetFiltersRegex.some((filter) => filter.test(fileName))) {
|
|
88
|
+
if (typeof chunk.source === "string") {
|
|
89
|
+
chunk.source = insertBannerHeader(chunk.source, banner + "\n");
|
|
90
|
+
}
|
|
162
91
|
}
|
|
163
92
|
}
|
|
164
93
|
}
|
|
165
94
|
},
|
|
166
|
-
|
|
167
|
-
|
|
95
|
+
// Write bundle phase
|
|
96
|
+
writeBundle: async (options2) => {
|
|
97
|
+
if (!insertMetadataBanner || !options2.dir) return;
|
|
168
98
|
try {
|
|
169
99
|
const files = await promises.readdir(options2.dir, { recursive: true });
|
|
170
100
|
for (const file of files) {
|
|
@@ -185,3 +115,4 @@ const screwUp = (options = {}) => {
|
|
|
185
115
|
};
|
|
186
116
|
};
|
|
187
117
|
module.exports = screwUp;
|
|
118
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../src/vite-plugin.ts"],"sourcesContent":["// screw-up - Easy package metadata inserter on Vite plugin\n// Copyright (c) Kouji Matsui (@kekyo@mi.kekyo.net)\n// Under MIT.\n// https://github.com/kekyo/screw-up/\n\nimport type { Plugin } from 'vite';\nimport { readFile, writeFile, readdir, mkdir } from 'fs/promises';\nimport { join, dirname } from 'path';\nimport { resolvePackageMetadata } from './internal.js';\nimport { ScrewUpOptions, PackageMetadata } from './types.js';\n\n/**\n * Generate banner string from package.json metadata\n * @param metadata - Package metadata\n * @param outputKeys - Array of keys to output in specified order\n * @returns Banner string\n */\nexport const generateBanner = (metadata: PackageMetadata, outputKeys: string[]): string => {\n const parts: string[] = [];\n \n for (const key of outputKeys) {\n const value = metadata[key];\n if (value) {\n parts.push(`${key}: ${value}`);\n }\n }\n \n return parts.length > 0 ? `/*!\\n * ${parts.join('\\n * ')}\\n */` : '';\n};\n\n/**\n * Insert banner header at appropriate position considering shebang\n * @param content - The content to insert banner into\n * @param banner - The banner header to insert\n * @returns Content with banner header inserted\n */\nconst insertBannerHeader = (content: string, banner: string): string => {\n const lines = content.split('\\n');\n \n // Check if first line is shebang\n if (lines.length > 0 && lines[0].startsWith('#!')) {\n // Insert banner after shebang line\n return lines[0] + '\\n' + banner + '\\n' + lines.slice(1).join('\\n');\n } else {\n // Insert banner at the beginning\n return banner + '\\n' + content;\n }\n};\n\n/**\n * Convert string key to valid TypeScript identifier\n * @param key - The key to convert\n * @returns Valid TypeScript identifier\n */\nconst sanitizeKey = (key: string): string => {\n // Replace dots and other invalid characters with underscores\n return key.replace(/[^a-zA-Z0-9_]/g, '_').replace(/^(\\d)/, '_$1');\n};\n\n/**\n * Generate TypeScript metadata file content from package metadata\n * @param metadata - Package metadata\n * @param outputKeys - Array of keys to output\n * @returns TypeScript file content\n */\nconst generateMetadataFile = (metadata: PackageMetadata, outputKeys: string[]): string => {\n const lines: string[] = [];\n \n lines.push('// This file is auto-generated by screw-up plugin');\n lines.push('// Do not edit manually');\n lines.push('');\n \n for (const key of outputKeys) {\n const value = metadata[key];\n if (value) {\n const sanitizedKey = sanitizeKey(key);\n const escapedValue = JSON.stringify(value);\n lines.push(`export const ${sanitizedKey} = ${escapedValue};`);\n }\n }\n \n lines.push('');\n \n return lines.join('\\n');\n};\n\n/////////////////////////////////////////////////////////////////////////////////////////\n\n/**\n * Vite plugin that adds banner to the bundled code\n * @param options - Plugin options\n * @returns Vite plugin\n */\nexport const screwUp = (options: ScrewUpOptions = {}): Plugin => {\n const {\n outputKeys = ['name', 'version', 'description', 'author', 'license', 'repository.url', 'git.commit.hash'],\n assetFilters = ['\\\\.d\\\\.ts$'],\n outputMetadataFile = false,\n outputMetadataFilePath = 'src/generated/packageMetadata.ts',\n outputMetadataKeys = ['name', 'version', 'description', 'author', 'license', 'repository.url', 'git.commit.hash'],\n checkWorkingDirectoryStatus = true,\n insertMetadataBanner = true} = options;\n\n const assetFiltersRegex = assetFilters.map(filter => new RegExp(filter));\n let banner: string;\n let metadata: any;\n let projectRoot: string;\n\n return {\n name: 'screw-up',\n apply: 'build',\n // Configuration resolved phase\n configResolved: async config => {\n // Save project root\n projectRoot = config.root;\n // Resolve package metadata\n metadata = await resolvePackageMetadata(config.root, checkWorkingDirectoryStatus);\n // Generate banner\n banner = generateBanner(metadata, outputKeys);\n },\n // Build start phase\n buildStart: async () => {\n // Generate metadata TypeScript file\n if (outputMetadataFile) {\n const metadataSourceContent = generateMetadataFile(metadata, outputMetadataKeys);\n const metadataSourcePath = join(projectRoot, outputMetadataFilePath);\n \n try {\n // Ensure directory exists\n await mkdir(dirname(metadataSourcePath), { recursive: true });\n // Write metadata source file\n await writeFile(metadataSourcePath, metadataSourceContent);\n } catch (error) {\n console.warn(`[screw-up]: Failed to write metadata source file: ${metadataSourcePath}:`, error);\n }\n }\n },\n // Generate bundle phase\n generateBundle: (_options, bundle) => {\n // Add banner to each output file if enabled\n if (insertMetadataBanner) {\n for (const fileName in bundle) {\n const chunk = bundle[fileName];\n if (chunk.type === 'chunk') {\n chunk.code = insertBannerHeader(chunk.code, banner);\n } else if (chunk.type === 'asset' && assetFiltersRegex.some(filter => filter.test(fileName))) {\n if (typeof chunk.source === 'string') {\n chunk.source = insertBannerHeader(chunk.source, banner + '\\n'); // insert more blank line\n }\n }\n }\n }\n },\n // Write bundle phase\n writeBundle: async options => {\n // Handle files written by other plugins (like vite-plugin-dts) if banner insertion is enabled\n if (!insertMetadataBanner || !options.dir) return;\n\n try {\n // Read all files in the output directory\n const files = await readdir(options.dir, { recursive: true });\n\n // Iterate over all files\n for (const file of files) {\n const filePath = join(options.dir, file);\n\n // Check if the file is target asset file\n if (assetFiltersRegex.some(filter => filter.test(file))) {\n try {\n // Read the asset file\n const content = await readFile(filePath, 'utf-8');\n // Append banner to the asset file if it doesn't already contain it\n if (!content.includes(banner)) {\n await writeFile(filePath, insertBannerHeader(content, banner + '\\n'));\n }\n } catch (error) {\n // Skip files that can't be read/written\n }\n }\n }\n } catch (error) {\n // Skip files that can't be read/written\n }\n }\n };\n};\n"],"names":["resolvePackageMetadata","join","mkdir","dirname","writeFile","options","readdir","readFile"],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,40 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { screwUp } from './vite-plugin.js';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
* screw-up options
|
|
5
|
-
*/
|
|
6
|
-
export interface ScrewUpOptions {
|
|
7
|
-
/**
|
|
8
|
-
* Array of keys to output in banner in the specified order
|
|
9
|
-
* @default ['name', 'version', 'description', 'author', 'license', 'repository.url']
|
|
10
|
-
*/
|
|
11
|
-
outputKeys?: string[];
|
|
12
|
-
/**
|
|
13
|
-
* Array of asset file regex to add banner to
|
|
14
|
-
* @default ['\.d\.ts$']
|
|
15
|
-
*/
|
|
16
|
-
assetFilters?: string[];
|
|
17
|
-
/**
|
|
18
|
-
* Enable TypeScript metadata file generation
|
|
19
|
-
* @default false
|
|
20
|
-
*/
|
|
21
|
-
outputMetadataFile?: boolean;
|
|
22
|
-
/**
|
|
23
|
-
* Output path for TypeScript metadata file
|
|
24
|
-
* @default 'src/generated/packageMetadata.ts'
|
|
25
|
-
*/
|
|
26
|
-
outputMetadataFilePath?: string;
|
|
27
|
-
/**
|
|
28
|
-
* Array of keys to output in metadata file in the specified order
|
|
29
|
-
* @default ['name', 'version', 'description', 'author', 'license', 'repository.url']
|
|
30
|
-
*/
|
|
31
|
-
outputMetadataKeys?: string[];
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Vite plugin that adds banner to the bundled code
|
|
35
|
-
* @param options - Plugin options
|
|
36
|
-
* @returns Vite plugin
|
|
37
|
-
*/
|
|
38
|
-
declare const screwUp: (options?: ScrewUpOptions) => Plugin;
|
|
3
|
+
export * from './types.js';
|
|
39
4
|
export default screwUp;
|
|
40
5
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAI3C,cAAc,YAAY,CAAC;AAC3B,eAAe,OAAO,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,84 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { readdir, readFile, writeFile, mkdir } from "fs/promises";
|
|
2
2
|
import { join, dirname } from "path";
|
|
3
|
-
import {
|
|
4
|
-
const flattenObject = (obj, prefix, map) => {
|
|
5
|
-
for (const [key, value] of Object.entries(obj)) {
|
|
6
|
-
if (!value)
|
|
7
|
-
continue;
|
|
8
|
-
const fullKey = prefix ? `${prefix}.${key}` : key;
|
|
9
|
-
if (typeof value === "string") {
|
|
10
|
-
map[fullKey] = value;
|
|
11
|
-
} else if (Array.isArray(value)) {
|
|
12
|
-
map[fullKey] = value.map((v) => String(v)).join(",");
|
|
13
|
-
} else if (typeof value === "object") {
|
|
14
|
-
flattenObject(value, fullKey, map);
|
|
15
|
-
} else {
|
|
16
|
-
map[fullKey] = String(value);
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
};
|
|
20
|
-
const readPackageMetadata = async (packagePath) => {
|
|
21
|
-
try {
|
|
22
|
-
const content = await readFile(packagePath, "utf-8");
|
|
23
|
-
const json = JSON.parse(content);
|
|
24
|
-
const map = {};
|
|
25
|
-
flattenObject(json, "", map);
|
|
26
|
-
return map;
|
|
27
|
-
} catch (error) {
|
|
28
|
-
console.warn(`Failed to read package.json from ${packagePath}:`, error);
|
|
29
|
-
return {};
|
|
30
|
-
}
|
|
31
|
-
};
|
|
32
|
-
const findWorkspaceRoot = async (startPath) => {
|
|
33
|
-
let currentPath = startPath;
|
|
34
|
-
while (currentPath !== dirname(currentPath)) {
|
|
35
|
-
const packageJsonPath = join(currentPath, "package.json");
|
|
36
|
-
if (existsSync(packageJsonPath)) {
|
|
37
|
-
try {
|
|
38
|
-
const content = await readFile(packageJsonPath, "utf-8");
|
|
39
|
-
const packageJson = JSON.parse(content);
|
|
40
|
-
if (packageJson.workspaces || existsSync(join(currentPath, "pnpm-workspace.yaml")) || existsSync(join(currentPath, "lerna.json"))) {
|
|
41
|
-
return currentPath;
|
|
42
|
-
}
|
|
43
|
-
} catch (error) {
|
|
44
|
-
console.warn(`Failed to parse package.json at ${packageJsonPath}:`, error);
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
currentPath = dirname(currentPath);
|
|
48
|
-
}
|
|
49
|
-
return void 0;
|
|
50
|
-
};
|
|
51
|
-
const mergePackageMetadata = (parentMetadata, childMetadata) => {
|
|
52
|
-
const merged = {};
|
|
53
|
-
for (const key in parentMetadata) {
|
|
54
|
-
const value = parentMetadata[key];
|
|
55
|
-
if (value !== void 0) {
|
|
56
|
-
merged[key] = value;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
for (const key in childMetadata) {
|
|
60
|
-
const value = childMetadata[key];
|
|
61
|
-
if (value !== void 0) {
|
|
62
|
-
merged[key] = value;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
return merged;
|
|
66
|
-
};
|
|
67
|
-
const resolvePackageMetadata = async (projectRoot) => {
|
|
68
|
-
const workspaceRoot = await findWorkspaceRoot(projectRoot);
|
|
69
|
-
if (!workspaceRoot) {
|
|
70
|
-
const localPackagePath = join(projectRoot, "package.json");
|
|
71
|
-
return await readPackageMetadata(localPackagePath);
|
|
72
|
-
}
|
|
73
|
-
const projectPackagePath = join(projectRoot, "package.json");
|
|
74
|
-
const rootPackagePath = join(workspaceRoot, "package.json");
|
|
75
|
-
let metadata = await readPackageMetadata(rootPackagePath);
|
|
76
|
-
if (projectPackagePath !== rootPackagePath && existsSync(projectPackagePath)) {
|
|
77
|
-
const projectMetadata = await readPackageMetadata(projectPackagePath);
|
|
78
|
-
metadata = mergePackageMetadata(metadata, projectMetadata);
|
|
79
|
-
}
|
|
80
|
-
return metadata;
|
|
81
|
-
};
|
|
3
|
+
import { r as resolvePackageMetadata } from "./internal-CzKyZ9wb.js";
|
|
82
4
|
const generateBanner = (metadata, outputKeys) => {
|
|
83
5
|
const parts = [];
|
|
84
6
|
for (const key of outputKeys) {
|
|
@@ -120,11 +42,13 @@ const generateMetadataFile = (metadata, outputKeys) => {
|
|
|
120
42
|
};
|
|
121
43
|
const screwUp = (options = {}) => {
|
|
122
44
|
const {
|
|
123
|
-
outputKeys = ["name", "version", "description", "author", "license", "repository.url"],
|
|
45
|
+
outputKeys = ["name", "version", "description", "author", "license", "repository.url", "git.commit.hash"],
|
|
124
46
|
assetFilters = ["\\.d\\.ts$"],
|
|
125
47
|
outputMetadataFile = false,
|
|
126
48
|
outputMetadataFilePath = "src/generated/packageMetadata.ts",
|
|
127
|
-
outputMetadataKeys = ["name", "version", "description", "author", "license", "repository.url"]
|
|
49
|
+
outputMetadataKeys = ["name", "version", "description", "author", "license", "repository.url", "git.commit.hash"],
|
|
50
|
+
checkWorkingDirectoryStatus = true,
|
|
51
|
+
insertMetadataBanner = true
|
|
128
52
|
} = options;
|
|
129
53
|
const assetFiltersRegex = assetFilters.map((filter) => new RegExp(filter));
|
|
130
54
|
let banner;
|
|
@@ -133,37 +57,43 @@ const screwUp = (options = {}) => {
|
|
|
133
57
|
return {
|
|
134
58
|
name: "screw-up",
|
|
135
59
|
apply: "build",
|
|
136
|
-
|
|
60
|
+
// Configuration resolved phase
|
|
61
|
+
configResolved: async (config) => {
|
|
137
62
|
projectRoot = config.root;
|
|
138
|
-
metadata = await resolvePackageMetadata(config.root);
|
|
63
|
+
metadata = await resolvePackageMetadata(config.root, checkWorkingDirectoryStatus);
|
|
139
64
|
banner = generateBanner(metadata, outputKeys);
|
|
140
65
|
},
|
|
141
|
-
|
|
66
|
+
// Build start phase
|
|
67
|
+
buildStart: async () => {
|
|
142
68
|
if (outputMetadataFile) {
|
|
143
|
-
const
|
|
144
|
-
const
|
|
69
|
+
const metadataSourceContent = generateMetadataFile(metadata, outputMetadataKeys);
|
|
70
|
+
const metadataSourcePath = join(projectRoot, outputMetadataFilePath);
|
|
145
71
|
try {
|
|
146
|
-
await mkdir(dirname(
|
|
147
|
-
await writeFile(
|
|
72
|
+
await mkdir(dirname(metadataSourcePath), { recursive: true });
|
|
73
|
+
await writeFile(metadataSourcePath, metadataSourceContent);
|
|
148
74
|
} catch (error) {
|
|
149
|
-
console.warn(`Failed to write metadata file
|
|
75
|
+
console.warn(`[screw-up]: Failed to write metadata source file: ${metadataSourcePath}:`, error);
|
|
150
76
|
}
|
|
151
77
|
}
|
|
152
78
|
},
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
chunk
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
79
|
+
// Generate bundle phase
|
|
80
|
+
generateBundle: (_options, bundle) => {
|
|
81
|
+
if (insertMetadataBanner) {
|
|
82
|
+
for (const fileName in bundle) {
|
|
83
|
+
const chunk = bundle[fileName];
|
|
84
|
+
if (chunk.type === "chunk") {
|
|
85
|
+
chunk.code = insertBannerHeader(chunk.code, banner);
|
|
86
|
+
} else if (chunk.type === "asset" && assetFiltersRegex.some((filter) => filter.test(fileName))) {
|
|
87
|
+
if (typeof chunk.source === "string") {
|
|
88
|
+
chunk.source = insertBannerHeader(chunk.source, banner + "\n");
|
|
89
|
+
}
|
|
161
90
|
}
|
|
162
91
|
}
|
|
163
92
|
}
|
|
164
93
|
},
|
|
165
|
-
|
|
166
|
-
|
|
94
|
+
// Write bundle phase
|
|
95
|
+
writeBundle: async (options2) => {
|
|
96
|
+
if (!insertMetadataBanner || !options2.dir) return;
|
|
167
97
|
try {
|
|
168
98
|
const files = await readdir(options2.dir, { recursive: true });
|
|
169
99
|
for (const file of files) {
|
|
@@ -186,3 +116,4 @@ const screwUp = (options = {}) => {
|
|
|
186
116
|
export {
|
|
187
117
|
screwUp as default
|
|
188
118
|
};
|
|
119
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/vite-plugin.ts"],"sourcesContent":["// screw-up - Easy package metadata inserter on Vite plugin\n// Copyright (c) Kouji Matsui (@kekyo@mi.kekyo.net)\n// Under MIT.\n// https://github.com/kekyo/screw-up/\n\nimport type { Plugin } from 'vite';\nimport { readFile, writeFile, readdir, mkdir } from 'fs/promises';\nimport { join, dirname } from 'path';\nimport { resolvePackageMetadata } from './internal.js';\nimport { ScrewUpOptions, PackageMetadata } from './types.js';\n\n/**\n * Generate banner string from package.json metadata\n * @param metadata - Package metadata\n * @param outputKeys - Array of keys to output in specified order\n * @returns Banner string\n */\nexport const generateBanner = (metadata: PackageMetadata, outputKeys: string[]): string => {\n const parts: string[] = [];\n \n for (const key of outputKeys) {\n const value = metadata[key];\n if (value) {\n parts.push(`${key}: ${value}`);\n }\n }\n \n return parts.length > 0 ? `/*!\\n * ${parts.join('\\n * ')}\\n */` : '';\n};\n\n/**\n * Insert banner header at appropriate position considering shebang\n * @param content - The content to insert banner into\n * @param banner - The banner header to insert\n * @returns Content with banner header inserted\n */\nconst insertBannerHeader = (content: string, banner: string): string => {\n const lines = content.split('\\n');\n \n // Check if first line is shebang\n if (lines.length > 0 && lines[0].startsWith('#!')) {\n // Insert banner after shebang line\n return lines[0] + '\\n' + banner + '\\n' + lines.slice(1).join('\\n');\n } else {\n // Insert banner at the beginning\n return banner + '\\n' + content;\n }\n};\n\n/**\n * Convert string key to valid TypeScript identifier\n * @param key - The key to convert\n * @returns Valid TypeScript identifier\n */\nconst sanitizeKey = (key: string): string => {\n // Replace dots and other invalid characters with underscores\n return key.replace(/[^a-zA-Z0-9_]/g, '_').replace(/^(\\d)/, '_$1');\n};\n\n/**\n * Generate TypeScript metadata file content from package metadata\n * @param metadata - Package metadata\n * @param outputKeys - Array of keys to output\n * @returns TypeScript file content\n */\nconst generateMetadataFile = (metadata: PackageMetadata, outputKeys: string[]): string => {\n const lines: string[] = [];\n \n lines.push('// This file is auto-generated by screw-up plugin');\n lines.push('// Do not edit manually');\n lines.push('');\n \n for (const key of outputKeys) {\n const value = metadata[key];\n if (value) {\n const sanitizedKey = sanitizeKey(key);\n const escapedValue = JSON.stringify(value);\n lines.push(`export const ${sanitizedKey} = ${escapedValue};`);\n }\n }\n \n lines.push('');\n \n return lines.join('\\n');\n};\n\n/////////////////////////////////////////////////////////////////////////////////////////\n\n/**\n * Vite plugin that adds banner to the bundled code\n * @param options - Plugin options\n * @returns Vite plugin\n */\nexport const screwUp = (options: ScrewUpOptions = {}): Plugin => {\n const {\n outputKeys = ['name', 'version', 'description', 'author', 'license', 'repository.url', 'git.commit.hash'],\n assetFilters = ['\\\\.d\\\\.ts$'],\n outputMetadataFile = false,\n outputMetadataFilePath = 'src/generated/packageMetadata.ts',\n outputMetadataKeys = ['name', 'version', 'description', 'author', 'license', 'repository.url', 'git.commit.hash'],\n checkWorkingDirectoryStatus = true,\n insertMetadataBanner = true} = options;\n\n const assetFiltersRegex = assetFilters.map(filter => new RegExp(filter));\n let banner: string;\n let metadata: any;\n let projectRoot: string;\n\n return {\n name: 'screw-up',\n apply: 'build',\n // Configuration resolved phase\n configResolved: async config => {\n // Save project root\n projectRoot = config.root;\n // Resolve package metadata\n metadata = await resolvePackageMetadata(config.root, checkWorkingDirectoryStatus);\n // Generate banner\n banner = generateBanner(metadata, outputKeys);\n },\n // Build start phase\n buildStart: async () => {\n // Generate metadata TypeScript file\n if (outputMetadataFile) {\n const metadataSourceContent = generateMetadataFile(metadata, outputMetadataKeys);\n const metadataSourcePath = join(projectRoot, outputMetadataFilePath);\n \n try {\n // Ensure directory exists\n await mkdir(dirname(metadataSourcePath), { recursive: true });\n // Write metadata source file\n await writeFile(metadataSourcePath, metadataSourceContent);\n } catch (error) {\n console.warn(`[screw-up]: Failed to write metadata source file: ${metadataSourcePath}:`, error);\n }\n }\n },\n // Generate bundle phase\n generateBundle: (_options, bundle) => {\n // Add banner to each output file if enabled\n if (insertMetadataBanner) {\n for (const fileName in bundle) {\n const chunk = bundle[fileName];\n if (chunk.type === 'chunk') {\n chunk.code = insertBannerHeader(chunk.code, banner);\n } else if (chunk.type === 'asset' && assetFiltersRegex.some(filter => filter.test(fileName))) {\n if (typeof chunk.source === 'string') {\n chunk.source = insertBannerHeader(chunk.source, banner + '\\n'); // insert more blank line\n }\n }\n }\n }\n },\n // Write bundle phase\n writeBundle: async options => {\n // Handle files written by other plugins (like vite-plugin-dts) if banner insertion is enabled\n if (!insertMetadataBanner || !options.dir) return;\n\n try {\n // Read all files in the output directory\n const files = await readdir(options.dir, { recursive: true });\n\n // Iterate over all files\n for (const file of files) {\n const filePath = join(options.dir, file);\n\n // Check if the file is target asset file\n if (assetFiltersRegex.some(filter => filter.test(file))) {\n try {\n // Read the asset file\n const content = await readFile(filePath, 'utf-8');\n // Append banner to the asset file if it doesn't already contain it\n if (!content.includes(banner)) {\n await writeFile(filePath, insertBannerHeader(content, banner + '\\n'));\n }\n } catch (error) {\n // Skip files that can't be read/written\n }\n }\n }\n } catch (error) {\n // Skip files that can't be read/written\n }\n }\n };\n};\n"],"names":["options"],"mappings":"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"}
|