1.0.12 β€’ Published 6 months ago

prisma-abstraction-alvamind v1.0.12

Weekly downloads
-
License
MIT
Repository
github
Last release
6 months ago

πŸš€ Prisma-Abstraction Lib | PrismaStack

πŸ“š Table of Contents

Test Publish npm version Downloads License: MIT

Enterprise-ready Prisma ORM enhancement framework with advanced caching, repository pattern, performance optimizations, and robust transaction management.

🎯 What is PrismaStack?

PrismaStack is a beast of a framework that beefs up your Prisma ORM, made for enterprise apps that need to be fast, stable, and easy to manage. It throws in goodies like smart caching, repository patterns, solid transactions, and tons of tests.

Keywords

prisma-orm typescript database orm caching repository-pattern enterprise nodejs typescript-orm database-framework prisma-extension orm-framework typescript-database prisma-tools database-caching prisma-wrapper prisma-enhancement database-performance prisma-utils acid-transactions

πŸ’« Why PrismaStack?

  • Enterprise-Ready: Built for big-time, heavy-traffic apps.
  • Type-Safe: 100% TypeScript, so no weird type errors.
  • Performance-Focused: Caching, query boosts, and fast batch ops.
  • Battle-Tested: Rigorous tests for real-world problems.
  • Developer-Friendly: Easy to use API with great docs.
  • Production-Proven: Works like a charm in high-traffic spots.
  • Extensible: Add your own stuff easily.
  • Secure: Built with security in mind.

πŸŽ‰ Perfect For:

  • Enterprise Apps
  • High-Traffic Systems
  • Microservices
  • REST APIs
  • GraphQL APIs
  • E-commerce
  • Real-time Apps
  • SaaS Products
  • Complex Data

🌟 Features: At a Glance

  • 😎 Type-Safe Repos: No more type guessing.
  • ⚑ Blazing Fast Cache: Smart caching for speed.
  • πŸ—‘οΈ Soft Delete: Easy peasy soft delete and restore.
  • πŸ’± Transactions: Simple, strong transaction control.
  • βš™οΈ Custom: Tweak it to your liking.
  • πŸ” Raw SQL: Full SQL power when you need it.
  • πŸ“¦ Bulk Ops: Quick create, update, delete many.
  • πŸ“„ Pagination: Smooth pagination with metadata.
  • βœ… Existence Checks: Fast checks for data.
  • 🀝 Concurrency: Handles parallel stuff like a pro.
  • πŸ”„ Runtime Config: Change settings on the fly.
  • πŸ§ͺ Tested: Enterprise-grade reliability.

πŸ”₯ Benefits:

  • πŸš€ Faster Dev: Less setup, more features.
  • πŸ’ͺ Maintainable Code: Clean and easy to read.
  • πŸ“ˆ Better Perf: Faster queries, less load.
  • πŸ›‘οΈ Fewer Bugs: Type safety and transactions fix common issues.
  • 🧠 Easier to Learn: Simple, smooth API.
  • ✨ Less Code: Do more with less code.
  • πŸ›‘οΈ More Secure: Built-in protection.
  • πŸ”„ Scalability: Designed for big growth.

πŸ“š Use Cases:

  • 🌐 REST APIs: Build solid APIs.
  • GraphQL Resolvers: Clean, efficient resolvers.
  • Microservices: Manage data smoothly.
  • SaaS Apps: Handle multi-tenancy, data isolation.
  • E-commerce: Products, orders, customers, all good.
  • Real-time Systems: High-frequency updates handled well.
  • πŸ€” Prisma?: Basically everywhere you use Prisma.

πŸ‘¨β€πŸ’» Usage Examples:

Installation

bun install prisma-abstraction-alvamind @prisma/client
# or
npm install prisma-abstraction-alvamind @prisma/client
# or
yarn add prisma-abstraction-alvamind @prisma/client

Setting Up

prisma/schema.prisma

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

generator client {
  provider = "prisma-client-js"
}

model User {
  id        String    @id @default(uuid())
  email     String    @unique
  name      String
  status    String    @default("active")
  metadata  Json?
  deletedAt DateTime?
  createdAt DateTime  @default(now())
  updatedAt DateTime  @updatedAt
}
bunx prisma generate

src/user-repository.ts

import { PrismaClient } from '@prisma/client';
import { BaseRepository, setPrismaClient } from 'prisma-abstraction-alvamind';

// Initialize Prisma client with prisma-abstraction
const prisma = setPrismaClient(new PrismaClient());

// Now you can chain prisma operations
prisma.$connect()
  .then(() => console.log('Connected'))
  .catch(console.error);

// Repository usage with proper types
export class UserRepository extends BaseRepository<typeof PrismaClient, 'user'> {}

Basic CRUD

import { UserRepository } from './user-repository';

async function main() {
  const userRepo = new UserRepository();

  // Create
  const newUser = await userRepo.create({
    data: { email: 'test@example.com', name: 'Test User' },
  });

  // Find
  const foundUser = await userRepo.findUnique({ where: { id: newUser.id } });

  // Update
  const updatedUser = await userRepo.update({
    where: { id: newUser.id },
    data: { name: 'Updated Name' },
  });

  // Delete
  await userRepo.delete({ where: { id: newUser.id } });
}

main();

Caching Example

import { PrismaClient } from '@prisma/client';
import { CachedRepository, setPrismaClient, Cache, setConfig } from 'prisma-abstraction-alvamind';
import Redis from 'ioredis';

// Redis cache implementation
class RedisCache implements Cache {
  constructor(private redis: Redis) {}

  async get<T>(key: string): Promise<T | null> {
    const value = await this.redis.get(key);
    return value ? JSON.parse(value) : null;
  }

  async set<T>(key: string, value: T, ttl?: number): Promise<void> {
    const serialized = JSON.stringify(value);
    if (ttl) {
      await this.redis.setex(key, ttl, serialized);
    } else {
      await this.redis.set(key, serialized);
    }
  }

  async delete(key: string): Promise<void> {
    await this.redis.del(key);
  }

  async clear(): Promise<void> {
    await this.redis.flushdb();
  }

  async keys(): Promise<string[]> {
    return this.redis.keys('*');
  }
}

// Initialize
const prisma = new PrismaClient();
setPrismaClient(prisma);
setConfig({
  cacheConfig: {
    defaultCaching: true,
    defaultTTL: 60
  }
});

class CachedUserRepository extends CachedRepository<typeof PrismaClient, 'user'> {
  constructor(cache: Cache) {
    super(cache);
  }
}

async function main() {
  const cache = new RedisCache(new Redis());
  const userRepo = new CachedUserRepository(cache);

  const newUser = await userRepo.create({
    data: { email: 'cached@example.com', name: 'Cached User' },
  });

  // Cached
  const user1 = await userRepo.cache({ cache: true }).findUnique({ where: { id: newUser.id } });
  // From cache
  const user2 = await userRepo.cache({ cache: true }).findUnique({ where: { id: newUser.id } });
}

main();

Soft Delete Example

import { UserRepository } from './user-repository';
import { setConfig } from 'prisma-abstraction-alvamind';

async function main() {
  setConfig({ softDelete: true });
  const userRepo = new UserRepository();

  const newUser = await userRepo.create({
    data: { email: 'softdelete@example.com', name: 'Soft Delete User' },
  });

  // Soft delete
  await userRepo.delete({ where: { id: newUser.id } });

  // Won't find
  const deletedUser = await userRepo.findUnique({ where: { id: newUser.id } });

  // Restore
  const restoredUser = await userRepo.restoreById(newUser.id);
}

main();

🎯 Advanced Examples:

Custom Repository Methods

class UserRepository extends BaseRepository<typeof PrismaClient, 'user'> {
  // Find active users
  async findActiveUsers() {
    return this.findMany({ where: { status: 'active', deletedAt: null } });
  }

  // Update with history
  async updateUserWithHistory(id: string, data: any) {
    return this.$transaction(async (trx) => {
      const currentUser = await this.trx(trx).findUnique({ where: { id } });
      const updatedUser = await this.trx(trx).update({ where: { id }, data });
      // Log to history model (not shown)
      return updatedUser;
    });
  }
}

Advanced Caching

class CachedUserRepository extends CachedRepository<typeof PrismaClient, 'user'> {
  // Custom cache settings
  async findUsersByStatus(status: string) {
      return this.cache({ cache: true, ttl: 300 }).findMany({ where: { status } });
  }

  // Conditional caching
  async findUserWithPosts(userId: string, options: { cache?: boolean } = {}) {
    return this.cache({ cache: options.cache, ttl: options.cache ? 60 : undefined })
               .findUnique({ where: { id: userId }, include: { posts: true } });
  }
}

Complex Transactions

class UserService {
  constructor(
    private userRepo: UserRepository,
    private postRepo: PostRepository,
    private emailService: EmailService // Example service
  ) {}

  async createUserWithPosts(userData: any, posts: any[]) {
    return this.userRepo.$transaction(async (trx) => {
      const user = await this.userRepo.trx(trx).create({ data: userData });
      const createdPosts = await Promise.all(
        posts.map(post => this.postRepo.trx(trx).create({ data: { ...post, authorId: user.id } }))
      );
      // Send welcome email (outside transaction)
      await this.emailService.sendWelcomeEmail(user.email);
      return { user, posts: createdPosts };
    });
  }
}

Soft Delete with Custom Logic

class SoftDeleteUserRepository extends BaseRepository<typeof PrismaClient, 'user'> {
  // Override delete
  async delete(args: any) {
    return this.update({
      ...args,
      data: {
        ...args.data,
        deletedAt: new Date(),
        status: 'inactive',
        metadata: {
          ...(args.data?.metadata || {}),
          deletedBy: 'system',
          deletionReason: args.data?.reason
        }
      }
    });
  }

  // Custom restore
  async restore(id: string, options: { reactivate?: boolean } = {}) {
    return this.update({
      where: { id },
      data: { deletedAt: null, ...(options.reactivate ? { status: 'active' } : {}) }
    });
  }
}

🎯 Advanced Features Deep Dive

πŸ“¦ Repository Pattern Enhancements

Model Name Auto-Detection

// Detects model name from class name
class UserRepository extends BaseRepository<typeof PrismaClient, 'user'> {}
class CachedUserRepository extends CachedRepository<typeof PrismaClient, 'user'> {}

Dynamic Transaction Client

// Switches between transaction and regular client
await userRepo.$transaction(async (trx) => {
  const user = await userRepo.trx(trx).findUnique({/*...*/});
  // Cleans up transaction reference
});

πŸ”„ Advanced Query Operations

Existence Checks with Select

// Existence checks with field selection
const exists = await userRepo.isExist(
  { email: 'test@example.com' },
  { id: true, email: true }
);

Advanced Pagination

const result = await userRepo.findManyWithPagination({
  page: 1,
  pageSize: 10,
  where: { status: 'active' },
  orderBy: { createdAt: 'desc' },
  select: { id: true, email: true },
  include: { posts: true }
});

console.log(result.meta);
// {
//   page: 1, pageSize: 10, total: 100, totalPages: 10,
//   hasNextPage: true, hasPreviousPage: false
// }

🎭 Advanced Caching Features

Pattern-Based Cache Flushing

// Flush operation cache
await repo.flushOperation('findMany');

// Flush exact cache entry
await repo.flushExact('findUnique', { where: { id: 'xyz' } });

// Flush all cache
await repo.flushAll();

Cache Key Management

// Custom cache key sanitization
setConfig({
  cacheConfig: {
    cacheKeySanitizer: (key) => `myapp:${Buffer.from(key).toString('base64url')}`
  }
});

Granular Cache Control

// Per-operation cache control
const users = await userRepo.cache({ cache: true, ttl: 300 }).findMany(
  { where: { status: 'active' } }
);

// Global cache configuration
setConfig({ cacheConfig: { defaultCaching: true, defaultTTL: 3600 } });

⚑ Performance Optimizations

Transaction Timeout Management

// Custom timeout for transactions
const result = await userRepo.$transaction(
  async (trx) => { /* Complex operations... */ },
  { timeout: 10000 }
);

Raw Query Support with Types

// Typed raw queries
const result = await userRepo.$queryRaw<User[]>`SELECT * FROM "User" WHERE "status" = 'active'`;

// Raw updates with parameters
const affected = await userRepo.$executeRaw`UPDATE "User" SET "status" = 'inactive' WHERE "id" = ${userId}`;

πŸ›‘οΈ Error Handling & Logging

Comprehensive Error Types

catch (error) {
  if (error instanceof RepositoryError) {
    // Handle repository error
  } else if (error instanceof CacheError) {
    // Handle cache error
  }
}

Configurable Logging

setConfig({
  logger: {
    info: (msg) => console.log(`[INFO] ${msg}`),
    error: (msg, error) => {
      Sentry.captureException(error);
      console.error(`[ERROR] ${msg}`);
    },
    warn: (msg) => console.warn(`[WARN] ${msg}`),
    debug: (msg) => debug(`[DEBUG] ${msg}`)
  }
});

πŸ”’ Soft Delete Enhancements

Restore Operations with Data

// Restore with data update
await userRepo.restoreById(
  userId,
  { status: 'active', metadata: { restoredBy: 'admin' } }
);

Bulk Soft Delete

// Soft delete multiple records
await userRepo.deleteMany({
  where: { status: 'inactive' },
  data: { metadata: { deletedBy: 'system' } }
});

🎨 Flexible Configuration

Runtime Configuration Changes

// Change configuration at runtime
setConfig({
  softDelete: true,
  cacheConfig: { defaultCaching: true, defaultTTL: 3600 },
  transactionOptions: { timeout: 5000 }
});

πŸ”§ Configuration Deep Dive

Complete Configuration Options

import { setConfig } from 'prisma-abstraction-alvamind';

setConfig({
  softDelete: true,
  logger: {
    info: (msg) => console.log(`[INFO] ${msg}`),
    error: (msg) => console.error(`[ERROR] ${msg}`),
    warn: (msg) => console.warn(`[WARN] ${msg}`),
    debug: (msg) => console.debug(`[DEBUG] ${msg}`)
  },
  cacheConfig: {
    defaultCaching: true,
    defaultTTL: 3600,
    cacheKeySanitizer: (key) => `my-app:${key}`
  },
  transactionOptions: {
    timeout: 5000,
    maxRetries: 3
  }
});

Custom Cache Implementation (Redis Example)

import { Cache } from 'prisma-abstraction-alvamind';
import Redis from 'ioredis';

class RedisCache implements Cache {
  constructor(private redis: Redis) {}

  async get<T>(key: string): Promise<T | null> {
    const value = await this.redis.get(key);
    return value ? JSON.parse(value) : null;
  }

  async set<T>(key: string, value: T, ttl?: number): Promise<void> {
    const serialized = JSON.stringify(value);
    if (ttl) {
      await this.redis.setex(key, ttl, serialized);
    } else {
      await this.redis.set(key, serialized);
    }
  }

  async delete(key: string): Promise<void> {
    await this.redis.del(key);
  }

  async clear(): Promise<void> {
    await this.redis.flushdb();
  }

  async keys(): Promise<string[]> {
    return this.redis.keys('*');
  }
}

// Usage
const redis = new Redis();
const cache = new RedisCache(redis);
const userRepo = new CachedUserRepository(cache);

πŸ›‘οΈ Battle-Tested Reliability

We're serious about tests. We've got a ton of 'em, from basic stuff to weird edge cases. Here's the breakdown:

🎯 Core Functionality Coverage

βœ“ Configuration & Initialization
βœ“ Basic CRUD Operations
βœ“ Soft Delete Mechanics
βœ“ Transaction Handling
βœ“ Raw Query Execution
βœ“ Bulk Operations
βœ“ Pagination Logic

⚑ Cache System Tests

βœ“ Cache Read Operations (findUnique, findMany, findFirst)
βœ“ Cache Invalidation (create, update, delete)
βœ“ Cache Flushing (all, specific, pattern-based)
βœ“ Edge Cases & Error Handling
βœ“ Custom Cache Key Sanitization

πŸ‹οΈ Performance & Reliability

βœ“ Bulk Operations (100 records < 1 second)
βœ“ Parallel Operations Handling
βœ“ Race Condition Management
βœ“ Transaction Rollbacks
βœ“ Memory Management

πŸ”¬ Edge Cases & Error Handling

βœ“ Invalid JSON Metadata
βœ“ Non-existent Records
βœ“ Empty Updates
βœ“ Cache System Failures
βœ“ Transaction Timeouts

πŸ“Š Test Statistics

Total Tests: 58
Pass Rate: 100%
Test Files: 1
Expectations: 103
Total Duration: 5.38s
Average Test Speed: ~93ms

🎯 Key Test Scenarios

CategoryTestsCoverage
Basic Operations15βœ“ Create, Read, Update, Delete
Caching14βœ“ Read/Write, Invalidation
Transactions5βœ“ Commit, Rollback
Soft Delete4βœ“ Delete, Restore
Concurrency4βœ“ Race Conditions
Edge Cases8βœ“ Error Handling
Configuration4βœ“ Runtime Changes
Performance4βœ“ Bulk Operations

πŸ’ͺ Reliability Metrics

  • Concurrency: 100 parallel ops, no sweat.
  • Cache Hit Rate: 99%+ for repeated queries.
  • Transaction Safety: 100% rollback on failures.
  • Data Integrity: Zero corruption.
  • Error Recovery: 100% graceful handling.

πŸ” Test Environment

  • Database: PostgreSQL (Latest)
  • Runtime: Bun
  • Platform: Docker Container
  • Test Framework: Bun Test
  • Coverage Tool: Built-in

These tests run on every commit, making sure everything stays solid.

Wanna run the tests yourself? Easy:

bun test

πŸ›£οΈ Roadmap

Here's the plan for PrismaStack:

High Priority (Next Up):

  • x More Granular Cache Control: Control caching at the model level.
  • x Advanced Querying: More complex data retrieval options.

Medium Priority (Coming Soon):

  • Real-time Subscriptions: Real-time data updates.

    // Add real-time updates support
    interface SubscriptionOptions {
      filter?: Record<string, any>;
      debounce?: number;
      batchSize?: number;
    }
    
    public subscribe<T>(
      callback: (updates: T[]) => void,
      options?: SubscriptionOptions
    ): Unsubscribe
  • Batch Operations with Progress: Batch processing with progress tracking.

    // Add batch processing with progress tracking and chunking
    public async batchProcess<T>(
      items: T[],
      operation: (item: T) => Promise<void>,
      options: {
        chunkSize?: number;
        onProgress?: (progress: number) => void;
        parallel?: boolean;
      }
    )
  • Smart Cache Prefetching: Cache loading based on user patterns.
    // Predictive cache loading based on access patterns
    public async prefetch(
      patterns: Array<{
        operation: string;
        args: any;
        priority?: 'high' | 'medium' | 'low';
      }>,
      options?: { background?: boolean }
    )
  • Built-in Auditing: Track all data changes with metadata.

    // Track all changes with detailed metadata
    interface AuditOptions {
      user?: string;
      reason?: string;
      metadata?: Record<string, any>;
      trackFields?: string[];
    }
    
    public async withAudit<T>(
      operation: () => Promise<T>,
      auditOptions: AuditOptions
    ): Promise<T>
  • Advanced Search Features: Fuzzy search, weights, highlights, language support, and synonyms.

    // Enhanced search capabilities
    interface SearchOptions {
      fuzzy?: boolean;
      weights?: Record<string, number>;
      highlight?: boolean;
      language?: string;
      synonyms?: Record<string, string[]>;
    }
    
    public async search<T>(
      query: string,
      fields: Array<keyof T>,
      options?: SearchOptions
    ): Promise<SearchResult<T>>

Lower Priority (Future Enhancements):

  • Data Encryption Layer: Field-level encryption for sensitive data.

    // Field-level encryption support
    interface EncryptionOptions {
      algorithm?: string;
      fields: string[];
      keyRotation?: boolean;
    }
    
    public enableEncryption(options: EncryptionOptions): this
    public async reEncryptField(field: string): Promise<void>
  • Smart Data Migration: Easy data migration with validation and rollback.

    // Intelligent data migration utilities
    interface MigrationOptions {
      batchSize?: number;
      validation?: boolean;
      rollback?: boolean;
      dryRun?: boolean;
    }
    
    public async migrate<T>(
      transformer: (data: T) => Promise<T>,
      options?: MigrationOptions
    ): Promise<MigrationResult>
  • Versioning Support: Track and revert to previous states of your data.

    // Add versioning capabilities to entities
    interface VersioningOptions {
      keepVersions?: number;
      compareFields?: string[];
      metadata?: Record<string, any>;
    }
    
    public async createVersion(id: string, options?: VersioningOptions)
    public async revertToVersion(id: string, version: number)
  • Performance Analytics: Get insights on query performance and cache efficiency.

    // Built-in performance monitoring
    interface PerformanceMetrics {
      queryStats: QueryStatistics[];
      cacheEfficiency: number;
      slowQueries: SlowQueryInfo[];
      recommendations: string[];
    }
    
    public async getPerformanceMetrics(): Promise<PerformanceMetrics>
    public enableQueryProfiling(options?: ProfilingOptions): this
  • Automatic Relationship Management: Handle relationships easier.

  • More Cache Adapters: Support for more cache solutions.
  • Improved Docs: More examples and tutorials.

Additional Advanced Features:

  • Read Replicas: Distribute reads across multiple replicas.

    // Read replica configuration
    interface DatabaseConfig {
      primary: PrismaClient;
      replicas?: PrismaClient[];
    }
    
    class EnhancedRepository<T extends PrismaClientType, Model extends ModelNames<T>> extends BaseRepository<T, Model> {
      private replicas: PrismaClient[];
    
      constructor(config: DatabaseConfig) {
        super();
        this.replicas = config.replicas || [];
      }
    
      private getReadReplica(): PrismaClient {
        if (this.replicas.length === 0) {
          return this.prisma;
        }
        const replicaIndex = Math.floor(Math.random() * this.replicas.length);
        return this.replicas[replicaIndex];
      }
    }
  • Database Sharding: Partition data for better scalability.

    // Sharding configuration
    interface ShardConfig {
      strategy: 'range' | 'hash' | 'directory';
      shards: Map<string, PrismaClient>;
      shardKey: string;
    }
    
    class ShardManager {
      constructor(private config: ShardConfig) {}
    
      getShardForQuery(args: any): PrismaClient {
        // Implement sharding logic here
      }
    }
  • Circuit Breaker Pattern: Prevent cascade failures with auto recovery.

    // Circuit breaker configuration
    interface CircuitBreakerConfig {
      failureThreshold: number;
      resetTimeout: number;
    }
    
    class CircuitBreaker {
      constructor(private config: CircuitBreakerConfig) {}
    
      isAllowed(): boolean {
        // Implement circuit breaker logic here
      }
    
      recordFailure(): void {
        // Implement failure recording logic here
      }
    }
  • Rate Limiting: Control the rate of requests to the database.

    // Rate limiting configuration
    interface RateLimiterConfig {
      maxRequests: number;
      windowMs: number;
    }
    
    class RateLimiter {
      constructor(private config: RateLimiterConfig) {}
    
      isAllowed(): boolean {
        // Implement rate limiting logic here
      }
    }
  • Retry Mechanism: Auto retry failed operations with backoff strategies.

    // Retry mechanism configuration
    interface RetryConfig {
      maxRetries: number;
      backoffStrategy: 'exponential' | 'linear';
    }
    
    class RetryMechanism {
      constructor(private config: RetryConfig) {}
    
      async retry<T>(operation: () => Promise<T>): Promise<T> {
        // Implement retry logic here
      }
    }
  • Connection Pooling: Manage database connections for better performance.

    // Connection pooling configuration
    interface PoolConfig {
      min: number;
      max: number;
      timeout: number;
    }
    
    class ConnectionPool {
      constructor(private config: PoolConfig) {}
    
      async acquire(): Promise<PrismaClient> {
        // Implement connection pooling logic here
      }
    
      release(connection: PrismaClient): void {
        // Implement connection release logic here
      }
    }
  • TypeScript Code-First to Prisma Schema Generator: Generate Prisma schema from TypeScript models.

    // TypeScript code-first to Prisma schema generator
    function generatePrismaSchema(models: any[]): string {
      // Implement schema generation logic here
    }

πŸ™Œ Contribution

Wanna help? Here’s how:

  1. Fork the repo.
  2. Clone your fork: git clone https://github.com/alvamind/prisma-abstraction-alvamind.git
  3. Create a branch: git checkout -b my-feature
  4. Make changes: Code, test, repeat.
  5. Commit: git commit -m "Add my feature"
  6. Push: git push origin my-feature
  7. Open a Pull Request.

Before submitting a PR:

  • Keep the same code style.
  • Write tests.
  • Document your code.
  • Keep PRs small and focused.

πŸ™ Donation

Show some love:

  • ⭐️ Star the repo.
  • ❀️ Sponsor us on GitHub.

πŸ“š Documentation

Check out our docs for everything you need.

🀝 Community & Support

πŸ“– Citation

@software{prismastack2024,
  author = {Alvamind Development Team},
  title = {PrismaStack: Enterprise-Grade Prisma ORM Enhancement Framework},
  year = {2024},
  publisher = {GitHub},
  url = {https://github.com/alvamind/prisma-abstraction-alvamind}
}

πŸ“œ Disclaimer

This is "as is", no warranties. Use at your own risk.

Prisma logo and name are trademarks of Prisma Media, Inc. This project ain't affiliated with them. We're an independent community project by @alvamind.

πŸŽ‰ That's All, Folks!

Go build cool stuff with PrismaStack! Hit us up if you got questions. Peace! ✌️

1.0.12

6 months ago

1.0.11

6 months ago

1.0.10

6 months ago

1.0.9

6 months ago

1.0.8

6 months ago

1.0.7

6 months ago

1.0.6

6 months ago

1.0.5

6 months ago

1.0.4

6 months ago

1.0.3

6 months ago

1.0.2

6 months ago

1.0.1

6 months ago