diff --git a/.docs/figure.png b/.docs/figure.png index 15c198e..643eb7f 100644 Binary files a/.docs/figure.png and b/.docs/figure.png differ diff --git a/README.md b/README.md index a15e576..65565b7 100644 --- a/README.md +++ b/README.md @@ -38,12 +38,10 @@ npm i image-shield import ImageShield from "image-shield"; ``` -### 🔀 Shuffle Mode - -**Fragment** +**Shuffle** ```ts -await ImageShield.encrypt({ +await ImageShield.shuffle({ // config: { /** FragmentationConfig */ }, imagePaths: [ "./input_1.png", @@ -81,7 +79,7 @@ output **Restore** ```ts -await ImageShield.decrypt({ +await ImageShield.restore({ manifestPath: "./output/fragmented/manifest.json", imagePaths: [ "./output/fragmented/img_1_fragmented.png", @@ -191,5 +189,5 @@ manifest.json: ## Clients -- [Raycast Extension](https://github.com/tuki0918/raycast-image-shield) +- [Raycast Extension (legacy)](https://github.com/tuki0918/raycast-image-shield) diff --git a/packages/cli/README.md b/packages/cli/README.md index 5d3660d..b7485a2 100644 --- a/packages/cli/README.md +++ b/packages/cli/README.md @@ -10,7 +10,7 @@ npm install @image-shield/cli ## Usage -The CLI provides two main commands: `encrypt` and `decrypt`. +The CLI provides two main commands: `shuffle` and `restore`. ### Global Help @@ -28,17 +28,17 @@ Options: -h, --help display help for command Commands: - encrypt [options] Fragment images - decrypt [options] Restore fragmented images + shuffle [options] Fragment images + restore [options] Restore fragmented images help [command] display help for command ``` -### Encrypt Command +### Shuffle Command Fragment images into multiple pieces. ```bash -image-shield encrypt -o [options] +image-shield shuffle -o [options] ``` #### Options @@ -55,17 +55,17 @@ image-shield encrypt -o [options] **Basic fragmentation:** ```bash -image-shield encrypt image1.jpg image2.png -o ./fragments +image-shield shuffle image1.jpg image2.png -o ./fragments ``` **Custom configuration:** ```bash -image-shield encrypt *.jpg -o ./output -b 20 -p "my_fragment" --restore-filename +image-shield shuffle *.jpg -o ./output -b 20 -p "my_fragment" --restore-filename ``` **With seed for reproducible results:** ```bash -image-shield encrypt image.png -o ./output -s 12345 +image-shield shuffle image.png -o ./output -s 12345 ``` #### Output Structure @@ -79,12 +79,12 @@ output/ └── ... ``` -### Decrypt Command +### Restore Command Restore fragmented images using the manifest file. ```bash -image-shield decrypt -m -o [options] +image-shield restore -m -o [options] ``` #### Options @@ -98,12 +98,12 @@ image-shield decrypt -m -o [op **Basic restoration:** ```bash -image-shield decrypt ./fragments/*.png -m ./fragments/manifest.json -o ./restored +image-shield restore ./fragments/*.png -m ./fragments/manifest.json -o ./restored ``` **Specific fragments:** ```bash -image-shield decrypt fragment_0000.png fragment_0001.png fragment_0002.png -m manifest.json -o ./output +image-shield restore fragment_0000.png fragment_0001.png fragment_0002.png -m manifest.json -o ./output ``` ## Error Handling @@ -127,7 +127,7 @@ The CLI provides clear error messages for common issues: 2. **Fragment images:** ```bash - image-shield encrypt images/photo1.jpg images/photo2.png -o ./backup --restore-filename + image-shield shuffle images/photo1.jpg images/photo2.png -o ./backup --restore-filename ``` ``` 🔀 Starting image fragmentation... @@ -142,7 +142,7 @@ The CLI provides clear error messages for common issues: 4. **Restore images:** ```bash - image-shield decrypt backup/*.png -m backup/manifest.json -o ./restored + image-shield restore backup/*.png -m backup/manifest.json -o ./restored ``` ``` 🔀 Starting image restoration... @@ -161,7 +161,7 @@ For custom fragmentation: ```bash # Fragment with custom settings -image-shield encrypt sensitive/*.jpg \ +image-shield shuffle sensitive/*.jpg \ -o ./vault \ -b 5 \ -p "secure_chunk" \ @@ -184,7 +184,7 @@ BACKUP_DIR="./backup" # Create backup echo "Creating backup..." -image-shield encrypt "$IMAGES_DIR"/*.{jpg,png} \ +image-shield shuffle "$IMAGES_DIR"/*.{jpg,png} \ -o "$BACKUP_DIR" \ --restore-filename @@ -208,7 +208,7 @@ RESTORE_DIR="./recovered_photos" # Restore from backup echo "Restoring from backup..." -image-shield decrypt "$BACKUP_DIR"/fragment_*.png \ +image-shield restore "$BACKUP_DIR"/fragment_*.png \ -m "$BACKUP_DIR/manifest.json" \ -o "$RESTORE_DIR" @@ -244,7 +244,7 @@ npm test ```bash cd packages/cli -npm run dev -- encrypt --help +npm run dev -- shuffle --help ``` ## Related Packages diff --git a/packages/cli/src/cli.ts b/packages/cli/src/cli.ts index 85a6ce7..1fa53b5 100644 --- a/packages/cli/src/cli.ts +++ b/packages/cli/src/cli.ts @@ -1,8 +1,8 @@ #!/usr/bin/env node import { Command } from "commander"; -import { registerDecryptCommand } from "./commands/decrypt"; -import { registerEncryptCommand } from "./commands/encrypt"; +import { registerRestoreCommand } from "./commands/restore"; +import { registerShuffleCommand } from "./commands/shuffle"; const program = new Command(); @@ -12,8 +12,8 @@ program .version("0.8.1"); // Register commands -registerEncryptCommand(program); -registerDecryptCommand(program); +registerShuffleCommand(program); +registerRestoreCommand(program); // Error handling program.on("command:*", () => { diff --git a/packages/cli/src/commands/decrypt.ts b/packages/cli/src/commands/restore.ts similarity index 76% rename from packages/cli/src/commands/decrypt.ts rename to packages/cli/src/commands/restore.ts index c8345b4..5f572d5 100644 --- a/packages/cli/src/commands/decrypt.ts +++ b/packages/cli/src/commands/restore.ts @@ -1,6 +1,6 @@ import ImageShield from "@image-shield/node"; import type { Command } from "commander"; -import type { DecryptOptions } from "../types"; +import type { RestoreOptions } from "../types"; import { validateImagePaths, validateManifestPath, @@ -8,27 +8,27 @@ import { } from "../validators"; /** - * Configures and registers the decrypt command + * Configures and registers the restore command * @param program Commander program instance */ -export function registerDecryptCommand(program: Command): void { +export function registerRestoreCommand(program: Command): void { program - .command("decrypt") + .command("restore") .description("Restore fragmented images") .argument("", "Fragment file paths") .requiredOption("-m, --manifest ", "Manifest file path") .requiredOption("-o, --output ", "Output directory") - .action(handleDecryptCommand); + .action(handleRestoreCommand); } /** - * Handles the decrypt command execution + * Handles the restore command execution * @param fragments Array of fragment file paths * @param options Command options */ -async function handleDecryptCommand( +async function handleRestoreCommand( fragments: string[], - options: DecryptOptions, + options: RestoreOptions, ): Promise { try { console.log("🔀 Starting image restoration..."); @@ -37,7 +37,7 @@ async function handleDecryptCommand( const manifestPath = validateManifestPath(options.manifest); const outputDir = validateOutputDirectory(options.output); - await ImageShield.decrypt({ + await ImageShield.restore({ imagePaths, manifestPath, outputDir, diff --git a/packages/cli/src/commands/encrypt.ts b/packages/cli/src/commands/shuffle.ts similarity index 85% rename from packages/cli/src/commands/encrypt.ts rename to packages/cli/src/commands/shuffle.ts index c528241..05eff7c 100644 --- a/packages/cli/src/commands/encrypt.ts +++ b/packages/cli/src/commands/shuffle.ts @@ -1,16 +1,16 @@ import type { FragmentationConfig } from "@image-shield/core"; import ImageShield from "@image-shield/node"; import type { Command } from "commander"; -import type { EncryptOptions } from "../types"; +import type { ShuffleOptions } from "../types"; import { validateImagePaths, validateOutputDirectory } from "../validators"; /** - * Configures and registers the encrypt command + * Configures and registers the shuffle command * @param program Commander program instance */ -export function registerEncryptCommand(program: Command): void { +export function registerShuffleCommand(program: Command): void { program - .command("encrypt") + .command("shuffle") .description("Fragment images") .argument("", "Input image file paths") .requiredOption("-o, --output ", "Output directory") @@ -30,17 +30,17 @@ export function registerEncryptCommand(program: Command): void { return num; }) .option("--restore-filename", "Restore original file names") - .action(handleEncryptCommand); + .action(handleShuffleCommand); } /** - * Handles the encrypt command execution + * Handles the shuffle command execution * @param images Array of image file paths * @param options Command options */ -async function handleEncryptCommand( +async function handleShuffleCommand( images: string[], - options: EncryptOptions, + options: ShuffleOptions, ): Promise { try { console.log("🔀 Starting image fragmentation..."); @@ -54,7 +54,7 @@ async function handleEncryptCommand( if (options.seed !== undefined) config.seed = options.seed; if (options.restoreFilename) config.restoreFileName = true; - await ImageShield.encrypt({ + await ImageShield.shuffle({ imagePaths, outputDir, config: Object.keys(config).length > 0 ? config : undefined, diff --git a/packages/cli/src/index.ts b/packages/cli/src/index.ts index d4283a6..89ef57d 100644 --- a/packages/cli/src/index.ts +++ b/packages/cli/src/index.ts @@ -1,4 +1,4 @@ // Export CLI functionality for programmatic usage if needed export { default as ImageShield } from "@image-shield/node"; export type { FragmentationConfig } from "@image-shield/core"; -export type { EncryptOptions, DecryptOptions } from "./types"; +export type { RestoreOptions, ShuffleOptions } from "./types"; diff --git a/packages/cli/src/types.ts b/packages/cli/src/types.ts index d0e8fe4..132fb1c 100644 --- a/packages/cli/src/types.ts +++ b/packages/cli/src/types.ts @@ -1,4 +1,4 @@ -export interface EncryptOptions { +export interface ShuffleOptions { output: string; blockSize?: number; prefix?: string; @@ -6,7 +6,7 @@ export interface EncryptOptions { restoreFilename?: boolean; } -export interface DecryptOptions { +export interface RestoreOptions { manifest: string; output: string; } diff --git a/packages/core/src/types.ts b/packages/core/src/types.ts index 00e859c..27424df 100644 --- a/packages/core/src/types.ts +++ b/packages/core/src/types.ts @@ -1,4 +1,4 @@ -export interface EncryptOptions { +export interface ShuffleOptions { /** Image paths (e.g., ["image1.png", "image2.png"]) */ imagePaths: string[]; /** Fragmentation config */ @@ -7,7 +7,7 @@ export interface EncryptOptions { outputDir: string; } -export interface DecryptOptions { +export interface RestoreOptions { /** Image paths (e.g., ["fragment1.png", "fragment2.png"]) */ imagePaths: string[]; /** Manifest path (e.g., "./output/fragments/manifest.json") */ diff --git a/packages/node/src/index.test.ts b/packages/node/src/index.test.ts index 03db360..febe4bc 100644 --- a/packages/node/src/index.test.ts +++ b/packages/node/src/index.test.ts @@ -45,8 +45,8 @@ describe("ImageShield (integration)", () => { await image.write(filePath, JimpMime.png); imagePaths.push(filePath); } - // Fragment images using ImageShield.encrypt - await ImageShield.encrypt({ + // Fragment images using ImageShield.shuffle + await ImageShield.shuffle({ imagePaths, config: { blockSize, prefix }, outputDir: tmpDir, @@ -65,8 +65,8 @@ describe("ImageShield (integration)", () => { path.join(tmpDir, generateFragmentFileName(manifestDataForFragment, i)), ); } - // Restore images using ImageShield.decrypt - await ImageShield.decrypt({ + // Restore images using ImageShield.restore + await ImageShield.restore({ imagePaths: fragmentPaths, manifestPath, outputDir: tmpDir, @@ -168,8 +168,8 @@ describe("ImageShield (restoreFileName integration)", () => { await image.write(filePath, JimpMime.png); imagePaths.push(filePath); } - // Fragment images using ImageShield.encrypt (with restoreFileName) - await ImageShield.encrypt({ + // Fragment images using ImageShield.shuffle (with restoreFileName) + await ImageShield.shuffle({ imagePaths, config: { blockSize, prefix, restoreFileName: true }, outputDir: tmpDir, @@ -188,8 +188,8 @@ describe("ImageShield (restoreFileName integration)", () => { path.join(tmpDir, generateFragmentFileName(manifest, i)), ); } - // Restore images using ImageShield.decrypt - await ImageShield.decrypt({ + // Restore images using ImageShield.restore + await ImageShield.restore({ imagePaths: fragmentPaths, manifestPath, outputDir: tmpDir, diff --git a/packages/node/src/index.ts b/packages/node/src/index.ts index 7a10d81..19d2aad 100644 --- a/packages/node/src/index.ts +++ b/packages/node/src/index.ts @@ -1,9 +1,9 @@ import { - type DecryptOptions, - type EncryptOptions, type FragmentationConfig, MANIFEST_FILE_NAME, type ManifestData, + type RestoreOptions, + type ShuffleOptions, generateFragmentFileName, generateRestoredFileName, generateRestoredOriginalFileName, @@ -20,8 +20,8 @@ export { }; export default class ImageShield { - static async encrypt(options: EncryptOptions): Promise { - const { imagePaths, config, outputDir } = validateEncryptOptions(options); + static async shuffle(options: ShuffleOptions): Promise { + const { imagePaths, config, outputDir } = validateShuffleOptions(options); const fragmenter = new ImageFragmenter(config ?? {}); const { manifest, fragmentedImages } = @@ -42,9 +42,9 @@ export default class ImageShield { ); } - static async decrypt(options: DecryptOptions): Promise { + static async restore(options: RestoreOptions): Promise { const { imagePaths, manifestPath, outputDir } = - validateDecryptOptions(options); + validateRestoreOptions(options); const manifest = await readJsonFile(manifestPath); @@ -65,7 +65,7 @@ export default class ImageShield { } } -function validateCommonOptions( +function validateCommonOptions( options: T, context: string, ) { @@ -78,13 +78,13 @@ function validateCommonOptions( return options; } -function validateEncryptOptions(options: EncryptOptions) { - return validateCommonOptions(options, "encrypt"); +function validateShuffleOptions(options: ShuffleOptions) { + return validateCommonOptions(options, "shuffle"); } -function validateDecryptOptions(options: DecryptOptions) { +function validateRestoreOptions(options: RestoreOptions) { const { manifestPath } = options; if (!manifestPath || typeof manifestPath !== "string") - throw new Error("[decrypt] manifestPath is required and must be a string."); - return validateCommonOptions(options, "decrypt"); + throw new Error("[restore] manifestPath is required and must be a string."); + return validateCommonOptions(options, "restore"); }