You're Invited:Meet the Socket Team at BlackHat and DEF CON in Las Vegas, Aug 4-6.RSVP
Socket
Book a DemoInstallSign in
Socket

zap-lang

Package Overview
Dependencies
Maintainers
1
Versions
6
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

zap-lang

Zap Lang parser and validator - A human-friendly, JSON-based language for describing HTTP requests, collections, environments, and variables for API testing

1.0.5
latest
Source
npmnpm
Version published
Weekly downloads
2
Maintainers
1
Weekly downloads
 
Created
Source

Zap Lang Package

A TypeScript utility library for parsing, validating, and transforming Zap Lang API collection files. It enables filesystem-first, portable, and human-readable API collections for use in VS Code, CLI, or browser-based API testing and automation tools.

Features

  • Parse and validate Zap Lang files (api-collection, api-folder, api-request, api-global, api-environment)
  • File System Discovery Mode: No items arrays required; hierarchy is inferred from directory structure
  • Variable resolution and merging across all scopes (global, environment, collection, folder, request, session)
  • Transforms Zap requests to Axios-compatible config objects (no Axios dependency - axios is dev dependency only)
  • Supports HTTP, GraphQL, WebSocket, and File operations (protocol is inferred by structure, not a type field in request)
  • Web-compatible build - works in browser environments like VS Code workbench
  • Comprehensive test coverage with real sample collections and live API execution
  • Strictly follows the Zap Lang Specification

Test Coverage

  • 56 passing tests covering all functionality
  • Live API execution tests against JSONPlaceholder API
  • End-to-end validation of all sample collection files
  • Variable resolution at all scopes (collection, folder, request)
  • Axios conversion for all HTTP methods (GET, POST, PUT, DELETE)
  • Error handling and edge cases

Installation

npm install zap-lang

Quick Start

Basic Parsing and Validation

import { parseZap, validateZapObject } from 'zap-lang';

// Parse a Zap Lang file
const zapFileContent = `{
  "zapType": "api-request",
  "zapVersion": 1,
  "meta": { "name": "Get Users" },
  "request": {
    "method": "GET",
    "url": "{{baseUrl}}/users",
    "headers": [
      { "name": "Authorization", "value": "Bearer {{token}}" }
    ]
  }
}`;

const result = parseZap(zapFileContent);
if (result.validation.valid) {
  console.log('Valid Zap request:', result.object);
} else {
  console.error('Validation errors:', result.validation.errors);
}

Variable Merging

import { mergeZapVariables } from 'zap-lang';

const variables = mergeZapVariables({
  global: { zapType: 'api-global', zapVersion: 1, variables: { timeout: 5000 } },
  environment: { zapType: 'api-environment', zapVersion: 1, variables: { baseUrl: 'https://api.dev.example.com' } },
  collection: { zapType: 'api-collection', zapVersion: 1, meta: { name: 'Users' }, variables: { version: 'v1' } },
  sessionVars: { token: 'abc123' }
});
// Result: { timeout: 5000, baseUrl: 'https://api.dev.example.com', version: 'v1', token: 'abc123' }

Converting to Axios Config

import { zapRequestToAxiosConfig } from 'zap-lang';

const zapRequest = {
  zapType: 'api-request',
  zapVersion: 1,
  meta: { name: 'Create User' },
  request: {
    method: 'POST',
    url: '{{baseUrl}}/users',
    headers: [
      { name: 'Content-Type', value: 'application/json' },
      { name: 'Authorization', value: 'Bearer {{token}}' }
    ],
    body: {
      type: 'json',
      content: '{"name": "{{userName}}", "email": "{{userEmail}}"}'
    }
  }
};

const variables = {
  baseUrl: 'https://api.example.com',
  token: 'abc123',
  userName: 'John Doe',
  userEmail: 'john@example.com'
};

const axiosConfig = zapRequestToAxiosConfig(zapRequest, variables);
// Result: Ready-to-use Axios config object
console.log(axiosConfig);
// {
//   method: 'post',
//   url: 'https://api.example.com/users',
//   headers: {
//     'Content-Type': 'application/json',
//     'Authorization': 'Bearer abc123'
//   },
//   data: {
//     name: 'John Doe',
//     email: 'john@example.com'
//   }
// }

File System Discovery

import { loadZapFiles, getAllRequests, mergeZapVariables } from 'zap-lang';

// Load all .zap files from a directory structure
const files = loadZapFiles('./my-api-collection');
// Returns a flat object with all parsed .zap files keyed by relative path

// Get all requests from the loaded files
const requests = getAllRequests(files);

// Example: Execute all requests in a collection
for (const [path, request] of Object.entries(requests)) {
  const variables = mergeZapVariables({
    collection: files['collection.zap'],
    request: request,
    sessionVars: { token: 'your-token' }
  });
  
  const axiosConfig = zapRequestToAxiosConfig(request, variables);
  // Execute with axios: await axios(axiosConfig)
}

API Reference

Parsing Functions

parseZap(content: string): ZapParseResult

Parses a JSON string into a validated Zap object.

const result = parseZap('{"zapType": "api-request", ...}');
if (result.validation.valid) {
  console.log(result.object); // Parsed Zap object
} else {
  console.log(result.validation.errors); // Validation errors
}

Returns: { object: ZapObject | null, validation: ZapValidationResult }

serializeZap(obj: ZapObject, indent?: number): string

Serializes a Zap object to a JSON string.

const json = serializeZap(zapObject, 2); // Pretty-printed with 2-space indent

isValidZapString(content: string): boolean

Quick check if a string contains valid Zap Lang JSON.

if (isValidZapString(fileContent)) {
  // Safe to parse
}

Validation Functions

validateZapObject(obj: any): ZapValidationResult

Validates any object against Zap Lang schema.

const validation = validateZapObject(someObject);
if (validation.valid) {
  // Object is valid
} else {
  console.log(validation.errors); // Array of error messages
}

Returns: { valid: boolean, errors: string[] }

isValidZapObject(obj: any): boolean

Quick boolean check for object validity.

if (isValidZapObject(obj)) {
  // Object is valid
}

Creator Functions

createApiRequest(options: Partial<ZapApiRequest>): ZapApiRequest

Creates a new API request object with defaults.

const request = createApiRequest({
  meta: { name: 'Get Users' },
  request: {
    method: 'GET',
    url: '{{baseUrl}}/users'
  }
});

createApiCollection(options: Partial<ZapApiCollection>): ZapApiCollection

Creates a new API collection object.

const collection = createApiCollection({
  meta: { name: 'My API Collection' },
  variables: { baseUrl: 'https://api.example.com' }
});

createApiFolder(options: Partial<ZapApiFolder>): ZapApiFolder

Creates a new API folder object.

const folder = createApiFolder({
  meta: { name: 'User Management' },
  variables: { endpoint: '/users' }
});

createApiEnvironment(options: Partial<ZapApiEnvironment>): ZapApiEnvironment

Creates a new environment object.

const env = createApiEnvironment({
  meta: { name: 'Development' },
  variables: { baseUrl: 'https://api.dev.example.com' }
});

createApiGlobal(options: Partial<ZapApiGlobal>): ZapApiGlobal

Creates a new global variables object.

const global = createApiGlobal({
  variables: { timeout: 5000, retries: 3 }
});

Variable Functions

mergeZapVariables(options: MergeVariablesOptions): Record<string, any>

Merges variables from all scopes with proper precedence.

const variables = mergeZapVariables({
  global: globalVarsObject,        // Lowest precedence
  environment: environmentObject,
  collection: collectionObject,
  folder: folderObject,
  request: requestObject,
  sessionVars: { token: 'abc123' } // Highest precedence
});

Precedence (lowest to highest): global → environment → collection → folder → request → session

replaceVariables(template: string, variables: Record<string, any>): string

Replaces {{variable}} placeholders in a string.

const url = replaceVariables('{{baseUrl}}/users/{{userId}}', {
  baseUrl: 'https://api.example.com',
  userId: '123'
});
// Result: 'https://api.example.com/users/123'

extractVariables(template: string): string[]

Extracts variable names from a template string.

const vars = extractVariables('{{baseUrl}}/users/{{userId}}');
// Result: ['baseUrl', 'userId']

Discovery Functions

loadZapFiles(directory: string): Record<string, ZapObject>

Loads all .zap files from a directory tree.

const files = loadZapFiles('./my-collection');
// Result: { 'folder/request.zap': requestObject, ... }

filterZapObjectsByType<T>(objects: Record<string, ZapObject>, zapType: ZapType): Record<string, T>

Filters loaded objects by type.

const requests = filterZapObjectsByType(files, 'api-request');
const collections = filterZapObjectsByType(files, 'api-collection');

findCollectionRoot(objects: Record<string, ZapObject>): ZapApiCollection | null

Finds the root collection object.

const rootCollection = findCollectionRoot(files);

getAllRequests(objects: Record<string, ZapObject>): Record<string, ZapApiRequest>

Gets all request objects from loaded files.

const requests = getAllRequests(files);

getAllFolders(objects: Record<string, ZapObject>): Record<string, ZapApiFolder>

Gets all folder objects from loaded files.

const folders = getAllFolders(files);

getEnvironments(objects: Record<string, ZapObject>): Record<string, ZapApiEnvironment>

Gets all environment objects.

const environments = getEnvironments(files);

getGlobalVariables(objects: Record<string, ZapObject>): ZapApiGlobal | null

Gets the global variables object.

const global = getGlobalVariables(files);

findAllRequests(obj: ZapObject): ZapApiRequest[]

Recursively finds all requests within a collection or folder.

const requests = findAllRequests(collectionObject);

Axios Adapter

zapRequestToAxiosConfig(zapRequest: ZapApiRequest, variables: Record<string, any>): AxiosRequestConfig

Converts a Zap request to an Axios-compatible configuration object.

const axiosConfig = zapRequestToAxiosConfig(zapRequest, variables);
// Use with axios: axios(axiosConfig)

Features:

  • Handles all HTTP methods (GET, POST, PUT, DELETE, PATCH, etc.)
  • Processes all body types (json, raw, form, urlencoded, binary, graphql)
  • Converts headers array to object format
  • Applies variable substitution
  • Handles authentication (Bearer, Basic, API Key)
  • Sets appropriate content-type headers

Utility Exports

ZAP_LANG_VERSION: string

The current version of this zap-lang package.

ZAP_SPEC_VERSION: number

The Zap Lang specification version supported (currently 1).

Advanced Examples

Complete End-to-End Workflow

import { 
  loadZapFiles, 
  getAllRequests, 
  mergeZapVariables, 
  zapRequestToAxiosConfig,
  getEnvironments,
  getGlobalVariables 
} from 'zap-lang';
import axios from 'axios';

// 1. Load collection from filesystem
const files = loadZapFiles('./my-api-collection');

// 2. Get environment and global variables
const environments = getEnvironments(files);
const global = getGlobalVariables(files);
const environment = environments['development.zap']; // or user selection

// 3. Get all requests
const requests = getAllRequests(files);

// 4. Execute a specific request
async function executeRequest(requestPath: string, sessionVars: Record<string, any> = {}) {
  const request = requests[requestPath];
  if (!request) throw new Error(`Request not found: ${requestPath}`);

  // Merge variables from all scopes
  const variables = mergeZapVariables({
    global,
    environment,
    collection: files['collection.zap'],
    request,
    sessionVars
  });

  // Convert to axios config
  const axiosConfig = zapRequestToAxiosConfig(request, variables);

  // Execute the request
  try {
    const response = await axios(axiosConfig);
    console.log(`✅ ${request.meta.name}:`, response.status, response.data);
    return response;
  } catch (error) {
    console.error(`❌ ${request.meta.name}:`, error.message);
    throw error;
  }
}

// Execute requests
await executeRequest('users/create-user.zap', { 
  userName: 'John Doe',
  userEmail: 'john@example.com' 
});

Creating Collections Programmatically

import { 
  createApiCollection, 
  createApiFolder, 
  createApiRequest,
  serializeZap 
} from 'zap-lang';

// Create a new collection
const collection = createApiCollection({
  meta: { 
    name: 'Users API',
    description: 'CRUD operations for user management'
  },
  variables: {
    baseUrl: 'https://api.example.com',
    version: 'v1'
  }
});

// Create a folder
const usersFolder = createApiFolder({
  meta: { name: 'User Operations' },
  variables: { endpoint: '/users' }
});

// Create requests
const createUserRequest = createApiRequest({
  meta: { name: 'Create User' },
  request: {
    method: 'POST',
    url: '{{baseUrl}}/{{version}}{{endpoint}}',
    headers: [
      { name: 'Content-Type', value: 'application/json' },
      { name: 'Authorization', value: 'Bearer {{token}}' }
    ],
    body: {
      type: 'json',
      content: JSON.stringify({
        name: '{{userName}}',
        email: '{{userEmail}}'
      })
    }
  }
});

// Serialize to JSON
console.log(serializeZap(collection, 2));
console.log(serializeZap(createUserRequest, 2));

Dynamic Variable Resolution

import { mergeZapVariables, replaceVariables, extractVariables } from 'zap-lang';

// Complex variable merging with session state
const variables = mergeZapVariables({
  global: { timeout: 5000, retries: 3 },
  environment: { baseUrl: 'https://api.dev.example.com' },
  collection: { version: 'v1' },
  folder: { endpoint: '/users' },
  request: { userId: '{{createdUserId}}' }, // Dynamic from previous request
  sessionVars: { 
    token: 'session-token',
    createdUserId: '12345' // From previous request response
  }
});

// Template processing
const urlTemplate = '{{baseUrl}}/{{version}}{{endpoint}}/{{userId}}';
const resolvedUrl = replaceVariables(urlTemplate, variables);
console.log(resolvedUrl); // 'https://api.dev.example.com/v1/users/12345'

// Find missing variables
const requiredVars = extractVariables('{{baseUrl}}/{{version}}/{{missingVar}}');
const missingVars = requiredVars.filter(v => !(v in variables));
if (missingVars.length > 0) {
  console.warn('Missing variables:', missingVars);
}

GraphQL Request Example

const graphqlRequest = createApiRequest({
  meta: { name: 'Get User Profile' },
  request: {
    url: '{{graphqlEndpoint}}',
    headers: [
      { name: 'Content-Type', value: 'application/json' },
      { name: 'Authorization', value: 'Bearer {{token}}' }
    ],
    body: {
      type: 'graphql',
      content: `
        query GetUser($userId: ID!) {
          user(id: $userId) {
            id
            name
            email
            profile {
              avatar
              bio
            }
          }
        }
      `
    }
  },
  variables: {
    userId: '{{currentUserId}}'
  }
});

// Convert to axios config
const axiosConfig = zapRequestToAxiosConfig(graphqlRequest, {
  graphqlEndpoint: 'https://api.example.com/graphql',
  token: 'your-token',
  currentUserId: '123'
});

// The body will be properly formatted as:
// { query: "...", variables: { userId: "123" } }

Request Types

The package automatically detects request types based on structure:

  • HTTP Request: Has method and url fields
  • GraphQL Request: Has url and body.type: 'graphql' fields
  • WebSocket Request: Has url and wsMessage fields
  • File Request: Has fileOp field

Body Types

Supported body types in requests:

  • { type: 'json', content: '...' } - JSON content
  • { type: 'raw', content: '...' } - Raw text content
  • { type: 'form', form: [{ name: '...', value: '...' }] } - Form data
  • { type: 'urlencoded', urlencoded: [{ name: '...', value: '...' }] } - URL-encoded form
  • { type: 'binary', file: '...' } - Binary file
  • { type: 'none' } - No body
  • { type: 'graphql', content: '...' } - GraphQL query

Development

# Install dependencies
npm install

# Run tests
npm test

# Build for production
npm run build

# Build for Node.js environment
npm run build:node

# Development mode with watch
npm run dev

Browser Compatibility

This package is built for browser environments and works in:

  • VS Code workbench/webview environment
  • Modern browsers (ES2020+)
  • Node.js 16+ (with node build)

What this package does NOT do

  • Does NOT perform HTTP requests (no fetch/axios runtime dependency)
  • Does NOT manage request execution or test running
  • Does NOT provide CLI tools (focused on library functionality)
  • Does NOT require Node.js specific APIs (web-compatible)

Testing

The package includes comprehensive tests covering:

  • Parsing and validation of all Zap Lang object types
  • Variable merging and precedence
  • Axios adapter functionality
  • File system discovery
  • Real-world sample collections

License

MIT

Keywords

api

FAQs

Package last updated on 10 Jul 2025

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

About

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.

  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc

U.S. Patent No. 12,346,443 & 12,314,394. Other pending.