prisma-prefixed-ids 1.2.0 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs ADDED
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createPrefixedIdsExtension = createPrefixedIdsExtension;
4
+ exports.extendPrismaClient = extendPrismaClient;
5
+ const nanoid_1 = require("nanoid");
6
+ const defaultIdGenerator = (prefix) => {
7
+ const nanoid = (0, nanoid_1.customAlphabet)("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", 24);
8
+ return `${prefix}_${nanoid()}`;
9
+ };
10
+ function createPrefixedIdsExtension(config) {
11
+ const { prefixes, idGenerator = defaultIdGenerator } = config;
12
+ const prefixedId = (modelName) => {
13
+ if (modelName in prefixes) {
14
+ return idGenerator(prefixes[modelName]);
15
+ }
16
+ return null;
17
+ };
18
+ return {
19
+ name: "prefixedIds",
20
+ query: {
21
+ $allModels: {
22
+ create: ({ args, query, model }) => {
23
+ if (args.data && !args.data.id) {
24
+ const id = prefixedId(model);
25
+ if (id) {
26
+ args.data.id = id;
27
+ }
28
+ }
29
+ return query(args);
30
+ },
31
+ createMany: ({ args, query, model }) => {
32
+ if (model in prefixes && args.data && Array.isArray(args.data)) {
33
+ args.data = args.data.map((item) => {
34
+ if (!item.id) {
35
+ const id = prefixedId(model);
36
+ if (id) {
37
+ return {
38
+ ...item,
39
+ id,
40
+ };
41
+ }
42
+ }
43
+ return item;
44
+ });
45
+ }
46
+ return query(args);
47
+ },
48
+ },
49
+ },
50
+ };
51
+ }
52
+ function extendPrismaClient(prisma, config) {
53
+ return prisma.$extends(createPrefixedIdsExtension(config));
54
+ }
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { PrismaClient } from "@prisma/client";
1
+ import type { PrismaClient } from "@prisma/client";
2
2
  type ModelName = string;
3
3
  export type PrefixConfig<ModelName extends string> = {
4
4
  prefixes: Partial<Record<ModelName, string>>;
@@ -18,5 +18,9 @@ export declare function createPrefixedIdsExtension<ModelName extends string>(con
18
18
  };
19
19
  };
20
20
  };
21
- export declare function extendPrismaClient<ModelName extends string = string>(prisma: PrismaClient, config: PrefixConfig<ModelName>): PrismaClient;
21
+ export declare function extendPrismaClient<ModelName extends string = string, Client extends {
22
+ $extends: (extension: any) => Client;
23
+ } = PrismaClient & {
24
+ $extends: (extension: any) => any;
25
+ }>(prisma: Client, config: PrefixConfig<ModelName>): Client;
22
26
  export {};
package/dist/index.js CHANGED
@@ -1,13 +1,9 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createPrefixedIdsExtension = createPrefixedIdsExtension;
4
- exports.extendPrismaClient = extendPrismaClient;
5
- const nanoid_1 = require("nanoid");
1
+ import { customAlphabet } from "nanoid";
6
2
  const defaultIdGenerator = (prefix) => {
7
- const nanoid = (0, nanoid_1.customAlphabet)("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", 24);
3
+ const nanoid = customAlphabet("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", 24);
8
4
  return `${prefix}_${nanoid()}`;
9
5
  };
10
- function createPrefixedIdsExtension(config) {
6
+ export function createPrefixedIdsExtension(config) {
11
7
  const { prefixes, idGenerator = defaultIdGenerator } = config;
12
8
  const prefixedId = (modelName) => {
13
9
  if (modelName in prefixes) {
@@ -49,6 +45,6 @@ function createPrefixedIdsExtension(config) {
49
45
  },
50
46
  };
51
47
  }
52
- function extendPrismaClient(prisma, config) {
48
+ export function extendPrismaClient(prisma, config) {
53
49
  return prisma.$extends(createPrefixedIdsExtension(config));
54
50
  }
package/package.json CHANGED
@@ -1,16 +1,29 @@
1
1
  {
2
2
  "name": "prisma-prefixed-ids",
3
- "version": "1.2.0",
3
+ "version": "1.3.1",
4
4
  "description": "A Prisma extension that adds prefixed IDs to your models",
5
- "main": "dist/index.js",
6
- "types": "dist/index.d.ts",
7
5
  "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/index.js",
11
+ "require": "./dist/index.cjs",
12
+ "types": "./dist/index.d.ts"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist"
17
+ ],
8
18
  "repository": {
9
19
  "type": "git",
10
20
  "url": "https://github.com/pureartisan/prisma-prefixed-ids"
11
21
  },
12
22
  "scripts": {
13
- "build": "tsc",
23
+ "clean": "rm -rf dist",
24
+ "build": "npm run clean && npm run build:esm && npm run build:cjs",
25
+ "build:esm": "tsc -p tsconfig.json",
26
+ "build:cjs": "tsc -p tsconfig.cjs.json && mv dist/cjs/index.js dist/index.cjs && rm -rf dist/cjs",
14
27
  "prepare": "npm run build",
15
28
  "test": "jest",
16
29
  "test:watch": "jest --watch",
@@ -28,7 +41,7 @@
28
41
  "prefixed",
29
42
  "nanoid"
30
43
  ],
31
- "author": "Prageeth Silva <prageethsilva@gmail.com>",
44
+ "author": "Prageeth Silva <prageeth@codemode.com.au>",
32
45
  "license": "MIT",
33
46
  "dependencies": {
34
47
  "@prisma/client": "^5.0.0 || ^6.0.0",
package/.eslintrc.json DELETED
@@ -1,32 +0,0 @@
1
- {
2
- "env": {
3
- "node": true,
4
- "es2021": true,
5
- "jest": true
6
- },
7
- "extends": [
8
- "eslint:recommended",
9
- "plugin:@typescript-eslint/recommended",
10
- "prettier"
11
- ],
12
- "parser": "@typescript-eslint/parser",
13
- "parserOptions": {
14
- "ecmaVersion": "latest",
15
- "sourceType": "module"
16
- },
17
- "plugins": ["@typescript-eslint"],
18
- "rules": {
19
- "@typescript-eslint/explicit-function-return-type": "error",
20
- "@typescript-eslint/no-explicit-any": "off",
21
- "@typescript-eslint/no-unused-vars": [
22
- "error",
23
- { "argsIgnorePattern": "^_" }
24
- ]
25
- },
26
- "ignorePatterns": [
27
- "**/*.test.ts",
28
- "**/*.spec.ts",
29
- "dist/**/*",
30
- "node_modules/**/*"
31
- ]
32
- }
@@ -1,39 +0,0 @@
1
- name: CI
2
-
3
- on:
4
- push:
5
- branches: [ main ]
6
- pull_request:
7
- branches: [ main ]
8
-
9
- jobs:
10
- build:
11
- runs-on: ubuntu-latest
12
-
13
- strategy:
14
- matrix:
15
- node-version: [18.x, 20.x]
16
-
17
- steps:
18
- - uses: actions/checkout@v4
19
-
20
- - name: Use Node.js ${{ matrix.node-version }}
21
- uses: actions/setup-node@v4
22
- with:
23
- node-version: ${{ matrix.node-version }}
24
- cache: 'npm'
25
-
26
- - name: Install dependencies
27
- run: npm ci
28
-
29
- - name: Check formatting
30
- run: npm run format:check
31
-
32
- - name: Run linter
33
- run: npm run lint
34
-
35
- - name: Build
36
- run: npm run build
37
-
38
- - name: Run tests with coverage
39
- run: npm run test:coverage
package/.prettierrc DELETED
@@ -1 +0,0 @@
1
-
package/jest.config.cjs DELETED
@@ -1,16 +0,0 @@
1
- module.exports = {
2
- preset: "ts-jest",
3
- testEnvironment: "node",
4
- testMatch: ["**/__tests__/**/*.ts", "**/?(*.)+(spec|test).ts"],
5
- transform: {
6
- "^.+\\.ts$": [
7
- "ts-jest",
8
- {
9
- tsconfig: "tsconfig.test.json",
10
- },
11
- ],
12
- },
13
- moduleNameMapper: {
14
- "^(\\.{1,2}/.*)\\.js$": "$1",
15
- },
16
- };
@@ -1,184 +0,0 @@
1
- import { jest } from "@jest/globals";
2
-
3
- import { PrismaClient } from "@prisma/client";
4
- import {
5
- createPrefixedIdsExtension,
6
- extendPrismaClient,
7
- PrefixConfig,
8
- } from "../index";
9
-
10
- type MockUser = {
11
- id: string;
12
- name: string;
13
- };
14
-
15
- type CreateArgs = {
16
- data: Record<string, unknown>;
17
- };
18
-
19
- // Mock PrismaClient
20
- jest.mock("@prisma/client", () => {
21
- return {
22
- PrismaClient: jest.fn().mockImplementation(() => ({
23
- $extends: jest.fn(),
24
- user: {
25
- create: jest.fn(),
26
- findUnique: jest.fn(),
27
- },
28
- })),
29
- };
30
- });
31
-
32
- // Mock nanoid
33
- jest.mock("nanoid", () => ({
34
- customAlphabet: jest.fn().mockImplementation(() => () => "mock_nanoid_value"),
35
- }));
36
-
37
- describe("PrefixedIdsExtension", () => {
38
- let prisma: jest.Mocked<PrismaClient>;
39
- const mockQuery = jest.fn((args: any) => Promise.resolve(args));
40
-
41
- beforeEach(() => {
42
- jest.clearAllMocks();
43
- prisma = new PrismaClient() as jest.Mocked<PrismaClient>;
44
- });
45
-
46
- describe("createPrefixedIdsExtension", () => {
47
- it("should create an extension with the correct name", () => {
48
- const extension = createPrefixedIdsExtension({
49
- prefixes: {
50
- Test: "test",
51
- },
52
- });
53
-
54
- expect(extension.name).toBe("prefixedIds");
55
- });
56
-
57
- it("should use default idGenerator if none provided", async () => {
58
- const extension = createPrefixedIdsExtension({
59
- prefixes: {
60
- Test: "test",
61
- },
62
- });
63
-
64
- const result = await extension.query.$allModels.create({
65
- args: { data: {} },
66
- query: mockQuery,
67
- model: "Test",
68
- });
69
-
70
- expect(result).toBeDefined();
71
- expect(mockQuery).toHaveBeenCalled();
72
- });
73
-
74
- it("should use custom idGenerator if provided", async () => {
75
- const customIdGenerator = jest.fn(
76
- (prefix: string) => `${prefix}_custom_id`,
77
- );
78
- const extension = createPrefixedIdsExtension({
79
- prefixes: {
80
- Test: "test",
81
- },
82
- idGenerator: customIdGenerator,
83
- });
84
-
85
- await extension.query.$allModels.create({
86
- args: { data: {} },
87
- query: mockQuery,
88
- model: "Test",
89
- });
90
-
91
- expect(customIdGenerator).toHaveBeenCalledWith("test");
92
- expect(mockQuery).toHaveBeenCalledWith({
93
- data: { id: "test_custom_id" },
94
- });
95
- });
96
-
97
- it("should not modify args if model has no prefix", async () => {
98
- const extension = createPrefixedIdsExtension({
99
- prefixes: {
100
- Test: "test",
101
- },
102
- });
103
-
104
- const originalArgs = { data: {} };
105
- const result = await extension.query.$allModels.create({
106
- args: originalArgs,
107
- query: mockQuery,
108
- model: "UnknownModel",
109
- });
110
-
111
- expect(result).toBeDefined();
112
- expect(result.data).not.toHaveProperty("id");
113
- });
114
-
115
- it("should handle createMany operation", async () => {
116
- const extension = createPrefixedIdsExtension({
117
- prefixes: {
118
- Test: "test",
119
- },
120
- });
121
-
122
- const result = await extension.query.$allModels.createMany({
123
- args: {
124
- data: [{}, {}],
125
- },
126
- query: mockQuery,
127
- model: "Test",
128
- });
129
-
130
- expect(result).toBeDefined();
131
- expect(result.data).toHaveLength(2);
132
- expect(result.data[0]).toHaveProperty("id");
133
- expect(result.data[1]).toHaveProperty("id");
134
- });
135
-
136
- it("should generate IDs with uppercase letters", async (): Promise<void> => {
137
- const prefixConfig: PrefixConfig<"User"> = {
138
- prefixes: {
139
- User: "usr",
140
- },
141
- // Force an ID with uppercase for testing
142
- idGenerator: (prefix: string): string => {
143
- return `${prefix}_ABC123DEF`;
144
- },
145
- };
146
-
147
- const extension = createPrefixedIdsExtension(prefixConfig);
148
- prisma.$extends(extension);
149
-
150
- // Mock the create operation
151
- prisma.user.create.mockResolvedValueOnce({
152
- id: "usr_ABC123DEF",
153
- name: "Test User",
154
- });
155
-
156
- const user = await prisma.user.create({
157
- data: {
158
- name: "Test User",
159
- },
160
- });
161
-
162
- // Test that the ID matches our pattern including uppercase
163
- expect(user.id).toMatch(/^usr_[A-Z0-9]+$/);
164
- });
165
- });
166
-
167
- describe("extendPrismaClient", () => {
168
- it("should extend the Prisma client with the extension", () => {
169
- const extendedPrisma = extendPrismaClient(prisma, {
170
- prefixes: {
171
- Test: "test",
172
- },
173
- });
174
-
175
- expect(prisma.$extends).toHaveBeenCalled();
176
- });
177
-
178
- it("should not throw error if prefixes are not provided", () => {
179
- expect(() => {
180
- extendPrismaClient(prisma, {} as any);
181
- }).not.toThrow();
182
- });
183
- });
184
- });
package/src/index.ts DELETED
@@ -1,87 +0,0 @@
1
- import { PrismaClient } from "@prisma/client";
2
- import { customAlphabet } from "nanoid";
3
-
4
- // Define ModelName type based on Prisma's model names
5
- type ModelName = string;
6
-
7
- export type PrefixConfig<ModelName extends string> = {
8
- prefixes: Partial<Record<ModelName, string>>;
9
- idGenerator?: (prefix: string) => string;
10
- };
11
-
12
- const defaultIdGenerator = (prefix: string): string => {
13
- const nanoid = customAlphabet(
14
- "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",
15
- 24,
16
- );
17
- return `${prefix}_${nanoid()}`;
18
- };
19
-
20
- type QueryArgs = {
21
- args: any;
22
- query: (args: any) => Promise<any>;
23
- model: ModelName;
24
- };
25
-
26
- export function createPrefixedIdsExtension<ModelName extends string>(
27
- config: PrefixConfig<ModelName>,
28
- ): {
29
- name: string;
30
- query: {
31
- $allModels: {
32
- create: (args: QueryArgs) => Promise<any>;
33
- createMany: (args: QueryArgs) => Promise<any>;
34
- };
35
- };
36
- } {
37
- const { prefixes, idGenerator = defaultIdGenerator } = config;
38
-
39
- const prefixedId = (modelName: ModelName): string | null => {
40
- if (modelName in prefixes) {
41
- return idGenerator(prefixes[modelName] as string);
42
- }
43
- return null;
44
- };
45
-
46
- return {
47
- name: "prefixedIds",
48
- query: {
49
- $allModels: {
50
- create: ({ args, query, model }: QueryArgs): Promise<any> => {
51
- if (args.data && !args.data.id) {
52
- const id = prefixedId(model as ModelName);
53
- if (id) {
54
- args.data.id = id;
55
- }
56
- }
57
- return query(args);
58
- },
59
-
60
- createMany: ({ args, query, model }: QueryArgs): Promise<any> => {
61
- if (model in prefixes && args.data && Array.isArray(args.data)) {
62
- args.data = (args.data as Record<string, any>[]).map((item) => {
63
- if (!item.id) {
64
- const id = prefixedId(model as ModelName);
65
- if (id) {
66
- return {
67
- ...item,
68
- id,
69
- };
70
- }
71
- }
72
- return item;
73
- });
74
- }
75
- return query(args);
76
- },
77
- },
78
- },
79
- };
80
- }
81
-
82
- export function extendPrismaClient<ModelName extends string = string>(
83
- prisma: PrismaClient,
84
- config: PrefixConfig<ModelName>,
85
- ): PrismaClient {
86
- return prisma.$extends(createPrefixedIdsExtension(config));
87
- }
package/tsconfig.json DELETED
@@ -1,15 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2020",
4
- "module": "commonjs",
5
- "declaration": true,
6
- "outDir": "./dist",
7
- "strict": true,
8
- "esModuleInterop": true,
9
- "skipLibCheck": true,
10
- "forceConsistentCasingInFileNames": true,
11
- "moduleResolution": "node"
12
- },
13
- "include": ["src/**/*"],
14
- "exclude": ["node_modules", "**/*.test.ts"]
15
- }
@@ -1,11 +0,0 @@
1
- {
2
- "extends": "./tsconfig.json",
3
- "compilerOptions": {
4
- "module": "commonjs",
5
- "moduleResolution": "node",
6
- "types": ["jest", "node"],
7
- "esModuleInterop": true
8
- },
9
- "include": ["src/**/*.test.ts", "src/**/__tests__/**/*"],
10
- "exclude": ["node_modules"]
11
- }