@tooldeck/plugin-package 0.1.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/LICENSE +202 -0
- package/README.md +51 -0
- package/dist/constants.d.ts +11 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/digest.d.ts +2 -0
- package/dist/digest.d.ts.map +1 -0
- package/dist/errors.d.ts +15 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/fflate-zip-adapter.d.ts +14 -0
- package/dist/fflate-zip-adapter.d.ts.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +710 -0
- package/dist/index.js.map +1 -0
- package/dist/manifest.d.ts +4 -0
- package/dist/manifest.d.ts.map +1 -0
- package/dist/pack.d.ts +5 -0
- package/dist/pack.d.ts.map +1 -0
- package/dist/package-manifest.d.ts +11 -0
- package/dist/package-manifest.d.ts.map +1 -0
- package/dist/package-reader.d.ts +8 -0
- package/dist/package-reader.d.ts.map +1 -0
- package/dist/paths.d.ts +7 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/types.d.ts +70 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/utils.d.ts +2 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/zip-adapter.d.ts +26 -0
- package/dist/zip-adapter.d.ts.map +1 -0
- package/dist/zip-central-directory.d.ts +7 -0
- package/dist/zip-central-directory.d.ts.map +1 -0
- package/dist/zip-entry-policy.d.ts +4 -0
- package/dist/zip-entry-policy.d.ts.map +1 -0
- package/package.json +39 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/constants.ts","../src/errors.ts","../src/paths.ts","../src/utils.ts","../src/package-manifest.ts","../src/digest.ts","../src/zip-central-directory.ts","../src/zip-entry-policy.ts","../src/fflate-zip-adapter.ts","../src/manifest.ts","../src/package-reader.ts","../src/pack.ts"],"sourcesContent":["import type { TooldeckPackageLimits } from \"./types\";\n\nexport const TOOLDECK_PACKAGE_EXTENSION = \".tdplugin\";\n\nexport const TOOLDECK_PACKAGE_MANIFEST_PATH = \"tooldeck-package.json\";\n\nexport const TOOLDECK_PLUGIN_MANIFEST_PATH = \"manifest.json\";\n\nexport const TOOLDECK_PACKAGE_FORMAT_VERSION = \"1.0\";\n\nexport const DEFAULT_PACKAGE_LIMITS = {\n maxPackageSizeBytes: 50 * 1024 * 1024,\n maxUncompressedSizeBytes: 50 * 1024 * 1024,\n maxRegularFileCount: 1000,\n} as const satisfies TooldeckPackageLimits;\n\nexport const DEFAULT_PACKAGE_INCLUDE_DIRS = [\"dist\", \"assets\"] as const;\n","export type TooldeckPackageErrorCode =\n | \"INVALID_PACKAGE_EXTENSION\"\n | \"PACKAGE_READ_FAILED\"\n | \"PACKAGE_WRITE_FAILED\"\n | \"PACKAGE_EXTRACT_FAILED\"\n | \"PACKAGE_TOO_LARGE\"\n | \"TOO_MANY_FILES\"\n | \"UNCOMPRESSED_SIZE_TOO_LARGE\"\n | \"INVALID_ZIP\"\n | \"UNSUPPORTED_ENCRYPTED_ZIP\"\n | \"UNSUPPORTED_ZIP64\"\n | \"UNSUPPORTED_ZIP_ENTRY\"\n | \"MISSING_PACKAGE_MANIFEST\"\n | \"MISSING_PLUGIN_MANIFEST\"\n | \"MISSING_RUNTIME_ENTRY\"\n | \"UNSUPPORTED_RUNTIME_KIND\"\n | \"INVALID_PACKAGE_METADATA\"\n | \"INVALID_PACKAGE_MANIFEST\"\n | \"INVALID_PLUGIN_MANIFEST\"\n | \"INVALID_PACKAGE_PATH\"\n | \"NODE_MODULES_NOT_ALLOWED\"\n | \"DUPLICATE_FILE_LIST_ENTRY\"\n | \"UNSORTED_FILE_LIST\"\n | \"FILE_LIST_MISMATCH\"\n | \"EXTRACTION_ESCAPE\";\n\nexport interface TooldeckPackageErrorContext {\n packagePath?: string;\n entryPath?: string;\n manifestPath?: string;\n fieldPath?: string;\n reason?: string;\n}\n\nexport class TooldeckPackageError extends Error {\n readonly code: TooldeckPackageErrorCode;\n readonly context: TooldeckPackageErrorContext;\n\n constructor(\n code: TooldeckPackageErrorCode,\n message: string,\n context: TooldeckPackageErrorContext = {},\n ) {\n super(message);\n this.name = \"TooldeckPackageError\";\n this.code = code;\n this.context = context;\n }\n}\n\nexport function packageError(\n code: TooldeckPackageErrorCode,\n message: string,\n context: TooldeckPackageErrorContext = {},\n): TooldeckPackageError {\n return new TooldeckPackageError(code, message, context);\n}\n","import { packageError } from \"./errors.js\";\n\nexport function normalizePackagePath(input: string): string {\n const normalizedSlashes = input.replace(/\\\\/g, \"/\").trim();\n const withoutLeadingDot = normalizedSlashes.replace(/^\\.\\/+/, \"\");\n const collapsed = withoutLeadingDot.replace(/\\/+/g, \"/\");\n\n return collapsed.endsWith(\"/\") ? collapsed.slice(0, -1) : collapsed;\n}\n\nexport function assertSafePackagePath(input: string, fieldPath?: string): string {\n const normalized = normalizePackagePath(input);\n\n if (normalized.length === 0) {\n throw packageError(\"INVALID_PACKAGE_PATH\", \"Package path must not be empty.\", {\n entryPath: input,\n fieldPath,\n reason: \"empty path\",\n });\n }\n\n if (normalized.startsWith(\"/\") || normalized.startsWith(\"//\")) {\n throw packageError(\"INVALID_PACKAGE_PATH\", \"Package path must be relative.\", {\n entryPath: input,\n fieldPath,\n reason: \"absolute path\",\n });\n }\n\n if (/^[A-Za-z]:\\//.test(normalized)) {\n throw packageError(\"INVALID_PACKAGE_PATH\", \"Package path must not include a drive prefix.\", {\n entryPath: input,\n fieldPath,\n reason: \"drive-prefixed path\",\n });\n }\n\n const segments = normalized.split(\"/\");\n if (segments.some((segment) => segment === \".\" || segment === \"..\" || segment.length === 0)) {\n throw packageError(\n \"INVALID_PACKAGE_PATH\",\n \"Package path must not contain traversal segments.\",\n {\n entryPath: input,\n fieldPath,\n reason: \"path traversal\",\n },\n );\n }\n\n if (isNodeModulesPath(normalized)) {\n throw packageError(\"NODE_MODULES_NOT_ALLOWED\", \"Package must not contain node_modules.\", {\n entryPath: input,\n fieldPath,\n reason: \"node_modules is not allowed\",\n });\n }\n\n return normalized;\n}\n\nexport function isNodeModulesPath(input: string): boolean {\n return normalizePackagePath(input)\n .split(\"/\")\n .some((segment) => segment === \"node_modules\");\n}\n\nexport function dedupeAndSortPackagePaths(paths: Iterable<string>): string[] {\n return Array.from(new Set(Array.from(paths, (path) => assertSafePackagePath(path)))).sort(\n comparePackagePaths,\n );\n}\n\nexport function comparePackagePaths(a: string, b: string): number {\n return a.localeCompare(b, \"en\", { sensitivity: \"variant\" });\n}\n\nexport function packagePathStartsWith(path: string, directory: string): boolean {\n const normalizedPath = normalizePackagePath(path);\n const normalizedDirectory = normalizePackagePath(directory);\n\n return (\n normalizedPath === normalizedDirectory || normalizedPath.startsWith(`${normalizedDirectory}/`)\n );\n}\n","export function isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n","import {\n TOOLDECK_PACKAGE_FORMAT_VERSION,\n TOOLDECK_PACKAGE_MANIFEST_PATH,\n TOOLDECK_PLUGIN_MANIFEST_PATH,\n} from \"./constants.js\";\nimport { packageError } from \"./errors.js\";\nimport { assertSafePackagePath, dedupeAndSortPackagePaths } from \"./paths.js\";\nimport type { TooldeckPackageManifest } from \"./types.js\";\nimport { isRecord } from \"./utils.js\";\n\nexport function createTooldeckPackageManifest(options: {\n createdAt?: Date;\n files: Iterable<string>;\n}): TooldeckPackageManifest {\n const files = dedupeAndSortPackagePaths([\n TOOLDECK_PLUGIN_MANIFEST_PATH,\n TOOLDECK_PACKAGE_MANIFEST_PATH,\n ...options.files,\n ]);\n\n return {\n formatVersion: TOOLDECK_PACKAGE_FORMAT_VERSION,\n manifestPath: TOOLDECK_PLUGIN_MANIFEST_PATH,\n createdAt: (options.createdAt ?? new Date()).toISOString(),\n files,\n };\n}\n\nexport function validateTooldeckPackageManifest(value: unknown): TooldeckPackageManifest {\n if (!isRecord(value)) {\n throw packageError(\"INVALID_PACKAGE_METADATA\", \"tooldeck-package.json must be an object.\", {\n manifestPath: TOOLDECK_PACKAGE_MANIFEST_PATH,\n });\n }\n\n if (value.formatVersion !== TOOLDECK_PACKAGE_FORMAT_VERSION) {\n throw packageError(\"INVALID_PACKAGE_MANIFEST\", \"Unsupported Tooldeck package format version.\", {\n manifestPath: TOOLDECK_PACKAGE_MANIFEST_PATH,\n fieldPath: \"formatVersion\",\n reason: `expected ${TOOLDECK_PACKAGE_FORMAT_VERSION}`,\n });\n }\n\n if (value.manifestPath !== TOOLDECK_PLUGIN_MANIFEST_PATH) {\n throw packageError(\"INVALID_PACKAGE_MANIFEST\", \"Package manifestPath must be manifest.json.\", {\n manifestPath: TOOLDECK_PACKAGE_MANIFEST_PATH,\n fieldPath: \"manifestPath\",\n reason: \"1.3 only supports a root manifest.json\",\n });\n }\n\n if (typeof value.createdAt !== \"string\" || Number.isNaN(Date.parse(value.createdAt))) {\n throw packageError(\n \"INVALID_PACKAGE_MANIFEST\",\n \"Package createdAt must be an ISO date string.\",\n {\n manifestPath: TOOLDECK_PACKAGE_MANIFEST_PATH,\n fieldPath: \"createdAt\",\n },\n );\n }\n\n if (!Array.isArray(value.files) || !value.files.every((file) => typeof file === \"string\")) {\n throw packageError(\"INVALID_PACKAGE_MANIFEST\", \"Package files must be a string array.\", {\n manifestPath: TOOLDECK_PACKAGE_MANIFEST_PATH,\n fieldPath: \"files\",\n });\n }\n\n const normalizedFiles = value.files.map((file) => assertSafePackagePath(file));\n const files = dedupeAndSortPackagePaths(normalizedFiles);\n if (files.length !== value.files.length) {\n throw packageError(\"DUPLICATE_FILE_LIST_ENTRY\", \"Package files must not contain duplicates.\", {\n manifestPath: TOOLDECK_PACKAGE_MANIFEST_PATH,\n fieldPath: \"files\",\n });\n }\n\n for (let index = 0; index < files.length; index += 1) {\n if (normalizedFiles[index] !== files[index]) {\n throw packageError(\"UNSORTED_FILE_LIST\", \"Package files must be sorted.\", {\n manifestPath: TOOLDECK_PACKAGE_MANIFEST_PATH,\n fieldPath: \"files\",\n reason: `expected ${files[index]} at index ${index}`,\n });\n }\n }\n\n for (const requiredPath of [TOOLDECK_PLUGIN_MANIFEST_PATH, TOOLDECK_PACKAGE_MANIFEST_PATH]) {\n assertSafePackagePath(requiredPath);\n if (!files.includes(requiredPath)) {\n throw packageError(\"INVALID_PACKAGE_MANIFEST\", \"Package files is missing a required file.\", {\n manifestPath: TOOLDECK_PACKAGE_MANIFEST_PATH,\n fieldPath: \"files\",\n entryPath: requiredPath,\n });\n }\n }\n\n return {\n formatVersion: TOOLDECK_PACKAGE_FORMAT_VERSION,\n manifestPath: TOOLDECK_PLUGIN_MANIFEST_PATH,\n createdAt: value.createdAt,\n files,\n };\n}\n\nexport function assertPackageFileListMatches(options: {\n declaredFiles: Iterable<string>;\n actualFiles: Iterable<string>;\n}): string[] {\n const declaredFiles = dedupeAndSortPackagePaths(options.declaredFiles);\n const actualFiles = dedupeAndSortPackagePaths(options.actualFiles);\n\n if (declaredFiles.length !== actualFiles.length) {\n throw packageError(\"FILE_LIST_MISMATCH\", \"Package file list does not match ZIP entries.\", {\n manifestPath: TOOLDECK_PACKAGE_MANIFEST_PATH,\n fieldPath: \"files\",\n reason: \"file count mismatch\",\n });\n }\n\n for (let index = 0; index < declaredFiles.length; index += 1) {\n if (declaredFiles[index] !== actualFiles[index]) {\n throw packageError(\"FILE_LIST_MISMATCH\", \"Package file list does not match ZIP entries.\", {\n manifestPath: TOOLDECK_PACKAGE_MANIFEST_PATH,\n fieldPath: \"files\",\n reason: `expected ${declaredFiles[index]}, got ${actualFiles[index]}`,\n });\n }\n }\n\n return declaredFiles;\n}\n","import { createHash } from \"node:crypto\";\nimport { readFile } from \"node:fs/promises\";\n\nexport async function computePackageDigest(packagePath: string): Promise<string> {\n const data = await readFile(packagePath);\n\n return createHash(\"sha256\").update(data).digest(\"hex\");\n}\n","import { strFromU8 } from \"fflate\";\n\nimport { packageError } from \"./errors.js\";\nimport { normalizePackagePath } from \"./paths.js\";\nimport type { ZipEntryKind, ZipEntryMetadata } from \"./zip-adapter.js\";\n\nexport interface CentralDirectoryEntry extends ZipEntryMetadata {\n compression: number;\n encrypted: boolean;\n}\n\n// ZIP signatures and sentinel values are defined by the PKWARE APPNOTE spec.\nconst EOCD_SIGNATURE = 0x06054b50;\nconst ZIP64_EOCD_LOCATOR_SIGNATURE = 0x07064b50;\nconst CENTRAL_DIRECTORY_SIGNATURE = 0x02014b50;\nconst EOCD_FIXED_SIZE = 22;\nconst CENTRAL_DIRECTORY_HEADER_SIZE = 46;\nconst MAX_EOCD_COMMENT_BYTES = 0xffff;\nconst ZIP64_SENTINEL_16 = 0xffff;\nconst ZIP64_SENTINEL_32 = 0xffffffff;\n\nexport function parseCentralDirectory(data: Uint8Array): CentralDirectoryEntry[] {\n const view = new DataView(data.buffer, data.byteOffset, data.byteLength);\n const eocdOffset = findEndOfCentralDirectory(view);\n\n if (eocdOffset < 0) {\n throw packageError(\"INVALID_ZIP\", \"ZIP end of central directory was not found.\");\n }\n\n if (hasZip64Locator(view, eocdOffset)) {\n throw packageError(\"UNSUPPORTED_ZIP64\", \"ZIP64 packages are not supported.\");\n }\n\n const diskNumber = view.getUint16(eocdOffset + 4, true);\n const centralDirectoryDisk = view.getUint16(eocdOffset + 6, true);\n const entriesOnDisk = view.getUint16(eocdOffset + 8, true);\n const entryCount = view.getUint16(eocdOffset + 10, true);\n const centralDirectorySize = view.getUint32(eocdOffset + 12, true);\n const centralDirectoryOffset = view.getUint32(eocdOffset + 16, true);\n\n if (diskNumber !== 0 || centralDirectoryDisk !== 0 || entriesOnDisk !== entryCount) {\n throw packageError(\"UNSUPPORTED_ZIP_ENTRY\", \"Multi-disk ZIP packages are not supported.\");\n }\n\n if (\n entryCount === ZIP64_SENTINEL_16 ||\n centralDirectorySize === ZIP64_SENTINEL_32 ||\n centralDirectoryOffset === ZIP64_SENTINEL_32\n ) {\n throw packageError(\"UNSUPPORTED_ZIP64\", \"ZIP64 packages are not supported.\");\n }\n\n const endOffset = centralDirectoryOffset + centralDirectorySize;\n\n if (endOffset !== eocdOffset || centralDirectoryOffset > endOffset) {\n throw packageError(\"INVALID_ZIP\", \"ZIP central directory range is invalid.\");\n }\n\n const entries: CentralDirectoryEntry[] = [];\n const entryPaths = new Set<string>();\n let offset = centralDirectoryOffset;\n\n while (offset < endOffset) {\n assertAvailableRange(\n view,\n offset,\n CENTRAL_DIRECTORY_HEADER_SIZE,\n \"ZIP central directory entry\",\n );\n\n if (view.getUint32(offset, true) !== CENTRAL_DIRECTORY_SIGNATURE) {\n throw packageError(\"INVALID_ZIP\", \"Invalid ZIP central directory entry.\");\n }\n\n const generalPurposeFlag = view.getUint16(offset + 8, true);\n const compression = view.getUint16(offset + 10, true);\n const compressedSize = view.getUint32(offset + 20, true);\n const uncompressedSize = view.getUint32(offset + 24, true);\n const fileNameLength = view.getUint16(offset + 28, true);\n const extraFieldLength = view.getUint16(offset + 30, true);\n const fileCommentLength = view.getUint16(offset + 32, true);\n const externalAttributes = view.getUint32(offset + 38, true);\n const entrySize =\n CENTRAL_DIRECTORY_HEADER_SIZE + fileNameLength + extraFieldLength + fileCommentLength;\n\n assertAvailableRange(view, offset, entrySize, \"ZIP central directory entry data\");\n\n if (offset + entrySize > endOffset) {\n throw packageError(\"INVALID_ZIP\", \"ZIP central directory entry exceeds its declared range.\");\n }\n\n const fileNameOffset = offset + CENTRAL_DIRECTORY_HEADER_SIZE;\n const fileNameBytes = data.subarray(fileNameOffset, fileNameOffset + fileNameLength);\n const rawEntryPath = strFromU8(fileNameBytes);\n const entryPath = normalizePackagePath(rawEntryPath);\n\n if (entryPaths.has(entryPath)) {\n throw packageError(\n \"DUPLICATE_FILE_LIST_ENTRY\",\n \"ZIP entries must not contain duplicate paths.\",\n {\n entryPath,\n },\n );\n }\n\n entryPaths.add(entryPath);\n\n if (compressedSize === ZIP64_SENTINEL_32 || uncompressedSize === ZIP64_SENTINEL_32) {\n throw packageError(\"UNSUPPORTED_ZIP64\", \"ZIP64 packages are not supported.\", {\n entryPath,\n });\n }\n\n entries.push({\n path: entryPath,\n kind: classifyEntry(rawEntryPath, externalAttributes),\n compression,\n encrypted: (generalPurposeFlag & 0x1) === 0x1,\n compressedSizeBytes: compressedSize,\n uncompressedSizeBytes: uncompressedSize,\n });\n\n offset += entrySize;\n }\n\n if (offset !== endOffset || entries.length !== entryCount) {\n throw packageError(\"INVALID_ZIP\", \"ZIP central directory entry count does not match EOCD.\");\n }\n\n return entries;\n}\n\nfunction findEndOfCentralDirectory(view: DataView): number {\n const minOffset = Math.max(0, view.byteLength - (MAX_EOCD_COMMENT_BYTES + EOCD_FIXED_SIZE));\n\n for (let offset = view.byteLength - EOCD_FIXED_SIZE; offset >= minOffset; offset -= 1) {\n if (view.getUint32(offset, true) !== EOCD_SIGNATURE) {\n continue;\n }\n\n const commentLength = view.getUint16(offset + 20, true);\n\n if (offset + EOCD_FIXED_SIZE + commentLength === view.byteLength) {\n return offset;\n }\n }\n\n return -1;\n}\n\nfunction hasZip64Locator(view: DataView, eocdOffset: number): boolean {\n const locatorOffset = eocdOffset - 20;\n\n return locatorOffset >= 0 && view.getUint32(locatorOffset, true) === ZIP64_EOCD_LOCATOR_SIGNATURE;\n}\n\nfunction classifyEntry(rawEntryPath: string, externalAttributes: number): ZipEntryKind {\n if (rawEntryPath.replaceAll(\"\\\\\", \"/\").endsWith(\"/\")) {\n return \"directory\";\n }\n\n const unixMode = externalAttributes >>> 16;\n const unixType = unixMode & 0o170000;\n\n if (unixType === 0o040000) {\n return \"directory\";\n }\n\n if (unixType === 0o120000) {\n return \"symlink\";\n }\n\n if (unixType !== 0 && unixType !== 0o100000) {\n return \"special\";\n }\n\n if ((externalAttributes & 0x10) === 0x10) {\n return \"directory\";\n }\n\n return \"file\";\n}\n\nfunction assertAvailableRange(\n view: DataView,\n offset: number,\n length: number,\n description: string,\n): void {\n if (offset < 0 || length < 0 || offset > view.byteLength - length) {\n throw packageError(\"INVALID_ZIP\", `${description} is truncated.`);\n }\n}\n","import { packageError } from \"./errors.js\";\nimport { assertSafePackagePath } from \"./paths.js\";\nimport type { TooldeckPackageLimits } from \"./types.js\";\nimport type { CentralDirectoryEntry } from \"./zip-central-directory.js\";\n\nexport function validateZipEntries(\n entries: CentralDirectoryEntry[],\n limits: TooldeckPackageLimits,\n): void {\n let regularFileCount = 0;\n let uncompressedSizeBytes = 0;\n\n for (const entry of entries) {\n assertSafePackagePath(entry.path);\n\n if (entry.encrypted) {\n throw packageError(\"UNSUPPORTED_ENCRYPTED_ZIP\", \"Encrypted ZIP entries are not supported.\", {\n entryPath: entry.path,\n });\n }\n\n if (entry.compression !== 0 && entry.compression !== 8) {\n throw packageError(\"UNSUPPORTED_ZIP_ENTRY\", \"Unsupported ZIP compression method.\", {\n entryPath: entry.path,\n reason: `compression method ${entry.compression}`,\n });\n }\n\n if (entry.kind !== \"file\" && entry.kind !== \"directory\") {\n throw packageError(\"UNSUPPORTED_ZIP_ENTRY\", \"Only regular files are supported in packages.\", {\n entryPath: entry.path,\n reason: entry.kind,\n });\n }\n\n if (entry.kind === \"file\") {\n regularFileCount += 1;\n uncompressedSizeBytes += entry.uncompressedSizeBytes ?? 0;\n }\n }\n\n if (regularFileCount > limits.maxRegularFileCount) {\n throw packageError(\"TOO_MANY_FILES\", \"Tooldeck package contains too many files.\", {\n reason: `${regularFileCount} > ${limits.maxRegularFileCount}`,\n });\n }\n\n if (uncompressedSizeBytes > limits.maxUncompressedSizeBytes) {\n throw packageError(\n \"UNCOMPRESSED_SIZE_TOO_LARGE\",\n \"Tooldeck package is too large after unzip.\",\n {\n reason: `${uncompressedSizeBytes} > ${limits.maxUncompressedSizeBytes}`,\n },\n );\n }\n}\n","import { mkdir, readFile, realpath, stat, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport { strFromU8, strToU8, unzipSync, zipSync, type Zippable } from \"fflate\";\n\nimport { packageError } from \"./errors.js\";\nimport { assertSafePackagePath, normalizePackagePath } from \"./paths.js\";\nimport type { TooldeckPackageLimits } from \"./types.js\";\nimport type { ZipAdapter, ZipReadArchive, ZipWriteEntry } from \"./zip-adapter.js\";\nimport { parseCentralDirectory } from \"./zip-central-directory.js\";\nimport { validateZipEntries } from \"./zip-entry-policy.js\";\n\nexport class FflateZipAdapter implements ZipAdapter {\n async readArchive(archivePath: string, limits: TooldeckPackageLimits): Promise<ZipReadArchive> {\n await assertPackageFileSize(archivePath, limits);\n const data = await readPackageFile(archivePath);\n const entries = parseCentralDirectory(data);\n\n validateZipEntries(entries, limits);\n\n return {\n entries,\n readFile: async (entryPath) => {\n const normalizedPath = assertSafePackagePath(entryPath);\n const file = unzipSingleFile(data, normalizedPath);\n\n if (!file) {\n throw packageError(\"FILE_LIST_MISMATCH\", \"ZIP entry does not exist.\", {\n packagePath: archivePath,\n entryPath: normalizedPath,\n });\n }\n\n return file;\n },\n };\n }\n\n async writeArchive(archivePath: string, entries: ZipWriteEntry[]): Promise<void> {\n const zippable: Zippable = {};\n\n for (const entry of entries) {\n const normalizedPath = assertSafePackagePath(entry.path);\n zippable[normalizedPath] = [entry.data, { level: 6 }];\n }\n\n let data: Uint8Array;\n\n try {\n data = zipSync(zippable);\n } catch (error) {\n throw packageError(\"PACKAGE_WRITE_FAILED\", \"Tooldeck package could not be created.\", {\n packagePath: archivePath,\n reason: formatUnknownError(error),\n });\n }\n\n await writePackageFile(archivePath, data);\n }\n\n async extractArchive(options: {\n archivePath: string;\n destinationDir: string;\n limits: TooldeckPackageLimits;\n }): Promise<void> {\n await assertPackageFileSize(options.archivePath, options.limits);\n const data = await readPackageFile(options.archivePath);\n const entries = parseCentralDirectory(data);\n validateZipEntries(entries, options.limits);\n const files = unzipArchive(data, options.archivePath);\n const destinationDir = path.resolve(options.destinationDir);\n\n await createExtractionDirectory(destinationDir, options.archivePath);\n const resolvedDestinationDir = path.resolve(destinationDir);\n const destinationRealpath = await getExtractionRealpath(\n destinationDir,\n options.archivePath,\n \"<destination>\",\n );\n\n for (const entry of entries) {\n if (entry.kind !== \"file\") {\n continue;\n }\n\n const normalizedPath = assertSafePackagePath(entry.path);\n const fileData = files.get(normalizedPath);\n\n if (!fileData) {\n throw packageError(\"FILE_LIST_MISMATCH\", \"ZIP entry was not extracted.\", {\n packagePath: options.archivePath,\n entryPath: normalizedPath,\n });\n }\n\n const outputPath = path.resolve(destinationDir, ...normalizedPath.split(\"/\"));\n assertContainedPath(resolvedDestinationDir, outputPath, normalizedPath);\n await createExtractionDirectory(\n path.dirname(outputPath),\n options.archivePath,\n normalizedPath,\n );\n await writeExtractedFile(outputPath, fileData, options.archivePath, normalizedPath);\n\n const outputRealpath = await getExtractionRealpath(\n outputPath,\n options.archivePath,\n normalizedPath,\n );\n assertContainedPath(destinationRealpath, outputRealpath, normalizedPath);\n }\n }\n}\n\nfunction unzipSingleFile(data: Uint8Array, entryPath: string): Uint8Array | undefined {\n try {\n const files = unzipSync(data, {\n filter: (file) => normalizePackagePath(file.name) === entryPath,\n });\n\n return Object.entries(files).find(([path]) => normalizePackagePath(path) === entryPath)?.[1];\n } catch (error) {\n throw mapFflateError(error);\n }\n}\n\nfunction unzipArchive(data: Uint8Array, archivePath: string): Map<string, Uint8Array> {\n try {\n return new Map(\n Object.entries(unzipSync(data)).map(([entryPath, fileData]) => [\n normalizePackagePath(entryPath),\n fileData,\n ]),\n );\n } catch (error) {\n throw packageError(\"PACKAGE_EXTRACT_FAILED\", \"Tooldeck package could not be extracted.\", {\n packagePath: archivePath,\n reason: formatUnknownError(error),\n });\n }\n}\n\nasync function assertPackageFileSize(\n archivePath: string,\n limits: TooldeckPackageLimits,\n): Promise<void> {\n let archiveStat: Awaited<ReturnType<typeof stat>>;\n\n try {\n archiveStat = await stat(archivePath);\n } catch (error) {\n throw packageError(\"PACKAGE_READ_FAILED\", \"Tooldeck package file could not be inspected.\", {\n packagePath: archivePath,\n reason: formatUnknownError(error),\n });\n }\n\n if (archiveStat.size > limits.maxPackageSizeBytes) {\n throw packageError(\"PACKAGE_TOO_LARGE\", \"Tooldeck package file is too large.\", {\n packagePath: archivePath,\n reason: `${archiveStat.size} > ${limits.maxPackageSizeBytes}`,\n });\n }\n}\n\nasync function readPackageFile(archivePath: string): Promise<Uint8Array> {\n try {\n return await readFile(archivePath);\n } catch (error) {\n throw packageError(\"PACKAGE_READ_FAILED\", \"Tooldeck package could not be read.\", {\n packagePath: archivePath,\n reason: formatUnknownError(error),\n });\n }\n}\n\nasync function writePackageFile(archivePath: string, data: Uint8Array): Promise<void> {\n try {\n await mkdir(path.dirname(archivePath), { recursive: true });\n await writeFile(archivePath, data);\n } catch (error) {\n throw packageError(\"PACKAGE_WRITE_FAILED\", \"Tooldeck package could not be written.\", {\n packagePath: archivePath,\n reason: formatUnknownError(error),\n });\n }\n}\n\nasync function createExtractionDirectory(\n directoryPath: string,\n archivePath: string,\n entryPath?: string,\n): Promise<void> {\n try {\n await mkdir(directoryPath, { recursive: true });\n } catch (error) {\n throw packageError(\n \"PACKAGE_EXTRACT_FAILED\",\n \"Package extraction directory could not be created.\",\n {\n packagePath: archivePath,\n entryPath,\n reason: formatUnknownError(error),\n },\n );\n }\n}\n\nasync function writeExtractedFile(\n outputPath: string,\n data: Uint8Array,\n archivePath: string,\n entryPath: string,\n): Promise<void> {\n try {\n await writeFile(outputPath, data);\n } catch (error) {\n throw packageError(\"PACKAGE_EXTRACT_FAILED\", \"Package entry could not be extracted.\", {\n packagePath: archivePath,\n entryPath,\n reason: formatUnknownError(error),\n });\n }\n}\n\nasync function getExtractionRealpath(\n targetPath: string,\n archivePath: string,\n entryPath: string,\n): Promise<string> {\n try {\n return await realpath(targetPath);\n } catch (error) {\n throw packageError(\"PACKAGE_EXTRACT_FAILED\", \"Extracted path could not be resolved.\", {\n packagePath: archivePath,\n entryPath,\n reason: formatUnknownError(error),\n });\n }\n}\n\nfunction assertContainedPath(root: string, target: string, entryPath: string): void {\n const relative = path.relative(root, target);\n\n if (relative === \"..\" || relative.startsWith(`..${path.sep}`) || path.isAbsolute(relative)) {\n throw packageError(\n \"EXTRACTION_ESCAPE\",\n \"Package extraction escaped the destination directory.\",\n {\n entryPath,\n reason: target,\n },\n );\n }\n}\n\nfunction mapFflateError(error: unknown): never {\n if (isFlateError(error) && error.code === 14) {\n throw packageError(\"UNSUPPORTED_ZIP_ENTRY\", \"Unsupported ZIP compression method.\", {\n reason: error.message,\n });\n }\n\n throw packageError(\"INVALID_ZIP\", \"ZIP could not be read.\", {\n reason: formatUnknownError(error),\n });\n}\n\nfunction isFlateError(error: unknown): error is Error & { code: number } {\n return error instanceof Error && typeof (error as { code?: unknown }).code === \"number\";\n}\n\nfunction formatUnknownError(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nexport function textToBytes(text: string): Uint8Array {\n return strToU8(text);\n}\n\nexport function bytesToText(data: Uint8Array): string {\n return strFromU8(data);\n}\n","import { manifestV1Schema } from \"@tooldeck/protocol\";\nimport Ajv, { type ErrorObject } from \"ajv\";\n\nimport { packageError } from \"./errors.js\";\nimport { assertSafePackagePath } from \"./paths.js\";\nimport type { TooldeckPackagePluginManifest } from \"./types.js\";\nimport { isRecord } from \"./utils.js\";\n\nconst ajv = new Ajv({\n allErrors: true,\n strict: false,\n validateSchema: false,\n});\nconst validatePackageManifestSchema = ajv.compile<TooldeckPackagePluginManifest>(\n createPackageManifestSchema(),\n);\n\nexport function parsePluginManifestText(\n text: string,\n manifestPath: string,\n): TooldeckPackagePluginManifest {\n let value: unknown;\n\n try {\n value = JSON.parse(text);\n } catch (error) {\n throw packageError(\"INVALID_PLUGIN_MANIFEST\", \"Plugin manifest is not valid JSON.\", {\n manifestPath,\n reason: error instanceof Error ? error.message : String(error),\n });\n }\n\n return validatePluginManifestShape(value, manifestPath);\n}\n\nexport function validatePluginManifestShape(\n value: unknown,\n manifestPath: string,\n): TooldeckPackagePluginManifest {\n if (!isRecord(value)) {\n throw packageError(\"INVALID_PLUGIN_MANIFEST\", \"Plugin manifest must be an object.\", {\n manifestPath,\n });\n }\n\n if (!validatePackageManifestSchema(value)) {\n throw formatManifestSchemaError(validatePackageManifestSchema.errors ?? [], manifestPath);\n }\n\n assertSafePackagePath(value.runtime.entry, \"runtime.entry\");\n assertLocalePaths(value, manifestPath);\n\n return value;\n}\n\nfunction createPackageManifestSchema(): object {\n const schema = structuredClone(manifestV1Schema) as {\n definitions?: {\n runtime?: {\n properties?: {\n kind?: unknown;\n };\n };\n tooldeckInputJsonSchema?: unknown;\n tooldeckJsonSchema?: unknown;\n };\n };\n\n if (schema.definitions?.runtime?.properties) {\n schema.definitions.runtime.properties.kind = {\n type: \"string\",\n minLength: 1,\n };\n }\n\n if (schema.definitions) {\n schema.definitions.tooldeckInputJsonSchema = {\n type: \"object\",\n description:\n \"A command input JSON Schema object. Full JSON Schema validation is deferred to command input handling.\",\n };\n schema.definitions.tooldeckJsonSchema = {\n type: \"object\",\n description:\n \"A JSON Schema object. Full JSON Schema validation is deferred to command input handling.\",\n };\n }\n\n return schema;\n}\n\nfunction formatManifestSchemaError(\n errors: ErrorObject[],\n manifestPath: string,\n): ReturnType<typeof packageError> {\n const error = errors[0];\n const message = error?.message\n ? `Plugin manifest schema violation: ${error.message}.`\n : \"Plugin manifest does not match the protocol schema.\";\n\n return packageError(\"INVALID_PLUGIN_MANIFEST\", message, {\n manifestPath,\n fieldPath: error ? formatAjvFieldPath(error) : undefined,\n reason: error?.keyword,\n });\n}\n\nfunction formatAjvFieldPath(error: ErrorObject): string | undefined {\n const path = pointerToFieldPath(error.instancePath);\n\n if (error.keyword === \"required\") {\n const missingProperty = getStringParam(error.params, \"missingProperty\");\n return joinFieldPath(path, missingProperty);\n }\n\n if (error.keyword === \"additionalProperties\") {\n const additionalProperty = getStringParam(error.params, \"additionalProperty\");\n return joinFieldPath(path, additionalProperty);\n }\n\n return path;\n}\n\nfunction pointerToFieldPath(pointer: string): string | undefined {\n if (!pointer) {\n return undefined;\n }\n\n const segments = pointer\n .slice(1)\n .split(\"/\")\n .map((segment) => segment.replace(/~1/g, \"/\").replace(/~0/g, \"~\"));\n\n return segments\n .map((segment, index) =>\n /^\\d+$/.test(segment) ? `[${segment}]` : `${index === 0 ? \"\" : \".\"}${segment}`,\n )\n .join(\"\");\n}\n\nfunction joinFieldPath(base: string | undefined, property: string | undefined): string | undefined {\n if (!property) {\n return base;\n }\n\n return base ? `${base}.${property}` : property;\n}\n\nfunction getStringParam(params: Record<string, unknown>, name: string): string | undefined {\n const value = params[name];\n\n return typeof value === \"string\" ? value : undefined;\n}\n\nfunction assertLocalePaths(value: Record<string, unknown>, manifestPath: string): void {\n if (value.locales === undefined) {\n return;\n }\n\n if (!isRecord(value.locales)) {\n throw packageError(\"INVALID_PLUGIN_MANIFEST\", \"Plugin manifest locales must be an object.\", {\n manifestPath,\n fieldPath: \"locales\",\n });\n }\n\n for (const [locale, localePath] of Object.entries(value.locales)) {\n if (typeof localePath !== \"string\") {\n throw packageError(\"INVALID_PLUGIN_MANIFEST\", \"Plugin locale path must be a string.\", {\n manifestPath,\n fieldPath: `locales.${locale}`,\n });\n }\n\n assertSafePackagePath(localePath, `locales.${locale}`);\n }\n}\n","import { stat } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport {\n DEFAULT_PACKAGE_LIMITS,\n TOOLDECK_PACKAGE_EXTENSION,\n TOOLDECK_PACKAGE_MANIFEST_PATH,\n TOOLDECK_PLUGIN_MANIFEST_PATH,\n} from \"./constants.js\";\nimport { computePackageDigest } from \"./digest.js\";\nimport { packageError } from \"./errors.js\";\nimport { bytesToText, FflateZipAdapter } from \"./fflate-zip-adapter.js\";\nimport { parsePluginManifestText } from \"./manifest.js\";\nimport {\n assertPackageFileListMatches,\n validateTooldeckPackageManifest,\n} from \"./package-manifest.js\";\nimport { assertSafePackagePath } from \"./paths.js\";\nimport type {\n ReadTooldeckPackageOptions,\n TooldeckPackageLimits,\n TooldeckPackageSummary,\n UnpackTooldeckPackageOptions,\n} from \"./types.js\";\nimport type { ZipAdapter } from \"./zip-adapter.js\";\n\nconst defaultZipAdapter = new FflateZipAdapter();\n\nexport async function readTooldeckPackage(\n options: ReadTooldeckPackageOptions,\n zipAdapter: ZipAdapter = defaultZipAdapter,\n): Promise<TooldeckPackageSummary> {\n assertTooldeckPackageExtension(options.packagePath);\n const limits = resolvePackageLimits(options.limits);\n const archive = await zipAdapter.readArchive(options.packagePath, limits);\n const actualFiles = archive.entries\n .filter((entry) => entry.kind === \"file\")\n .map((entry) => assertSafePackagePath(entry.path));\n\n if (!actualFiles.includes(TOOLDECK_PACKAGE_MANIFEST_PATH)) {\n throw packageError(\"MISSING_PACKAGE_MANIFEST\", \"Package is missing tooldeck-package.json.\", {\n packagePath: options.packagePath,\n entryPath: TOOLDECK_PACKAGE_MANIFEST_PATH,\n });\n }\n\n if (!actualFiles.includes(TOOLDECK_PLUGIN_MANIFEST_PATH)) {\n throw packageError(\"MISSING_PLUGIN_MANIFEST\", \"Package is missing root manifest.json.\", {\n packagePath: options.packagePath,\n entryPath: TOOLDECK_PLUGIN_MANIFEST_PATH,\n });\n }\n\n const packageManifestBytes = await archive.readFile(TOOLDECK_PACKAGE_MANIFEST_PATH);\n const packageManifest = validateTooldeckPackageManifest(\n parseJson(bytesToText(packageManifestBytes), TOOLDECK_PACKAGE_MANIFEST_PATH),\n );\n const files = assertPackageFileListMatches({\n declaredFiles: packageManifest.files,\n actualFiles,\n });\n\n const pluginManifestBytes = await archive.readFile(TOOLDECK_PLUGIN_MANIFEST_PATH);\n const pluginManifest = parsePluginManifestText(\n bytesToText(pluginManifestBytes),\n TOOLDECK_PLUGIN_MANIFEST_PATH,\n );\n const runtimeEntry = assertSafePackagePath(pluginManifest.runtime.entry, \"runtime.entry\");\n\n if (!files.includes(runtimeEntry)) {\n throw packageError(\"MISSING_RUNTIME_ENTRY\", \"Package is missing manifest runtime entry.\", {\n packagePath: options.packagePath,\n entryPath: runtimeEntry,\n fieldPath: \"runtime.entry\",\n });\n }\n\n const archiveStat = await stat(options.packagePath);\n const packageDigest = await computePackageDigest(options.packagePath);\n const uncompressedSizeBytes = archive.entries\n .filter((entry) => entry.kind === \"file\")\n .reduce((sum, entry) => sum + (entry.uncompressedSizeBytes ?? 0), 0);\n\n return {\n packagePath: options.packagePath,\n packageDigest,\n packageSizeBytes: archiveStat.size,\n packageManifest,\n pluginManifest,\n files,\n uncompressedSizeBytes,\n };\n}\n\nexport async function validateTooldeckPackage(\n options: ReadTooldeckPackageOptions,\n zipAdapter?: ZipAdapter,\n): Promise<TooldeckPackageSummary> {\n return readTooldeckPackage(options, zipAdapter);\n}\n\nexport async function unpackTooldeckPackage(\n options: UnpackTooldeckPackageOptions,\n zipAdapter: ZipAdapter = defaultZipAdapter,\n): Promise<TooldeckPackageSummary> {\n const summary = await readTooldeckPackage(options, zipAdapter);\n await zipAdapter.extractArchive({\n archivePath: options.packagePath,\n destinationDir: options.destinationDir,\n limits: resolvePackageLimits(options.limits),\n });\n\n return summary;\n}\n\nexport function resolvePackageLimits(\n limits: Partial<TooldeckPackageLimits> | undefined,\n): TooldeckPackageLimits {\n return {\n ...DEFAULT_PACKAGE_LIMITS,\n ...limits,\n };\n}\n\nexport function assertTooldeckPackageExtension(packagePath: string): void {\n if (path.extname(packagePath) !== TOOLDECK_PACKAGE_EXTENSION) {\n throw packageError(\"INVALID_PACKAGE_EXTENSION\", \"Tooldeck packages must use .tdplugin.\", {\n packagePath,\n reason: `got ${path.extname(packagePath) || \"<none>\"}`,\n });\n }\n}\n\nfunction parseJson(text: string, manifestPath: string): unknown {\n try {\n return JSON.parse(text);\n } catch (error) {\n throw packageError(\"INVALID_PACKAGE_METADATA\", \"Package manifest is not valid JSON.\", {\n manifestPath,\n reason: error instanceof Error ? error.message : String(error),\n });\n }\n}\n","import { readdir, readFile, stat } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport {\n DEFAULT_PACKAGE_INCLUDE_DIRS,\n TOOLDECK_PACKAGE_MANIFEST_PATH,\n TOOLDECK_PLUGIN_MANIFEST_PATH,\n} from \"./constants.js\";\nimport { computePackageDigest } from \"./digest.js\";\nimport { FflateZipAdapter, textToBytes } from \"./fflate-zip-adapter.js\";\nimport { parsePluginManifestText } from \"./manifest.js\";\nimport { createTooldeckPackageManifest } from \"./package-manifest.js\";\nimport { readTooldeckPackage } from \"./package-reader.js\";\nimport { assertSafePackagePath, dedupeAndSortPackagePaths } from \"./paths.js\";\nimport type {\n PackTooldeckPluginOptions,\n PackTooldeckPluginResult,\n TooldeckPackageFile,\n TooldeckPackagePluginManifest,\n} from \"./types.js\";\nimport type { ZipAdapter, ZipWriteEntry } from \"./zip-adapter.js\";\n\nconst defaultZipAdapter = new FflateZipAdapter();\n\nexport async function packTooldeckPlugin(\n options: PackTooldeckPluginOptions,\n zipAdapter: ZipAdapter = defaultZipAdapter,\n): Promise<PackTooldeckPluginResult> {\n const manifestFile = path.resolve(\n options.manifestPath ??\n path.join(options.projectDir ?? process.cwd(), TOOLDECK_PLUGIN_MANIFEST_PATH),\n );\n const projectDir = path.resolve(options.projectDir ?? path.dirname(manifestFile));\n const manifestText = await readFile(manifestFile, \"utf8\");\n const pluginManifest = parsePluginManifestText(manifestText, TOOLDECK_PLUGIN_MANIFEST_PATH);\n const outputPath =\n options.outputPath ??\n path.join(projectDir, `${pluginManifest.id}-${pluginManifest.version}.tdplugin`);\n\n const files = await collectTooldeckPackageFiles(projectDir, pluginManifest, manifestText);\n const packageManifest = createTooldeckPackageManifest({\n createdAt: options.createdAt,\n files: files.map((file) => file.path),\n });\n const entries: ZipWriteEntry[] = [\n ...files,\n {\n path: TOOLDECK_PACKAGE_MANIFEST_PATH,\n data: textToBytes(`${JSON.stringify(packageManifest, null, 2)}\\n`),\n },\n ];\n\n await zipAdapter.writeArchive(outputPath, entries);\n const summary = await readTooldeckPackage(\n {\n packagePath: outputPath,\n limits: options.limits,\n },\n zipAdapter,\n );\n\n return {\n packagePath: outputPath,\n packageManifest: summary.packageManifest,\n pluginManifest,\n files: summary.files,\n packageDigest: await computePackageDigest(outputPath),\n packageSizeBytes: summary.packageSizeBytes,\n };\n}\n\nexport async function collectTooldeckPackageFiles(\n projectDir: string,\n pluginManifest: TooldeckPackagePluginManifest,\n manifestText?: string,\n): Promise<TooldeckPackageFile[]> {\n const packagePaths = dedupeAndSortPackagePaths([\n TOOLDECK_PLUGIN_MANIFEST_PATH,\n pluginManifest.runtime.entry,\n ...Object.values(pluginManifest.locales ?? {}).filter(\n (localePath) => typeof localePath === \"string\",\n ),\n ...(await collectDefaultDirectoryPackagePaths(projectDir)),\n ]);\n\n const files: TooldeckPackageFile[] = [];\n\n for (const packagePath of packagePaths) {\n if (packagePath === TOOLDECK_PACKAGE_MANIFEST_PATH) {\n continue;\n }\n\n if (packagePath === TOOLDECK_PLUGIN_MANIFEST_PATH && manifestText !== undefined) {\n files.push({\n path: packagePath,\n data: textToBytes(manifestText.endsWith(\"\\n\") ? manifestText : `${manifestText}\\n`),\n });\n } else {\n const absolutePath = resolveProjectPackagePath(projectDir, packagePath);\n files.push({\n path: packagePath,\n data: await readFile(absolutePath),\n });\n }\n }\n\n return files;\n}\n\nasync function collectDefaultDirectoryPackagePaths(projectDir: string): Promise<string[]> {\n const paths: string[] = [];\n\n for (const directory of DEFAULT_PACKAGE_INCLUDE_DIRS) {\n const absoluteDirectory = path.join(projectDir, directory);\n\n if (!(await isDirectory(absoluteDirectory))) {\n continue;\n }\n\n paths.push(...(await collectRegularFiles(projectDir, absoluteDirectory)));\n }\n\n return paths;\n}\n\nasync function collectRegularFiles(projectDir: string, directory: string): Promise<string[]> {\n const entries = await readdir(directory, { withFileTypes: true });\n const files: string[] = [];\n\n for (const entry of entries) {\n const absolutePath = path.join(directory, entry.name);\n\n if (entry.isDirectory()) {\n files.push(...(await collectRegularFiles(projectDir, absolutePath)));\n continue;\n }\n\n if (!entry.isFile()) {\n continue;\n }\n\n files.push(toPackagePath(projectDir, absolutePath));\n }\n\n return files;\n}\n\nfunction resolveProjectPackagePath(projectDir: string, packagePath: string): string {\n const normalizedPath = assertSafePackagePath(packagePath);\n const absolutePath = path.resolve(projectDir, ...normalizedPath.split(\"/\"));\n const relative = path.relative(projectDir, absolutePath);\n\n if (relative.startsWith(\"..\") || path.isAbsolute(relative)) {\n throw new Error(`Package path escapes the project directory: ${packagePath}`);\n }\n\n return absolutePath;\n}\n\nfunction toPackagePath(projectDir: string, absolutePath: string): string {\n return assertSafePackagePath(path.relative(projectDir, absolutePath).replaceAll(path.sep, \"/\"));\n}\n\nasync function isDirectory(filePath: string): Promise<boolean> {\n try {\n return (await stat(filePath)).isDirectory();\n } catch {\n return false;\n }\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { TooldeckPackagePluginManifest } from "./types.js";
|
|
2
|
+
export declare function parsePluginManifestText(text: string, manifestPath: string): TooldeckPackagePluginManifest;
|
|
3
|
+
export declare function validatePluginManifestShape(value: unknown, manifestPath: string): TooldeckPackagePluginManifest;
|
|
4
|
+
//# sourceMappingURL=manifest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,YAAY,CAAC;AAYhE,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,MAAM,GACnB,6BAA6B,CAa/B;AAED,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,OAAO,EACd,YAAY,EAAE,MAAM,GACnB,6BAA6B,CAe/B"}
|
package/dist/pack.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { PackTooldeckPluginOptions, PackTooldeckPluginResult, TooldeckPackageFile, TooldeckPackagePluginManifest } from "./types.js";
|
|
2
|
+
import type { ZipAdapter } from "./zip-adapter.js";
|
|
3
|
+
export declare function packTooldeckPlugin(options: PackTooldeckPluginOptions, zipAdapter?: ZipAdapter): Promise<PackTooldeckPluginResult>;
|
|
4
|
+
export declare function collectTooldeckPackageFiles(projectDir: string, pluginManifest: TooldeckPackagePluginManifest, manifestText?: string): Promise<TooldeckPackageFile[]>;
|
|
5
|
+
//# sourceMappingURL=pack.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pack.d.ts","sourceRoot":"","sources":["../src/pack.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EACV,yBAAyB,EACzB,wBAAwB,EACxB,mBAAmB,EACnB,6BAA6B,EAC9B,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,UAAU,EAAiB,MAAM,kBAAkB,CAAC;AAIlE,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,yBAAyB,EAClC,UAAU,GAAE,UAA8B,GACzC,OAAO,CAAC,wBAAwB,CAAC,CA0CnC;AAED,wBAAsB,2BAA2B,CAC/C,UAAU,EAAE,MAAM,EAClB,cAAc,EAAE,6BAA6B,EAC7C,YAAY,CAAC,EAAE,MAAM,GACpB,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAgChC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { TooldeckPackageManifest } from "./types.js";
|
|
2
|
+
export declare function createTooldeckPackageManifest(options: {
|
|
3
|
+
createdAt?: Date;
|
|
4
|
+
files: Iterable<string>;
|
|
5
|
+
}): TooldeckPackageManifest;
|
|
6
|
+
export declare function validateTooldeckPackageManifest(value: unknown): TooldeckPackageManifest;
|
|
7
|
+
export declare function assertPackageFileListMatches(options: {
|
|
8
|
+
declaredFiles: Iterable<string>;
|
|
9
|
+
actualFiles: Iterable<string>;
|
|
10
|
+
}): string[];
|
|
11
|
+
//# sourceMappingURL=package-manifest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"package-manifest.d.ts","sourceRoot":"","sources":["../src/package-manifest.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAG1D,wBAAgB,6BAA6B,CAAC,OAAO,EAAE;IACrD,SAAS,CAAC,EAAE,IAAI,CAAC;IACjB,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;CACzB,GAAG,uBAAuB,CAa1B;AAED,wBAAgB,+BAA+B,CAAC,KAAK,EAAE,OAAO,GAAG,uBAAuB,CA6EvF;AAED,wBAAgB,4BAA4B,CAAC,OAAO,EAAE;IACpD,aAAa,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAChC,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;CAC/B,GAAG,MAAM,EAAE,CAuBX"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ReadTooldeckPackageOptions, TooldeckPackageLimits, TooldeckPackageSummary, UnpackTooldeckPackageOptions } from "./types.js";
|
|
2
|
+
import type { ZipAdapter } from "./zip-adapter.js";
|
|
3
|
+
export declare function readTooldeckPackage(options: ReadTooldeckPackageOptions, zipAdapter?: ZipAdapter): Promise<TooldeckPackageSummary>;
|
|
4
|
+
export declare function validateTooldeckPackage(options: ReadTooldeckPackageOptions, zipAdapter?: ZipAdapter): Promise<TooldeckPackageSummary>;
|
|
5
|
+
export declare function unpackTooldeckPackage(options: UnpackTooldeckPackageOptions, zipAdapter?: ZipAdapter): Promise<TooldeckPackageSummary>;
|
|
6
|
+
export declare function resolvePackageLimits(limits: Partial<TooldeckPackageLimits> | undefined): TooldeckPackageLimits;
|
|
7
|
+
export declare function assertTooldeckPackageExtension(packagePath: string): void;
|
|
8
|
+
//# sourceMappingURL=package-reader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"package-reader.d.ts","sourceRoot":"","sources":["../src/package-reader.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EACV,0BAA0B,EAC1B,qBAAqB,EACrB,sBAAsB,EACtB,4BAA4B,EAC7B,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAInD,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,0BAA0B,EACnC,UAAU,GAAE,UAA8B,GACzC,OAAO,CAAC,sBAAsB,CAAC,CA6DjC;AAED,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,0BAA0B,EACnC,UAAU,CAAC,EAAE,UAAU,GACtB,OAAO,CAAC,sBAAsB,CAAC,CAEjC;AAED,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,4BAA4B,EACrC,UAAU,GAAE,UAA8B,GACzC,OAAO,CAAC,sBAAsB,CAAC,CASjC;AAED,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,OAAO,CAAC,qBAAqB,CAAC,GAAG,SAAS,GACjD,qBAAqB,CAKvB;AAED,wBAAgB,8BAA8B,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAOxE"}
|
package/dist/paths.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare function normalizePackagePath(input: string): string;
|
|
2
|
+
export declare function assertSafePackagePath(input: string, fieldPath?: string): string;
|
|
3
|
+
export declare function isNodeModulesPath(input: string): boolean;
|
|
4
|
+
export declare function dedupeAndSortPackagePaths(paths: Iterable<string>): string[];
|
|
5
|
+
export declare function comparePackagePaths(a: string, b: string): number;
|
|
6
|
+
export declare function packagePathStartsWith(path: string, directory: string): boolean;
|
|
7
|
+
//# sourceMappingURL=paths.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"AAEA,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAM1D;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAiD/E;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAIxD;AAED,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,MAAM,EAAE,CAI3E;AAED,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAEhE;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAO9E"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import type { LocalizedString, PluginContributes } from "@tooldeck/protocol";
|
|
2
|
+
export interface TooldeckPackageLimits {
|
|
3
|
+
maxPackageSizeBytes: number;
|
|
4
|
+
maxUncompressedSizeBytes: number;
|
|
5
|
+
maxRegularFileCount: number;
|
|
6
|
+
}
|
|
7
|
+
export interface TooldeckPackageManifest {
|
|
8
|
+
formatVersion: "1.0";
|
|
9
|
+
manifestPath: "manifest.json";
|
|
10
|
+
createdAt: string;
|
|
11
|
+
files: string[];
|
|
12
|
+
}
|
|
13
|
+
export interface TooldeckPackageRuntime {
|
|
14
|
+
kind: string;
|
|
15
|
+
entry: string;
|
|
16
|
+
}
|
|
17
|
+
export interface TooldeckPackagePluginManifest {
|
|
18
|
+
$schema?: string;
|
|
19
|
+
schemaVersion: "1.0";
|
|
20
|
+
id: string;
|
|
21
|
+
name: LocalizedString;
|
|
22
|
+
description?: LocalizedString;
|
|
23
|
+
version: string;
|
|
24
|
+
runtime: TooldeckPackageRuntime;
|
|
25
|
+
defaultLocale?: string;
|
|
26
|
+
locales?: Record<string, string>;
|
|
27
|
+
contributes?: PluginContributes;
|
|
28
|
+
}
|
|
29
|
+
export interface TooldeckPackageSummary {
|
|
30
|
+
packagePath: string;
|
|
31
|
+
packageDigest: string;
|
|
32
|
+
packageSizeBytes: number;
|
|
33
|
+
packageManifest: TooldeckPackageManifest;
|
|
34
|
+
pluginManifest: TooldeckPackagePluginManifest;
|
|
35
|
+
files: string[];
|
|
36
|
+
uncompressedSizeBytes: number;
|
|
37
|
+
}
|
|
38
|
+
export interface PackTooldeckPluginOptions {
|
|
39
|
+
projectDir?: string;
|
|
40
|
+
manifestPath?: string;
|
|
41
|
+
outputPath?: string;
|
|
42
|
+
createdAt?: Date;
|
|
43
|
+
limits?: Partial<TooldeckPackageLimits>;
|
|
44
|
+
}
|
|
45
|
+
export interface ReadTooldeckPackageOptions {
|
|
46
|
+
packagePath: string;
|
|
47
|
+
limits?: Partial<TooldeckPackageLimits>;
|
|
48
|
+
}
|
|
49
|
+
export interface UnpackTooldeckPackageOptions extends ReadTooldeckPackageOptions {
|
|
50
|
+
destinationDir: string;
|
|
51
|
+
}
|
|
52
|
+
export interface TooldeckPackageFile {
|
|
53
|
+
path: string;
|
|
54
|
+
data: Uint8Array;
|
|
55
|
+
}
|
|
56
|
+
export interface PackTooldeckPluginResult {
|
|
57
|
+
packagePath: string;
|
|
58
|
+
packageManifest: TooldeckPackageManifest;
|
|
59
|
+
pluginManifest: TooldeckPackagePluginManifest;
|
|
60
|
+
files: string[];
|
|
61
|
+
packageDigest: string;
|
|
62
|
+
packageSizeBytes: number;
|
|
63
|
+
}
|
|
64
|
+
export interface PackageJsonTooldeckConfig {
|
|
65
|
+
package?: {
|
|
66
|
+
include?: string[];
|
|
67
|
+
exclude?: string[];
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAE7E,MAAM,WAAW,qBAAqB;IACpC,mBAAmB,EAAE,MAAM,CAAC;IAC5B,wBAAwB,EAAE,MAAM,CAAC;IACjC,mBAAmB,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,uBAAuB;IACtC,aAAa,EAAE,KAAK,CAAC;IACrB,YAAY,EAAE,eAAe,CAAC;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,6BAA6B;IAC5C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,KAAK,CAAC;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,eAAe,CAAC;IACtB,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,sBAAsB,CAAC;IAChC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,WAAW,CAAC,EAAE,iBAAiB,CAAC;CACjC;AAED,MAAM,WAAW,sBAAsB;IACrC,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,uBAAuB,CAAC;IACzC,cAAc,EAAE,6BAA6B,CAAC;IAC9C,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,qBAAqB,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,yBAAyB;IACxC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,IAAI,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC,qBAAqB,CAAC,CAAC;CACzC;AAED,MAAM,WAAW,0BAA0B;IACzC,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC,qBAAqB,CAAC,CAAC;CACzC;AAED,MAAM,WAAW,4BAA6B,SAAQ,0BAA0B;IAC9E,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,UAAU,CAAC;CAClB;AAED,MAAM,WAAW,wBAAwB;IACvC,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,uBAAuB,CAAC;IACzC,cAAc,EAAE,6BAA6B,CAAC;IAC9C,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,yBAAyB;IACxC,OAAO,CAAC,EAAE;QACR,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;QACnB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;KACpB,CAAC;CACH"}
|
package/dist/utils.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEzE"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { TooldeckPackageLimits } from "./types.js";
|
|
2
|
+
export type ZipEntryKind = "file" | "directory" | "symlink" | "special";
|
|
3
|
+
export interface ZipEntryMetadata {
|
|
4
|
+
path: string;
|
|
5
|
+
kind: ZipEntryKind;
|
|
6
|
+
compressedSizeBytes?: number;
|
|
7
|
+
uncompressedSizeBytes?: number;
|
|
8
|
+
}
|
|
9
|
+
export interface ZipWriteEntry {
|
|
10
|
+
path: string;
|
|
11
|
+
data: Uint8Array;
|
|
12
|
+
}
|
|
13
|
+
export interface ZipReadArchive {
|
|
14
|
+
entries: ZipEntryMetadata[];
|
|
15
|
+
readFile(path: string): Promise<Uint8Array>;
|
|
16
|
+
}
|
|
17
|
+
export interface ZipAdapter {
|
|
18
|
+
readArchive(path: string, limits: TooldeckPackageLimits): Promise<ZipReadArchive>;
|
|
19
|
+
writeArchive(path: string, entries: ZipWriteEntry[]): Promise<void>;
|
|
20
|
+
extractArchive(options: {
|
|
21
|
+
archivePath: string;
|
|
22
|
+
destinationDir: string;
|
|
23
|
+
limits: TooldeckPackageLimits;
|
|
24
|
+
}): Promise<void>;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=zip-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zip-adapter.d.ts","sourceRoot":"","sources":["../src/zip-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAExD,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,WAAW,GAAG,SAAS,GAAG,SAAS,CAAC;AAExE,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,YAAY,CAAC;IACnB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,UAAU,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;CAC7C;AAED,MAAM,WAAW,UAAU;IACzB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,qBAAqB,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IAClF,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpE,cAAc,CAAC,OAAO,EAAE;QACtB,WAAW,EAAE,MAAM,CAAC;QACpB,cAAc,EAAE,MAAM,CAAC;QACvB,MAAM,EAAE,qBAAqB,CAAC;KAC/B,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACnB"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ZipEntryMetadata } from "./zip-adapter.js";
|
|
2
|
+
export interface CentralDirectoryEntry extends ZipEntryMetadata {
|
|
3
|
+
compression: number;
|
|
4
|
+
encrypted: boolean;
|
|
5
|
+
}
|
|
6
|
+
export declare function parseCentralDirectory(data: Uint8Array): CentralDirectoryEntry[];
|
|
7
|
+
//# sourceMappingURL=zip-central-directory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zip-central-directory.d.ts","sourceRoot":"","sources":["../src/zip-central-directory.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAgB,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEvE,MAAM,WAAW,qBAAsB,SAAQ,gBAAgB;IAC7D,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;CACpB;AAYD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,UAAU,GAAG,qBAAqB,EAAE,CA8G/E"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { TooldeckPackageLimits } from "./types.js";
|
|
2
|
+
import type { CentralDirectoryEntry } from "./zip-central-directory.js";
|
|
3
|
+
export declare function validateZipEntries(entries: CentralDirectoryEntry[], limits: TooldeckPackageLimits): void;
|
|
4
|
+
//# sourceMappingURL=zip-entry-policy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zip-entry-policy.d.ts","sourceRoot":"","sources":["../src/zip-entry-policy.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AACxD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAExE,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,qBAAqB,EAAE,EAChC,MAAM,EAAE,qBAAqB,GAC5B,IAAI,CAgDN"}
|
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@tooldeck/plugin-package",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Tooldeck .tdplugin package format utilities.",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/origin-coding/tooldeck.git",
|
|
9
|
+
"directory": "packages/plugin-package"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"dist"
|
|
13
|
+
],
|
|
14
|
+
"type": "module",
|
|
15
|
+
"main": "./dist/index.js",
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
17
|
+
"exports": {
|
|
18
|
+
".": {
|
|
19
|
+
"types": "./dist/index.d.ts",
|
|
20
|
+
"import": "./dist/index.js"
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"publishConfig": {
|
|
24
|
+
"access": "public"
|
|
25
|
+
},
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"ajv": "^8.20.0",
|
|
28
|
+
"fflate": "^0.8.3",
|
|
29
|
+
"@tooldeck/protocol": "1.3.0"
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@types/node": "^25.9.1"
|
|
33
|
+
},
|
|
34
|
+
"scripts": {
|
|
35
|
+
"build": "vite build --configLoader runner && tsc -p tsconfig.build.json --emitDeclarationOnly",
|
|
36
|
+
"test": "vitest run",
|
|
37
|
+
"typecheck": "tsc --noEmit"
|
|
38
|
+
}
|
|
39
|
+
}
|