prisma-prefixed-ids 1.1.1 → 1.3.0
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 +54 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +4 -8
- package/package.json +18 -5
- package/.eslintrc.json +0 -32
- package/.github/workflows/ci.yml +0 -39
- package/.prettierrc +0 -1
- package/jest.config.cjs +0 -16
- package/src/__tests__/index.test.ts +0 -137
- package/src/index.ts +0 -84
- package/tsconfig.json +0 -15
- package/tsconfig.test.json +0 -11
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,7 +1,7 @@
|
|
|
1
1
|
import { PrismaClient } from "@prisma/client";
|
|
2
2
|
type ModelName = string;
|
|
3
3
|
export type PrefixConfig<ModelName extends string> = {
|
|
4
|
-
prefixes: Record<ModelName, string
|
|
4
|
+
prefixes: Partial<Record<ModelName, string>>;
|
|
5
5
|
idGenerator?: (prefix: string) => string;
|
|
6
6
|
};
|
|
7
7
|
type QueryArgs = {
|
package/dist/index.js
CHANGED
|
@@ -1,13 +1,9 @@
|
|
|
1
|
-
|
|
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 =
|
|
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.
|
|
3
|
+
"version": "1.3.0",
|
|
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
|
-
"
|
|
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 <
|
|
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
|
-
}
|
package/.github/workflows/ci.yml
DELETED
|
@@ -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,137 +0,0 @@
|
|
|
1
|
-
import { jest } from "@jest/globals";
|
|
2
|
-
|
|
3
|
-
import { PrismaClient } from "@prisma/client";
|
|
4
|
-
import { createPrefixedIdsExtension, extendPrismaClient } from "../index";
|
|
5
|
-
|
|
6
|
-
// Mock PrismaClient
|
|
7
|
-
jest.mock("@prisma/client", () => {
|
|
8
|
-
return {
|
|
9
|
-
PrismaClient: jest.fn().mockImplementation(() => ({
|
|
10
|
-
$extends: jest.fn(),
|
|
11
|
-
})),
|
|
12
|
-
};
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
// Mock nanoid
|
|
16
|
-
jest.mock("nanoid", () => ({
|
|
17
|
-
customAlphabet: jest.fn().mockImplementation(() => () => "mock_nanoid_value"),
|
|
18
|
-
}));
|
|
19
|
-
|
|
20
|
-
describe("PrefixedIdsExtension", () => {
|
|
21
|
-
let prisma: PrismaClient;
|
|
22
|
-
const mockQuery = jest.fn((args: any) => Promise.resolve(args));
|
|
23
|
-
|
|
24
|
-
beforeEach(() => {
|
|
25
|
-
jest.clearAllMocks();
|
|
26
|
-
prisma = new PrismaClient();
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
describe("createPrefixedIdsExtension", () => {
|
|
30
|
-
it("should create an extension with the correct name", () => {
|
|
31
|
-
const extension = createPrefixedIdsExtension({
|
|
32
|
-
prefixes: {
|
|
33
|
-
Test: "test",
|
|
34
|
-
},
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
expect(extension.name).toBe("prefixedIds");
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
it("should use default idGenerator if none provided", async () => {
|
|
41
|
-
const extension = createPrefixedIdsExtension({
|
|
42
|
-
prefixes: {
|
|
43
|
-
Test: "test",
|
|
44
|
-
},
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
const result = await extension.query.$allModels.create({
|
|
48
|
-
args: { data: {} },
|
|
49
|
-
query: mockQuery,
|
|
50
|
-
model: "Test",
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
expect(result).toBeDefined();
|
|
54
|
-
expect(mockQuery).toHaveBeenCalled();
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
it("should use custom idGenerator if provided", async () => {
|
|
58
|
-
const customIdGenerator = jest.fn(
|
|
59
|
-
(prefix: string) => `${prefix}_custom_id`,
|
|
60
|
-
);
|
|
61
|
-
const extension = createPrefixedIdsExtension({
|
|
62
|
-
prefixes: {
|
|
63
|
-
Test: "test",
|
|
64
|
-
},
|
|
65
|
-
idGenerator: customIdGenerator,
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
await extension.query.$allModels.create({
|
|
69
|
-
args: { data: {} },
|
|
70
|
-
query: mockQuery,
|
|
71
|
-
model: "Test",
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
expect(customIdGenerator).toHaveBeenCalledWith("test");
|
|
75
|
-
expect(mockQuery).toHaveBeenCalledWith({
|
|
76
|
-
data: { id: "test_custom_id" },
|
|
77
|
-
});
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
it("should not modify args if model has no prefix", async () => {
|
|
81
|
-
const extension = createPrefixedIdsExtension({
|
|
82
|
-
prefixes: {
|
|
83
|
-
Test: "test",
|
|
84
|
-
},
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
const originalArgs = { data: {} };
|
|
88
|
-
const result = await extension.query.$allModels.create({
|
|
89
|
-
args: originalArgs,
|
|
90
|
-
query: mockQuery,
|
|
91
|
-
model: "UnknownModel",
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
expect(result).toBeDefined();
|
|
95
|
-
expect(result.data).not.toHaveProperty("id");
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
it("should handle createMany operation", async () => {
|
|
99
|
-
const extension = createPrefixedIdsExtension({
|
|
100
|
-
prefixes: {
|
|
101
|
-
Test: "test",
|
|
102
|
-
},
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
const result = await extension.query.$allModels.createMany({
|
|
106
|
-
args: {
|
|
107
|
-
data: [{}, {}],
|
|
108
|
-
},
|
|
109
|
-
query: mockQuery,
|
|
110
|
-
model: "Test",
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
expect(result).toBeDefined();
|
|
114
|
-
expect(result.data).toHaveLength(2);
|
|
115
|
-
expect(result.data[0]).toHaveProperty("id");
|
|
116
|
-
expect(result.data[1]).toHaveProperty("id");
|
|
117
|
-
});
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
describe("extendPrismaClient", () => {
|
|
121
|
-
it("should extend the Prisma client with the extension", () => {
|
|
122
|
-
const extendedPrisma = extendPrismaClient(prisma, {
|
|
123
|
-
prefixes: {
|
|
124
|
-
Test: "test",
|
|
125
|
-
},
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
expect(prisma.$extends).toHaveBeenCalled();
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
it("should not throw error if prefixes are not provided", () => {
|
|
132
|
-
expect(() => {
|
|
133
|
-
extendPrismaClient(prisma, {} as any);
|
|
134
|
-
}).not.toThrow();
|
|
135
|
-
});
|
|
136
|
-
});
|
|
137
|
-
});
|
package/src/index.ts
DELETED
|
@@ -1,84 +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: Record<ModelName, string>;
|
|
9
|
-
idGenerator?: (prefix: string) => string;
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
const defaultIdGenerator = (prefix: string): string => {
|
|
13
|
-
const nanoid = customAlphabet("0123456789abcdefghijklmnopqrstuvwxyz", 24);
|
|
14
|
-
return `${prefix}_${nanoid()}`;
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
type QueryArgs = {
|
|
18
|
-
args: any;
|
|
19
|
-
query: (args: any) => Promise<any>;
|
|
20
|
-
model: ModelName;
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
export function createPrefixedIdsExtension<ModelName extends string>(
|
|
24
|
-
config: PrefixConfig<ModelName>,
|
|
25
|
-
): {
|
|
26
|
-
name: string;
|
|
27
|
-
query: {
|
|
28
|
-
$allModels: {
|
|
29
|
-
create: (args: QueryArgs) => Promise<any>;
|
|
30
|
-
createMany: (args: QueryArgs) => Promise<any>;
|
|
31
|
-
};
|
|
32
|
-
};
|
|
33
|
-
} {
|
|
34
|
-
const { prefixes, idGenerator = defaultIdGenerator } = config;
|
|
35
|
-
|
|
36
|
-
const prefixedId = (modelName: ModelName): string | null => {
|
|
37
|
-
if (modelName in prefixes) {
|
|
38
|
-
return idGenerator(prefixes[modelName]);
|
|
39
|
-
}
|
|
40
|
-
return null;
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
return {
|
|
44
|
-
name: "prefixedIds",
|
|
45
|
-
query: {
|
|
46
|
-
$allModels: {
|
|
47
|
-
create: ({ args, query, model }: QueryArgs): Promise<any> => {
|
|
48
|
-
if (args.data && !args.data.id) {
|
|
49
|
-
const id = prefixedId(model as ModelName);
|
|
50
|
-
if (id) {
|
|
51
|
-
args.data.id = id;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
return query(args);
|
|
55
|
-
},
|
|
56
|
-
|
|
57
|
-
createMany: ({ args, query, model }: QueryArgs): Promise<any> => {
|
|
58
|
-
if (model in prefixes && args.data && Array.isArray(args.data)) {
|
|
59
|
-
args.data = (args.data as Record<string, any>[]).map((item) => {
|
|
60
|
-
if (!item.id) {
|
|
61
|
-
const id = prefixedId(model as ModelName);
|
|
62
|
-
if (id) {
|
|
63
|
-
return {
|
|
64
|
-
...item,
|
|
65
|
-
id,
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
return item;
|
|
70
|
-
});
|
|
71
|
-
}
|
|
72
|
-
return query(args);
|
|
73
|
-
},
|
|
74
|
-
},
|
|
75
|
-
},
|
|
76
|
-
};
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
export function extendPrismaClient<ModelName extends string = string>(
|
|
80
|
-
prisma: PrismaClient,
|
|
81
|
-
config: PrefixConfig<ModelName>,
|
|
82
|
-
): PrismaClient {
|
|
83
|
-
return prisma.$extends(createPrefixedIdsExtension(config));
|
|
84
|
-
}
|
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
|
-
}
|
package/tsconfig.test.json
DELETED
|
@@ -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
|
-
}
|