包详细信息

@paljs/utils

paljs18.1kMIT8.2.1

自述文件

@paljs/utils

Table of Contents

Introduction

A comprehensive utility package for the PalJS ecosystem providing common helper functions, DMMF utilities, schema input generation, and Prisma integration helpers. This package serves as the foundation for other PalJS packages.

Installation

npm install @paljs/utils
# or
yarn add @paljs/utils
# or
pnpm add @paljs/utils

Dependencies

This package includes the following dependencies:

  • @paljs/types - Type definitions
  • @paljs/display - Logging utilities
  • @prisma/internals - Prisma internal utilities

Usage

Main Exports

DMMF Utilities

Functions for working with Prisma Data Model Meta Format (DMMF).

import { getDMMFBySchemaPath, getSchemaPath } from '@paljs/utils';

// Get schema path with validation
const schemaPath = await getSchemaPath('./custom/schema.prisma');

// Get DMMF from schema path
const dmmf = await getDMMFBySchemaPath('./prisma/schema.prisma');

Schema Input Generation

Functions for generating GraphQL input types from Prisma schema.

import { sdlInputs } from '@paljs/utils';
import { Prisma } from '@prisma/client';

// Generate SDL input types
const inputTypes = sdlInputs(Prisma.dmmf);
console.log(inputTypes); // Generated SDL input type definitions

Prisma Internals Re-exports

Direct access to useful Prisma internal functions.

import { getDMMF, formatSchema } from '@paljs/utils';

// Get DMMF from schema string
const dmmf = await getDMMF({
  datamodel: schemaString,
});

// Format schema string
const formattedSchema = formatSchema({
  schema: schemaString,
});

API Reference

getSchemaPath(path?: string)

Resolves and validates the Prisma schema file path.

async function getSchemaPath(path?: string): Promise<string>;

Parameters:

  • path (optional) - Custom schema file path

Returns:

  • Promise resolving to validated schema file path

Example:

import { getSchemaPath } from '@paljs/utils';

// Use default schema location
const defaultPath = await getSchemaPath();
// Returns: './prisma/schema.prisma'

// Use custom path
const customPath = await getSchemaPath('./custom/schema.prisma');
// Returns: './custom/schema.prisma'

// Error handling
try {
  const path = await getSchemaPath('./nonexistent/schema.prisma');
} catch (error) {
  console.error('Schema not found:', error.message);
}

getDMMFBySchemaPath(schemaPath?: string)

Loads and parses a Prisma schema file to return the DMMF document.

async function getDMMFBySchemaPath(schemaPath?: string): Promise<DMMF.Document>;

Parameters:

  • schemaPath (optional) - Path to the Prisma schema file

Returns:

  • Promise resolving to Prisma DMMF document

Example:

import { getDMMFBySchemaPath } from '@paljs/utils';

// Load DMMF from default schema
const dmmf = await getDMMFBySchemaPath();

// Load DMMF from custom path
const customDMMF = await getDMMFBySchemaPath('./custom/schema.prisma');

// Access DMMF data
console.log('Models:', dmmf.datamodel.models);
console.log('Enums:', dmmf.datamodel.enums);
console.log('Types:', dmmf.datamodel.types);

sdlInputs(dmmf: DMMF.Document)

Generates GraphQL SDL input type definitions from Prisma DMMF.

function sdlInputs(dmmf: DMMF.Document): string;

Parameters:

  • dmmf - Prisma DMMF document

Returns:

  • String containing SDL input type definitions

Example:

import { sdlInputs } from '@paljs/utils';
import { Prisma } from '@prisma/client';

const inputTypeDefs = sdlInputs(Prisma.dmmf);

// Generated output includes:
// - UserCreateInput
// - UserUpdateInput
// - UserWhereInput
// - UserOrderByInput
// - And many more...

Usage Examples

Basic Schema Processing

import { getSchemaPath, getDMMFBySchemaPath } from '@paljs/utils';

async function processSchema() {
  try {
    // Find and validate schema
    const schemaPath = await getSchemaPath();
    console.log(`Found schema at: ${schemaPath}`);

    // Load DMMF
    const dmmf = await getDMMFBySchemaPath(schemaPath);

    // Process models
    dmmf.datamodel.models.forEach((model) => {
      console.log(`Model: ${model.name}`);
      console.log(`Fields: ${model.fields.length}`);
    });
  } catch (error) {
    console.error('Schema processing failed:', error.message);
  }
}

await processSchema();

Generate GraphQL Types

import { getDMMFBySchemaPath, sdlInputs } from '@paljs/utils';
import { writeFileSync } from 'fs';

async function generateGraphQLTypes() {
  // Load schema
  const dmmf = await getDMMFBySchemaPath('./prisma/schema.prisma');

  // Generate input types
  const inputTypes = sdlInputs(dmmf);

  // Create complete type definitions
  const typeDefs = `
    # Generated input types
    ${inputTypes}

    # Your custom types
    type Query {
      users(where: UserWhereInput): [User!]!
      posts(where: PostWhereInput): [Post!]!
    }

    type Mutation {
      createUser(data: UserCreateInput!): User!
      updateUser(where: UserWhereUniqueInput!, data: UserUpdateInput!): User
    }
  `;

  // Save to file
  writeFileSync('./src/schema.graphql', typeDefs);
  console.log('GraphQL schema generated successfully!');
}

await generateGraphQLTypes();

Multi-Schema Processing

import { getDMMFBySchemaPath } from '@paljs/utils';

async function procesMultipleSchemas() {
  const schemaPaths = ['./prisma/user.prisma', './prisma/blog.prisma', './prisma/ecommerce.prisma'];

  const dmmfs = await Promise.all(schemaPaths.map((path) => getDMMFBySchemaPath(path)));

  // Combine models from all schemas
  const allModels = dmmfs.flatMap((dmmf) => dmmf.datamodel.models);

  console.log(`Total models across all schemas: ${allModels.length}`);

  // Process each schema separately
  dmmfs.forEach((dmmf, index) => {
    console.log(`\nSchema ${index + 1} (${schemaPaths[index]}):`);
    console.log(`Models: ${dmmf.datamodel.models.map((m) => m.name).join(', ')}`);
  });
}

await procesMultipleSchemas();

Schema Analysis

import { getDMMFBySchemaPath } from '@paljs/utils';

async function analyzeSchema() {
  const dmmf = await getDMMFBySchemaPath();

  // Count different elements
  const stats = {
    models: dmmf.datamodel.models.length,
    enums: dmmf.datamodel.enums.length,
    types: dmmf.datamodel.types.length,
  };

  console.log('Schema Statistics:', stats);

  // Find relations
  const relations = dmmf.datamodel.models.flatMap((model) => model.fields.filter((field) => field.relationName));

  console.log(`Total relations: ${relations.length}`);

  // Find models with specific field types
  const modelsWithDateTime = dmmf.datamodel.models.filter((model) =>
    model.fields.some((field) => field.type === 'DateTime'),
  );

  console.log(
    'Models with DateTime fields:',
    modelsWithDateTime.map((m) => m.name),
  );

  // Find optional fields
  const optionalFields = dmmf.datamodel.models.flatMap((model) =>
    model.fields.filter((field) => !field.isRequired && !field.isList),
  );

  console.log(`Total optional fields: ${optionalFields.length}`);
}

await analyzeSchema();

Integration with Code Generation

import { getDMMFBySchemaPath, sdlInputs } from '@paljs/utils';
import { log } from '@paljs/display';

async function generateWithProgress() {
  const spinner = log.spinner('Loading Prisma schema...').start();

  try {
    // Load schema
    const dmmf = await getDMMFBySchemaPath();
    spinner.succeed('Schema loaded successfully');

    // Generate types
    log.progress('Generating GraphQL input types...');
    const inputTypes = sdlInputs(dmmf);

    // Save generated types
    log.progress('Writing generated files...');
    // ... save logic here

    log.success('Code generation completed!');
    log.meta(`Generated types for ${dmmf.datamodel.models.length} models`);
  } catch (error) {
    spinner.fail('Generation failed');
    log.error(error.message);
    throw error;
  }
}

await generateWithProgress();

Error Handling and Validation

import { getSchemaPath, getDMMFBySchemaPath } from '@paljs/utils';
import { log } from '@paljs/display';

async function validateAndProcess(customPath?: string) {
  try {
    // Validate schema path
    const schemaPath = await getSchemaPath(customPath);

    // Load and validate DMMF
    const dmmf = await getDMMFBySchemaPath(schemaPath);

    // Validate schema content
    if (dmmf.datamodel.models.length === 0) {
      log.warning('No models found in schema');
      return;
    }

    // Check for required models
    const requiredModels = ['User', 'Post'];
    const missingModels = requiredModels.filter(
      (required) => !dmmf.datamodel.models.some((model) => model.name === required),
    );

    if (missingModels.length > 0) {
      log.warning(`Missing required models: ${missingModels.join(', ')}`);
    }

    log.success('Schema validation passed');
    return dmmf;
  } catch (error) {
    if (error.message.includes('schema.prisma')) {
      log.error('Schema file not found');
      log.meta('Make sure your schema file exists and is accessible');
    } else if (error.message.includes('Parse error')) {
      log.error('Schema syntax error');
      log.meta('Check your Prisma schema for syntax errors');
    } else {
      log.error(`Unexpected error: ${error.message}`);
    }

    throw error;
  }
}

// Usage
try {
  const dmmf = await validateAndProcess('./prisma/schema.prisma');
  if (dmmf) {
    console.log('Schema processed successfully');
  }
} catch (error) {
  console.error('Processing failed');
}

Integration with Build Tools

Webpack Plugin

```javascript const { getDMMFBySchemaPath } = require('@paljs/utils');

class PrismaUtilsPlugin { apply(compiler) { compiler.hooks.beforeCompile.tapAsync('PrismaUtils', async (params, callback) => { try { const dmmf = await getDMMFBySchemaPath(); console.log(`