Skip to main content

Base64 Encoder/Decoder

A bidirectional CTP tool demonstrating mode selection and conditional parameters.

Overview

PropertyValue
IDbase64-encoder
Categoryencoders
Execution Modeclient
MethodPOST

Parameters

NameTypeRequiredDefaultDescription
inputtextareaYes-Text or Base64 string
modeselectNoencodeOperation mode
urlSafebooleanNofalseURL-safe encoding (encode only)

Mode Options

ValueDescription
encodeConvert text → Base64
decodeConvert Base64 → text

URL-Safe Mode

When enabled (encode only):
  • + becomes -
  • / becomes _
  • Padding = is removed

Example

Encode:
{
  "input": "Hello, World!",
  "mode": "encode"
}
Output:
{
  "success": true,
  "data": {
    "output": "SGVsbG8sIFdvcmxkIQ==",
    "mode": "encode",
    "inputLength": 13,
    "outputLength": 20
  }
}
Decode:
{
  "input": "SGVsbG8sIFdvcmxkIQ==",
  "mode": "decode"
}
Output:
{
  "success": true,
  "data": {
    "output": "Hello, World!",
    "mode": "decode",
    "inputLength": 20,
    "outputLength": 13
  }
}

Implementation

import type { ToolDefinition, ToolFunction } from '@conveniencepro/ctp-core';

interface Base64Result {
  output: string;
  mode: 'encode' | 'decode';
  inputLength: number;
  outputLength: number;
}

export const base64EncoderDefinition: ToolDefinition = {
  id: 'base64-encoder',
  name: 'Base64 Encoder/Decoder',
  description: 'Encode text to Base64 or decode Base64 back to text.',
  category: 'encoders',
  tags: ['base64', 'encode', 'decode', 'text'],
  method: 'POST',
  parameters: [
    {
      name: 'input',
      type: 'textarea',
      label: 'Input',
      description: 'Text to encode or Base64 to decode',
      required: true,
    },
    {
      name: 'mode',
      type: 'select',
      label: 'Mode',
      description: 'Operation mode',
      required: false,
      defaultValue: 'encode',
      options: [
        { value: 'encode', label: 'Encode' },
        { value: 'decode', label: 'Decode' },
      ],
    },
    {
      name: 'urlSafe',
      type: 'boolean',
      label: 'URL Safe',
      description: 'Use URL-safe Base64 variant',
      required: false,
      defaultValue: false,
      // Only show when mode is 'encode'
      dependsOn: [{ field: 'mode', condition: 'equals', value: 'encode' }],
    },
  ],
  outputDescription: 'Encoded or decoded string',
  example: {
    input: { input: 'Hello', mode: 'encode' },
    output: { output: 'SGVsbG8=', mode: 'encode', inputLength: 5, outputLength: 8 },
  },
  executionMode: 'client',
};

function encodeBase64(str: string, urlSafe: boolean): string {
  // Convert string to UTF-8 bytes
  const bytes = new TextEncoder().encode(str);
  let binary = '';
  bytes.forEach(byte => {
    binary += String.fromCharCode(byte);
  });

  // Encode to Base64
  let result = btoa(binary);

  // Apply URL-safe transformation
  if (urlSafe) {
    result = result
      .replace(/\+/g, '-')
      .replace(/\//g, '_')
      .replace(/=/g, '');
  }

  return result;
}

function decodeBase64(str: string): string {
  // Handle URL-safe variant
  let input = str.replace(/-/g, '+').replace(/_/g, '/');

  // Add padding if needed
  while (input.length % 4) {
    input += '=';
  }

  // Decode from Base64
  const binary = atob(input);
  const bytes = new Uint8Array(binary.length);
  for (let i = 0; i < binary.length; i++) {
    bytes[i] = binary.charCodeAt(i);
  }

  // Convert UTF-8 bytes to string
  return new TextDecoder().decode(bytes);
}

export const base64EncoderFn: ToolFunction<Base64Result> = (params) => {
  const input = params.input as string;
  const mode = (params.mode as 'encode' | 'decode') || 'encode';
  const urlSafe = params.urlSafe === true || params.urlSafe === 'true';

  // Validation
  if (!input) {
    return {
      success: false,
      error: 'Input is required',
      errorCode: 'MISSING_REQUIRED',
    };
  }

  try {
    const output = mode === 'encode'
      ? encodeBase64(input, urlSafe)
      : decodeBase64(input);

    return {
      success: true,
      data: {
        output,
        mode,
        inputLength: input.length,
        outputLength: output.length,
      },
    };
  } catch (e) {
    return {
      success: false,
      error: mode === 'decode'
        ? `Invalid Base64: ${(e as Error).message}`
        : `Encoding failed: ${(e as Error).message}`,
      errorCode: 'INVALID_INPUT',
    };
  }
};

export default { definition: base64EncoderDefinition, fn: base64EncoderFn };

Key Patterns

Bidirectional Operations

Handle two opposite operations in one tool:
const output = mode === 'encode'
  ? encodeBase64(input, urlSafe)
  : decodeBase64(input);

Conditional Parameters

Show urlSafe only when encoding:
{
  name: 'urlSafe',
  type: 'boolean',
  dependsOn: [{ field: 'mode', condition: 'equals', value: 'encode' }],
}

UTF-8 Support

Properly handle international characters:
// Encode: Convert string to UTF-8 bytes first
const bytes = new TextEncoder().encode(str);

// Decode: Convert bytes back to string
return new TextDecoder().decode(bytes);

URL-Safe Variant

Transform standard Base64 for URL safety:
if (urlSafe) {
  result = result
    .replace(/\+/g, '-')   // + → -
    .replace(/\//g, '_')   // / → _
    .replace(/=/g, '');    // Remove padding
}

Error Handling

Error CodeCause
MISSING_REQUIREDinput not provided
INVALID_INPUTInvalid Base64 string (decode mode)