Skip to content

Create Next.js adapter package (@universal-data-layer/adapter-nextjs) #54

Description

@dawidurbanski

Create Next.js adapter package

Summary

Create @universal-data-layer/adapter-nextjs, the first adapter package that exposes a udl-next CLI as a drop-in replacement for next commands, running both UDL and Next.js together.

Context

Component: New package packages/adapter-nextjs/
Estimated Time: 2-3 days
Priority: Medium

Problem Statement

Currently, developers must run UDL and Next.js in separate terminals or use shell concurrency:

"scripts": {
  "dev": "udl & next dev",  // Manual concurrency
  "udl": "universal-data-layer"
}

The adapter provides a cleaner solution:

"scripts": {
  "dev": "udl-next dev",
  "build": "udl-next build",
  "start": "udl-next start"
}

Technical Specification

CLI Commands

Command Behavior
udl-next dev Run universal-data-layer + next dev concurrently
udl-next build Start UDL server, run codegen, then run next build
udl-next start Run universal-data-layer + next start concurrently

Implementation Approach

Create a new package using native child_process (no external dependencies):

  1. Parse subcommand (dev, build, start)
  2. For dev/start: spawn both processes concurrently with prefixed output
  3. For build: start UDL, wait for ready, run codegen, run next build, cleanup
  4. Prefix output lines with [udl] and [next] for clarity
  5. Handle graceful shutdown (SIGINT/SIGTERM kills both)
  6. If either process exits unexpectedly, terminate the other and exit

Files to Create

  • packages/adapter-nextjs/package.json - Package manifest with bin config
  • packages/adapter-nextjs/bin/udl-next.js - CLI entry point
  • packages/adapter-nextjs/src/cli.ts - CLI arg parsing and command routing
  • packages/adapter-nextjs/src/commands/dev.ts - Dev command (concurrent)
  • packages/adapter-nextjs/src/commands/build.ts - Build command (sequential)
  • packages/adapter-nextjs/src/commands/start.ts - Start command (concurrent)
  • packages/adapter-nextjs/src/utils/spawn.ts - Process spawning utilities
  • packages/adapter-nextjs/src/utils/prefix-output.ts - Output prefixing
  • packages/adapter-nextjs/tsconfig.json - TypeScript config
  • packages/adapter-nextjs/README.md - Usage documentation

Files to Modify

  • examples/nextjs/package.json - Update scripts to use udl-next

Key Interfaces

// src/utils/spawn.ts
import { spawn, ChildProcess } from 'node:child_process';

interface SpawnedProcess {
  process: ChildProcess;
  name: string;
  prefix: string;
}

function spawnWithPrefix(
  command: string,
  args: string[],
  prefix: string
): SpawnedProcess;

function killAll(processes: SpawnedProcess[]): void;

// src/cli.ts - CLI structure
// udl-next dev [--port <udl-port>] [--next-port <port>]
// udl-next build [--port <udl-port>]
// udl-next start [--port <udl-port>] [--next-port <port>]
// udl-next --help

Package.json Configuration

{
  "name": "@universal-data-layer/adapter-nextjs",
  "version": "1.0.0",
  "type": "module",
  "bin": {
    "udl-next": "bin/udl-next.js"
  },
  "main": "dist/index.js",
  "types": "dist/index.d.ts",
  "files": ["dist", "bin", "README.md"],
  "peerDependencies": {
    "universal-data-layer": "^1.0.0",
    "next": ">=14.0.0"
  }
}

Note: No runtime dependencies - uses native child_process.

Implementation Tasks

  • Create package directory structure and package.json
  • Implement bin/udl-next.js CLI entry point
  • Implement CLI arg parsing with subcommand support (dev, build, start)
  • Implement spawnWithPrefix utility for prefixed output
  • Implement dev command (concurrent UDL + next dev)
  • Implement start command (concurrent UDL + next start)
  • Implement build command (sequential: UDL → codegen → next build)
  • Add graceful shutdown on SIGINT/SIGTERM
  • Add "kill both on exit" behavior
  • Write unit tests
  • Update examples/nextjs/package.json scripts
  • Add README with usage documentation

Acceptance Criteria

  • udl-next dev starts both UDL and Next.js dev servers concurrently
  • udl-next build runs codegen then next build
  • udl-next start runs both UDL and Next.js production servers
  • Console output shows [udl] and [next] prefixes
  • Ctrl+C gracefully stops all processes
  • If one process crashes, the other is terminated
  • --help shows usage information
  • All tests pass
  • Type checking passes

Testing Requirements

Unit Tests

  • Test CLI arg parsing for each subcommand
  • Test output prefixing logic
  • Test graceful shutdown handling
  • Test "kill both" behavior when one exits

Integration Test

  • Spawn udl-next dev, verify both servers start, send SIGINT, verify both stop

Dependencies

  • Blocked by: None
  • Related to: Next.js example at examples/nextjs/

Notes

  • Uses native child_process - no external dependencies
  • Follow existing CLI patterns from packages/core/bin/cli.js
  • This is the first "adapter" package, establishing the pattern for future adapters (Remix, Astro, etc.)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions