payload-rbac-plugin 1.0.1 → 1.0.2
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/collections/Permissions.js +100 -7
- package/dist/collections/Permissions.js.map +1 -1
- package/dist/collections/Roles.js +2 -1
- package/dist/collections/Roles.js.map +1 -1
- package/dist/exports/client.js +1 -1
- package/dist/exports/client.js.map +1 -1
- package/dist/exports/rsc.js +1 -1
- package/dist/exports/rsc.js.map +1 -1
- package/dist/hooks/beforePermissionChange.js +58 -0
- package/dist/hooks/beforePermissionChange.js.map +1 -0
- package/dist/index.js +4 -4
- package/dist/index.js.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utilities/checkPermission.js +1 -1
- package/dist/utilities/checkPermission.js.map +1 -1
- package/dist/utilities/hasPermission.js +0 -5
- package/dist/utilities/hasPermission.js.map +1 -1
- package/dist/utilities/hasPermission.spec.js +3 -1
- package/dist/utilities/hasPermission.spec.js.map +1 -1
- package/dist/utilities/index.js +2 -2
- package/dist/utilities/index.js.map +1 -1
- package/package.json +32 -60
|
@@ -1,27 +1,120 @@
|
|
|
1
|
+
import { createBeforePermissionChangeHook } from '../hooks/beforePermissionChange';
|
|
1
2
|
export const createPermissionsCollection = (options)=>{
|
|
2
3
|
const slug = options.permissionsCollectionSlug || 'permissions';
|
|
3
4
|
const customFields = options.permissionsFields || [];
|
|
4
5
|
return {
|
|
5
6
|
slug,
|
|
6
|
-
admin: {
|
|
7
|
-
useAsTitle: 'name',
|
|
8
|
-
group: 'Access Control'
|
|
9
|
-
},
|
|
10
7
|
access: {
|
|
11
8
|
read: ()=>true
|
|
12
9
|
},
|
|
10
|
+
admin: {
|
|
11
|
+
group: 'Access Control',
|
|
12
|
+
hidden: options.hidePermissions ?? false,
|
|
13
|
+
useAsTitle: 'name'
|
|
14
|
+
},
|
|
13
15
|
fields: [
|
|
16
|
+
{
|
|
17
|
+
name: 'type',
|
|
18
|
+
type: 'select',
|
|
19
|
+
admin: {
|
|
20
|
+
condition: (data)=>!data?.id && !data?._id && !data?.createdAt,
|
|
21
|
+
description: 'Choose whether to create a single custom permission or generate multiple CRUD permissions at once.',
|
|
22
|
+
disableListColumn: true,
|
|
23
|
+
disableListFilter: true
|
|
24
|
+
},
|
|
25
|
+
defaultValue: 'single',
|
|
26
|
+
options: [
|
|
27
|
+
{
|
|
28
|
+
label: 'Single Permission',
|
|
29
|
+
value: 'single'
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
label: 'Bulk CRUD Generator',
|
|
33
|
+
value: 'bulk'
|
|
34
|
+
}
|
|
35
|
+
]
|
|
36
|
+
},
|
|
14
37
|
{
|
|
15
38
|
name: 'name',
|
|
16
39
|
type: 'text',
|
|
17
|
-
|
|
40
|
+
admin: {
|
|
41
|
+
condition: (data)=>data?.type === 'single',
|
|
42
|
+
description: 'The unique name of the permission (e.g., "access:admin", "posts:create").'
|
|
43
|
+
},
|
|
18
44
|
unique: true,
|
|
45
|
+
validate: (value, { data })=>{
|
|
46
|
+
if (data?.type === 'single' && !value) {
|
|
47
|
+
return 'Name is required for single permissions.';
|
|
48
|
+
}
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
name: 'collectionName',
|
|
54
|
+
type: 'text',
|
|
19
55
|
admin: {
|
|
20
|
-
|
|
56
|
+
condition: (data)=>data?.type === 'bulk',
|
|
57
|
+
description: 'Enter a collection slug (e.g., "posts") to auto-generate permissions.',
|
|
58
|
+
disableListColumn: true,
|
|
59
|
+
disableListFilter: true
|
|
21
60
|
}
|
|
22
61
|
},
|
|
62
|
+
{
|
|
63
|
+
type: 'row',
|
|
64
|
+
fields: [
|
|
65
|
+
{
|
|
66
|
+
name: 'create',
|
|
67
|
+
type: 'checkbox',
|
|
68
|
+
admin: {
|
|
69
|
+
condition: (data)=>data?.type === 'bulk',
|
|
70
|
+
disableListColumn: true,
|
|
71
|
+
disableListFilter: true,
|
|
72
|
+
width: '25%'
|
|
73
|
+
},
|
|
74
|
+
defaultValue: false
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
name: 'read',
|
|
78
|
+
type: 'checkbox',
|
|
79
|
+
admin: {
|
|
80
|
+
condition: (data)=>data?.type === 'bulk',
|
|
81
|
+
disableListColumn: true,
|
|
82
|
+
disableListFilter: true,
|
|
83
|
+
width: '25%'
|
|
84
|
+
},
|
|
85
|
+
defaultValue: false
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
name: 'update',
|
|
89
|
+
type: 'checkbox',
|
|
90
|
+
admin: {
|
|
91
|
+
condition: (data)=>data?.type === 'bulk',
|
|
92
|
+
disableListColumn: true,
|
|
93
|
+
disableListFilter: true,
|
|
94
|
+
width: '25%'
|
|
95
|
+
},
|
|
96
|
+
defaultValue: false
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
name: 'delete',
|
|
100
|
+
type: 'checkbox',
|
|
101
|
+
admin: {
|
|
102
|
+
condition: (data)=>data?.type === 'bulk',
|
|
103
|
+
disableListColumn: true,
|
|
104
|
+
disableListFilter: true,
|
|
105
|
+
width: '25%'
|
|
106
|
+
},
|
|
107
|
+
defaultValue: false
|
|
108
|
+
}
|
|
109
|
+
]
|
|
110
|
+
},
|
|
23
111
|
...customFields
|
|
24
|
-
]
|
|
112
|
+
],
|
|
113
|
+
hooks: {
|
|
114
|
+
beforeChange: [
|
|
115
|
+
createBeforePermissionChangeHook(slug)
|
|
116
|
+
]
|
|
117
|
+
}
|
|
25
118
|
};
|
|
26
119
|
};
|
|
27
120
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/collections/Permissions.ts"],"sourcesContent":["import type { CollectionConfig } from 'payload'\nimport type { PluginOptions } from '../types
|
|
1
|
+
{"version":3,"sources":["../../src/collections/Permissions.ts"],"sourcesContent":["import type { CollectionConfig } from 'payload'\n\nimport type { PluginOptions } from '../types'\n\nimport { createBeforePermissionChangeHook } from '../hooks/beforePermissionChange'\n\nexport const createPermissionsCollection = (options: PluginOptions): CollectionConfig => {\n const slug = options.permissionsCollectionSlug || 'permissions'\n const customFields = options.permissionsFields || []\n\n return {\n slug,\n access: {\n read: () => true,\n },\n admin: {\n group: 'Access Control',\n hidden: options.hidePermissions ?? false,\n useAsTitle: 'name',\n },\n fields: [\n {\n name: 'type',\n type: 'select',\n admin: {\n condition: (data) => !data?.id && !data?._id && !data?.createdAt,\n description:\n 'Choose whether to create a single custom permission or generate multiple CRUD permissions at once.',\n disableListColumn: true,\n disableListFilter: true,\n },\n defaultValue: 'single',\n options: [\n { label: 'Single Permission', value: 'single' },\n { label: 'Bulk CRUD Generator', value: 'bulk' },\n ],\n },\n {\n name: 'name',\n type: 'text',\n admin: {\n condition: (data) => data?.type === 'single',\n description: 'The unique name of the permission (e.g., \"access:admin\", \"posts:create\").',\n },\n unique: true,\n validate: (value: null | string | undefined, { data }: { data?: any }) => {\n if (data?.type === 'single' && !value) {\n return 'Name is required for single permissions.'\n }\n return true\n },\n },\n {\n name: 'collectionName',\n type: 'text',\n admin: {\n condition: (data) => data?.type === 'bulk',\n description: 'Enter a collection slug (e.g., \"posts\") to auto-generate permissions.',\n disableListColumn: true,\n disableListFilter: true,\n },\n },\n {\n type: 'row',\n fields: [\n {\n name: 'create',\n type: 'checkbox',\n admin: {\n condition: (data) => data?.type === 'bulk',\n disableListColumn: true,\n disableListFilter: true,\n width: '25%',\n },\n defaultValue: false,\n },\n {\n name: 'read',\n type: 'checkbox',\n admin: {\n condition: (data) => data?.type === 'bulk',\n disableListColumn: true,\n disableListFilter: true,\n width: '25%',\n },\n defaultValue: false,\n },\n {\n name: 'update',\n type: 'checkbox',\n admin: {\n condition: (data) => data?.type === 'bulk',\n disableListColumn: true,\n disableListFilter: true,\n width: '25%',\n },\n defaultValue: false,\n },\n {\n name: 'delete',\n type: 'checkbox',\n admin: {\n condition: (data) => data?.type === 'bulk',\n disableListColumn: true,\n disableListFilter: true,\n width: '25%',\n },\n defaultValue: false,\n },\n ],\n },\n ...customFields,\n ],\n hooks: {\n beforeChange: [createBeforePermissionChangeHook(slug)],\n },\n }\n}\n"],"names":["createBeforePermissionChangeHook","createPermissionsCollection","options","slug","permissionsCollectionSlug","customFields","permissionsFields","access","read","admin","group","hidden","hidePermissions","useAsTitle","fields","name","type","condition","data","id","_id","createdAt","description","disableListColumn","disableListFilter","defaultValue","label","value","unique","validate","width","hooks","beforeChange"],"mappings":"AAIA,SAASA,gCAAgC,QAAQ,kCAAiC;AAElF,OAAO,MAAMC,8BAA8B,CAACC;IAC1C,MAAMC,OAAOD,QAAQE,yBAAyB,IAAI;IAClD,MAAMC,eAAeH,QAAQI,iBAAiB,IAAI,EAAE;IAEpD,OAAO;QACLH;QACAI,QAAQ;YACNC,MAAM,IAAM;QACd;QACAC,OAAO;YACLC,OAAO;YACPC,QAAQT,QAAQU,eAAe,IAAI;YACnCC,YAAY;QACd;QACAC,QAAQ;YACN;gBACEC,MAAM;gBACNC,MAAM;gBACNP,OAAO;oBACLQ,WAAW,CAACC,OAAS,CAACA,MAAMC,MAAM,CAACD,MAAME,OAAO,CAACF,MAAMG;oBACvDC,aACE;oBACFC,mBAAmB;oBACnBC,mBAAmB;gBACrB;gBACAC,cAAc;gBACdvB,SAAS;oBACP;wBAAEwB,OAAO;wBAAqBC,OAAO;oBAAS;oBAC9C;wBAAED,OAAO;wBAAuBC,OAAO;oBAAO;iBAC/C;YACH;YACA;gBACEZ,MAAM;gBACNC,MAAM;gBACNP,OAAO;oBACLQ,WAAW,CAACC,OAASA,MAAMF,SAAS;oBACpCM,aAAa;gBACf;gBACAM,QAAQ;gBACRC,UAAU,CAACF,OAAkC,EAAET,IAAI,EAAkB;oBACnE,IAAIA,MAAMF,SAAS,YAAY,CAACW,OAAO;wBACrC,OAAO;oBACT;oBACA,OAAO;gBACT;YACF;YACA;gBACEZ,MAAM;gBACNC,MAAM;gBACNP,OAAO;oBACLQ,WAAW,CAACC,OAASA,MAAMF,SAAS;oBACpCM,aAAa;oBACbC,mBAAmB;oBACnBC,mBAAmB;gBACrB;YACF;YACA;gBACER,MAAM;gBACNF,QAAQ;oBACN;wBACEC,MAAM;wBACNC,MAAM;wBACNP,OAAO;4BACLQ,WAAW,CAACC,OAASA,MAAMF,SAAS;4BACpCO,mBAAmB;4BACnBC,mBAAmB;4BACnBM,OAAO;wBACT;wBACAL,cAAc;oBAChB;oBACA;wBACEV,MAAM;wBACNC,MAAM;wBACNP,OAAO;4BACLQ,WAAW,CAACC,OAASA,MAAMF,SAAS;4BACpCO,mBAAmB;4BACnBC,mBAAmB;4BACnBM,OAAO;wBACT;wBACAL,cAAc;oBAChB;oBACA;wBACEV,MAAM;wBACNC,MAAM;wBACNP,OAAO;4BACLQ,WAAW,CAACC,OAASA,MAAMF,SAAS;4BACpCO,mBAAmB;4BACnBC,mBAAmB;4BACnBM,OAAO;wBACT;wBACAL,cAAc;oBAChB;oBACA;wBACEV,MAAM;wBACNC,MAAM;wBACNP,OAAO;4BACLQ,WAAW,CAACC,OAASA,MAAMF,SAAS;4BACpCO,mBAAmB;4BACnBC,mBAAmB;4BACnBM,OAAO;wBACT;wBACAL,cAAc;oBAChB;iBACD;YACH;eACGpB;SACJ;QACD0B,OAAO;YACLC,cAAc;gBAAChC,iCAAiCG;aAAM;QACxD;IACF;AACF,EAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/collections/Roles.ts"],"sourcesContent":["import type { CollectionConfig } from 'payload'
|
|
1
|
+
{"version":3,"sources":["../../src/collections/Roles.ts"],"sourcesContent":["import type { CollectionConfig } from 'payload';\nimport type { PluginOptions } from '../types';\n\nexport const createRolesCollection = (options: PluginOptions): CollectionConfig => {\n const slug = options.rolesCollectionSlug || 'roles'\n const permissionsSlug = options.permissionsCollectionSlug || 'permissions'\n const customFields = options.rolesFields || []\n\n return {\n slug,\n admin: {\n useAsTitle: 'name',\n group: 'Access Control',\n hidden: options.hideRoles ?? false,\n },\n access: {\n read: () => true,\n },\n fields: [\n {\n name: 'name',\n type: 'text',\n required: true,\n unique: true,\n admin: {\n description: 'The unique name of the role (e.g., \"admin\", \"editor\").',\n },\n },\n {\n name: 'permissions',\n type: 'relationship',\n relationTo: permissionsSlug,\n hasMany: true,\n admin: {\n description: 'The permissions assigned to this role.',\n },\n },\n ...customFields,\n ],\n }\n}\n"],"names":["createRolesCollection","options","slug","rolesCollectionSlug","permissionsSlug","permissionsCollectionSlug","customFields","rolesFields","admin","useAsTitle","group","hidden","hideRoles","access","read","fields","name","type","required","unique","description","relationTo","hasMany"],"mappings":"AAGA,OAAO,MAAMA,wBAAwB,CAACC;IACpC,MAAMC,OAAOD,QAAQE,mBAAmB,IAAI;IAC5C,MAAMC,kBAAkBH,QAAQI,yBAAyB,IAAI;IAC7D,MAAMC,eAAeL,QAAQM,WAAW,IAAI,EAAE;IAE9C,OAAO;QACLL;QACAM,OAAO;YACLC,YAAY;YACZC,OAAO;YACPC,QAAQV,QAAQW,SAAS,IAAI;QAC/B;QACAC,QAAQ;YACNC,MAAM,IAAM;QACd;QACAC,QAAQ;YACN;gBACEC,MAAM;gBACNC,MAAM;gBACNC,UAAU;gBACVC,QAAQ;gBACRX,OAAO;oBACLY,aAAa;gBACf;YACF;YACA;gBACEJ,MAAM;gBACNC,MAAM;gBACNI,YAAYjB;gBACZkB,SAAS;gBACTd,OAAO;oBACLY,aAAa;gBACf;YACF;eACGd;SACJ;IACH;AACF,EAAC"}
|
package/dist/exports/client.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/exports/client.ts"],"sourcesContent":["export { BeforeDashboardClient } from '../components/BeforeDashboardClient
|
|
1
|
+
{"version":3,"sources":["../../src/exports/client.ts"],"sourcesContent":["export { BeforeDashboardClient } from '../components/BeforeDashboardClient';\n\n"],"names":["BeforeDashboardClient"],"mappings":"AAAA,SAASA,qBAAqB,QAAQ,sCAAsC"}
|
package/dist/exports/rsc.js
CHANGED
package/dist/exports/rsc.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/exports/rsc.ts"],"sourcesContent":["export { BeforeDashboardServer } from '../components/BeforeDashboardServer
|
|
1
|
+
{"version":3,"sources":["../../src/exports/rsc.ts"],"sourcesContent":["export { BeforeDashboardServer } from '../components/BeforeDashboardServer';\n\n"],"names":["BeforeDashboardServer"],"mappings":"AAAA,SAASA,qBAAqB,QAAQ,sCAAsC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
export const createBeforePermissionChangeHook = (slug)=>{
|
|
2
|
+
return async ({ data, req })=>{
|
|
3
|
+
// Only run generator logic on create/update if type is bulk
|
|
4
|
+
if (data.type === 'bulk' && data.collectionName) {
|
|
5
|
+
const actions = [
|
|
6
|
+
'create',
|
|
7
|
+
'read',
|
|
8
|
+
'update',
|
|
9
|
+
'delete'
|
|
10
|
+
].filter((action)=>data[action] === true);
|
|
11
|
+
if (actions.length === 0) {
|
|
12
|
+
throw new Error('You must select at least one CRUD operation when using the Bulk Generator.');
|
|
13
|
+
}
|
|
14
|
+
// e.g. ["posts:create", "posts:read"]
|
|
15
|
+
const generatedNames = actions.map((action)=>`${data.collectionName}:${action}`);
|
|
16
|
+
// Filter out names that already exist
|
|
17
|
+
const uniqueNames = [];
|
|
18
|
+
for (const name of generatedNames){
|
|
19
|
+
const existing = await req.payload.find({
|
|
20
|
+
collection: slug,
|
|
21
|
+
where: {
|
|
22
|
+
name: {
|
|
23
|
+
equals: name
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
if (existing.docs.length === 0) {
|
|
28
|
+
uniqueNames.push(name);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
if (uniqueNames.length === 0) {
|
|
32
|
+
throw new Error('All selected CRUD permissions already exist.');
|
|
33
|
+
}
|
|
34
|
+
// Mutate current document to save the first unique generated name
|
|
35
|
+
data.name = uniqueNames[0];
|
|
36
|
+
// Create the remaining unique permissions in the background
|
|
37
|
+
const remainingNames = uniqueNames.slice(1);
|
|
38
|
+
for (const name of remainingNames){
|
|
39
|
+
await req.payload.create({
|
|
40
|
+
collection: slug,
|
|
41
|
+
data: {
|
|
42
|
+
name
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
// Ensure UI-only fields are never saved to the database
|
|
48
|
+
delete data.type;
|
|
49
|
+
delete data.collectionName;
|
|
50
|
+
delete data.create;
|
|
51
|
+
delete data.read;
|
|
52
|
+
delete data.update;
|
|
53
|
+
delete data.delete;
|
|
54
|
+
return data;
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
//# sourceMappingURL=beforePermissionChange.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/hooks/beforePermissionChange.ts"],"sourcesContent":["import type { CollectionBeforeChangeHook } from 'payload'\n\nexport const createBeforePermissionChangeHook = (slug: string): CollectionBeforeChangeHook => {\n return async ({ data, req }) => {\n // Only run generator logic on create/update if type is bulk\n if (data.type === 'bulk' && data.collectionName) {\n const actions = ['create', 'read', 'update', 'delete'].filter(\n (action) => data[action] === true,\n )\n\n if (actions.length === 0) {\n throw new Error('You must select at least one CRUD operation when using the Bulk Generator.')\n }\n\n // e.g. [\"posts:create\", \"posts:read\"]\n const generatedNames = actions.map((action) => `${data.collectionName}:${action}`)\n\n // Filter out names that already exist\n const uniqueNames: string[] = []\n for (const name of generatedNames) {\n const existing = await req.payload.find({\n collection: slug,\n where: {\n name: { equals: name },\n },\n })\n if (existing.docs.length === 0) {\n uniqueNames.push(name)\n }\n }\n\n if (uniqueNames.length === 0) {\n throw new Error('All selected CRUD permissions already exist.')\n }\n\n // Mutate current document to save the first unique generated name\n data.name = uniqueNames[0]\n\n // Create the remaining unique permissions in the background\n const remainingNames = uniqueNames.slice(1)\n for (const name of remainingNames) {\n await req.payload.create({\n collection: slug,\n data: {\n name,\n },\n })\n }\n }\n\n // Ensure UI-only fields are never saved to the database\n delete data.type\n delete data.collectionName\n delete data.create\n delete data.read\n delete data.update\n delete data.delete\n\n return data\n }\n}\n"],"names":["createBeforePermissionChangeHook","slug","data","req","type","collectionName","actions","filter","action","length","Error","generatedNames","map","uniqueNames","name","existing","payload","find","collection","where","equals","docs","push","remainingNames","slice","create","read","update","delete"],"mappings":"AAEA,OAAO,MAAMA,mCAAmC,CAACC;IAC/C,OAAO,OAAO,EAAEC,IAAI,EAAEC,GAAG,EAAE;QACzB,4DAA4D;QAC5D,IAAID,KAAKE,IAAI,KAAK,UAAUF,KAAKG,cAAc,EAAE;YAC/C,MAAMC,UAAU;gBAAC;gBAAU;gBAAQ;gBAAU;aAAS,CAACC,MAAM,CAC3D,CAACC,SAAWN,IAAI,CAACM,OAAO,KAAK;YAG/B,IAAIF,QAAQG,MAAM,KAAK,GAAG;gBACxB,MAAM,IAAIC,MAAM;YAClB;YAEA,sCAAsC;YACtC,MAAMC,iBAAiBL,QAAQM,GAAG,CAAC,CAACJ,SAAW,GAAGN,KAAKG,cAAc,CAAC,CAAC,EAAEG,QAAQ;YAEjF,sCAAsC;YACtC,MAAMK,cAAwB,EAAE;YAChC,KAAK,MAAMC,QAAQH,eAAgB;gBACjC,MAAMI,WAAW,MAAMZ,IAAIa,OAAO,CAACC,IAAI,CAAC;oBACtCC,YAAYjB;oBACZkB,OAAO;wBACLL,MAAM;4BAAEM,QAAQN;wBAAK;oBACvB;gBACF;gBACA,IAAIC,SAASM,IAAI,CAACZ,MAAM,KAAK,GAAG;oBAC9BI,YAAYS,IAAI,CAACR;gBACnB;YACF;YAEA,IAAID,YAAYJ,MAAM,KAAK,GAAG;gBAC5B,MAAM,IAAIC,MAAM;YAClB;YAEA,kEAAkE;YAClER,KAAKY,IAAI,GAAGD,WAAW,CAAC,EAAE;YAE1B,4DAA4D;YAC5D,MAAMU,iBAAiBV,YAAYW,KAAK,CAAC;YACzC,KAAK,MAAMV,QAAQS,eAAgB;gBACjC,MAAMpB,IAAIa,OAAO,CAACS,MAAM,CAAC;oBACvBP,YAAYjB;oBACZC,MAAM;wBACJY;oBACF;gBACF;YACF;QACF;QAEA,wDAAwD;QACxD,OAAOZ,KAAKE,IAAI;QAChB,OAAOF,KAAKG,cAAc;QAC1B,OAAOH,KAAKuB,MAAM;QAClB,OAAOvB,KAAKwB,IAAI;QAChB,OAAOxB,KAAKyB,MAAM;QAClB,OAAOzB,KAAK0B,MAAM;QAElB,OAAO1B;IACT;AACF,EAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { createPermissionsCollection } from './collections/Permissions
|
|
2
|
-
import { createRolesCollection } from './collections/Roles
|
|
1
|
+
import { createPermissionsCollection } from './collections/Permissions';
|
|
2
|
+
import { createRolesCollection } from './collections/Roles';
|
|
3
3
|
export const rbac = (pluginOptions)=>(config)=>{
|
|
4
4
|
const options = pluginOptions || {};
|
|
5
5
|
if (options.enabled === false) {
|
|
@@ -32,7 +32,7 @@ export const rbac = (pluginOptions)=>(config)=>{
|
|
|
32
32
|
return config;
|
|
33
33
|
};
|
|
34
34
|
// Export utilities and types for consumers
|
|
35
|
-
export * from './types
|
|
36
|
-
export * from './utilities/index
|
|
35
|
+
export * from './types';
|
|
36
|
+
export * from './utilities/index';
|
|
37
37
|
|
|
38
38
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type { Config } from 'payload'
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type { Config } from 'payload';\nimport type { PluginOptions } from './types';\n\nimport { createPermissionsCollection } from './collections/Permissions';\nimport { createRolesCollection } from './collections/Roles';\n\nexport const rbac =\n (pluginOptions?: PluginOptions) =>\n (config: Config): Config => {\n const options = pluginOptions || {}\n \n if (options.enabled === false) {\n return config\n }\n\n if (!config.collections) {\n config.collections = []\n }\n\n // Add Roles and Permissions collections\n config.collections.push(createPermissionsCollection(options))\n config.collections.push(createRolesCollection(options))\n\n // Extend the target auth collection\n const authSlug = options.authCollectionSlug || 'users'\n const rolesSlug = options.rolesCollectionSlug || 'roles'\n\n const authCollection = config.collections.find(\n (collection) => collection.slug === authSlug,\n )\n\n if (authCollection) {\n authCollection.fields.push({\n name: 'roles',\n type: 'relationship',\n relationTo: rolesSlug,\n hasMany: true,\n saveToJWT: true,\n admin: {\n description: 'Roles assigned to this user.',\n },\n })\n } else {\n console.warn(`[rbac-plugin] Auth collection '${authSlug}' not found. Cannot inject roles field.`)\n }\n\n return config\n }\n\n// Export utilities and types for consumers\nexport * from './types';\nexport * from './utilities/index';\n\n"],"names":["createPermissionsCollection","createRolesCollection","rbac","pluginOptions","config","options","enabled","collections","push","authSlug","authCollectionSlug","rolesSlug","rolesCollectionSlug","authCollection","find","collection","slug","fields","name","type","relationTo","hasMany","saveToJWT","admin","description","console","warn"],"mappings":"AAGA,SAASA,2BAA2B,QAAQ,4BAA4B;AACxE,SAASC,qBAAqB,QAAQ,sBAAsB;AAE5D,OAAO,MAAMC,OACX,CAACC,gBACD,CAACC;QACC,MAAMC,UAAUF,iBAAiB,CAAC;QAElC,IAAIE,QAAQC,OAAO,KAAK,OAAO;YAC7B,OAAOF;QACT;QAEA,IAAI,CAACA,OAAOG,WAAW,EAAE;YACvBH,OAAOG,WAAW,GAAG,EAAE;QACzB;QAEA,wCAAwC;QACxCH,OAAOG,WAAW,CAACC,IAAI,CAACR,4BAA4BK;QACpDD,OAAOG,WAAW,CAACC,IAAI,CAACP,sBAAsBI;QAE9C,oCAAoC;QACpC,MAAMI,WAAWJ,QAAQK,kBAAkB,IAAI;QAC/C,MAAMC,YAAYN,QAAQO,mBAAmB,IAAI;QAEjD,MAAMC,iBAAiBT,OAAOG,WAAW,CAACO,IAAI,CAC5C,CAACC,aAAeA,WAAWC,IAAI,KAAKP;QAGtC,IAAII,gBAAgB;YAClBA,eAAeI,MAAM,CAACT,IAAI,CAAC;gBACzBU,MAAM;gBACNC,MAAM;gBACNC,YAAYT;gBACZU,SAAS;gBACTC,WAAW;gBACXC,OAAO;oBACLC,aAAa;gBACf;YACF;QACF,OAAO;YACLC,QAAQC,IAAI,CAAC,CAAC,+BAA+B,EAAEjB,SAAS,uCAAuC,CAAC;QAClG;QAEA,OAAOL;IACT,EAAC;AAEH,2CAA2C;AAC3C,cAAc,UAAU;AACxB,cAAc,oBAAoB"}
|
package/dist/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/types.ts"],"sourcesContent":["import type { Field } from 'payload'\n\nexport interface PluginOptions {\n /**\n * Enable or disable plugin\n * @default false\n */\n enabled?: boolean\n\n /**\n * Override the default collection slug for Roles\n * @default 'roles'\n */\n rolesCollectionSlug?: string\n\n /**\n * Override the default collection slug for Permissions\n * @default 'permissions'\n */\n permissionsCollectionSlug?: string\n\n /**\n * The collection slug for the authentication collection (typically 'users')\n * @default 'users'\n */\n authCollectionSlug?: string\n\n /**\n * Inject additional custom fields into the generated Roles collection\n */\n rolesFields?: Field[]\n\n /**\n * Inject additional custom fields into the generated Permissions collection\n */\n permissionsFields?: Field[]\n}\n"],"names":[],"mappings":"AAEA,
|
|
1
|
+
{"version":3,"sources":["../src/types.ts"],"sourcesContent":["import type { Field } from 'payload'\n\nexport interface PluginOptions {\n /**\n * Enable or disable plugin\n * @default false\n */\n enabled?: boolean\n\n /**\n * Override the default collection slug for Roles\n * @default 'roles'\n */\n rolesCollectionSlug?: string\n\n /**\n * Override the default collection slug for Permissions\n * @default 'permissions'\n */\n permissionsCollectionSlug?: string\n\n /**\n * The collection slug for the authentication collection (typically 'users')\n * @default 'users'\n */\n authCollectionSlug?: string\n\n /**\n * Inject additional custom fields into the generated Roles collection\n */\n rolesFields?: Field[]\n\n /**\n * Inject additional custom fields into the generated Permissions collection\n */\n permissionsFields?: Field[]\n\n /**\n * Hide the Roles collection from the Admin panel sidebar/dashboard\n * Can be a boolean or a function based on the logged-in user\n * @default false\n */\n hideRoles?: boolean | ((args: { user: any }) => boolean)\n\n /**\n * Hide the Permissions collection from the Admin panel sidebar/dashboard\n * Can be a boolean or a function based on the logged-in user\n * @default false\n */\n hidePermissions?: boolean | ((args: { user: any }) => boolean)\n}\n"],"names":[],"mappings":"AAEA,WAgDC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utilities/checkPermission.ts"],"sourcesContent":["import type { Access } from 'payload'
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/checkPermission.ts"],"sourcesContent":["import type { Access } from 'payload';\nimport { hasPermission } from './hasPermission';\n\n/**\n * A Higher-Order Function to drop into Payload Collection access control fields.\n * \n * @param permissionName - The required permission name\n * @returns Access function\n */\nexport const checkPermission = (permissionName: string): Access => {\n return ({ req: { user } }) => {\n // We can just rely on the synchronous hasPermission check.\n // If relations are unpopulated, it will return false. Ensure your auth\n // collection is configured with adequate depth for saveToJWT or default depth.\n return hasPermission(user, permissionName)\n }\n}\n"],"names":["hasPermission","checkPermission","permissionName","req","user"],"mappings":"AACA,SAASA,aAAa,QAAQ,kBAAkB;AAEhD;;;;;CAKC,GACD,OAAO,MAAMC,kBAAkB,CAACC;IAC9B,OAAO,CAAC,EAAEC,KAAK,EAAEC,IAAI,EAAE,EAAE;QACvB,2DAA2D;QAC3D,uEAAuE;QACvE,+EAA+E;QAC/E,OAAOJ,cAAcI,MAAMF;IAC7B;AACF,EAAC"}
|
|
@@ -19,16 +19,11 @@
|
|
|
19
19
|
continue;
|
|
20
20
|
}
|
|
21
21
|
for (const permission of permissions){
|
|
22
|
-
// If permission is an object (populated) and has a name
|
|
23
22
|
if (typeof permission === 'object' && permission !== null) {
|
|
24
23
|
if ('name' in permission && permission.name === requiredPermission) {
|
|
25
24
|
return true;
|
|
26
25
|
}
|
|
27
26
|
}
|
|
28
|
-
// Note: If permission is just an ID (unpopulated), we cannot synchronously
|
|
29
|
-
// determine its name here. In a strictly synchronous check, we must return false
|
|
30
|
-
// or ignore it. For a fully robust check with unpopulated data, an async version
|
|
31
|
-
// requiring the payload instance would be necessary.
|
|
32
27
|
}
|
|
33
28
|
}
|
|
34
29
|
return false;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utilities/hasPermission.ts"],"sourcesContent":["import type { PayloadRequest } from 'payload'\n\n/**\n * Checks if a user has a specific permission.\n * Gracefully handles populated and unpopulated relationship states as far as possible synchronously.\n * \n * @param user - The Payload user object from req.user\n * @param requiredPermission - The name of the permission to check for\n * @returns boolean\n */\nexport const hasPermission = (\n user: PayloadRequest['user'] | null | undefined,\n requiredPermission: string,\n): boolean => {\n if (!user || !user.roles || !Array.isArray(user.roles)) {\n return false\n }\n\n for (const role of user.roles) {\n // If role is just an ID (unpopulated), we can't check its permissions synchronously\n if (typeof role !== 'object' || role === null) {\n continue\n }\n\n const permissions = role.permissions\n if (!permissions || !Array.isArray(permissions)) {\n continue\n }\n\n for (const permission of permissions) {\n
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/hasPermission.ts"],"sourcesContent":["import type { PayloadRequest } from 'payload'\n\n/**\n * Checks if a user has a specific permission.\n * Gracefully handles populated and unpopulated relationship states as far as possible synchronously.\n * \n * @param user - The Payload user object from req.user\n * @param requiredPermission - The name of the permission to check for\n * @returns boolean\n */\nexport const hasPermission = (\n user: PayloadRequest['user'] | null | undefined,\n requiredPermission: string,\n): boolean => {\n if (!user || !user.roles || !Array.isArray(user.roles)) {\n return false\n }\n\n for (const role of user.roles) {\n // If role is just an ID (unpopulated), we can't check its permissions synchronously\n if (typeof role !== 'object' || role === null) {\n continue\n }\n\n const permissions = role.permissions\n if (!permissions || !Array.isArray(permissions)) {\n continue\n }\n\n for (const permission of permissions) {\n if (typeof permission === 'object' && permission !== null) {\n if ('name' in permission && permission.name === requiredPermission) {\n return true\n }\n } \n }\n }\n\n return false\n}\n"],"names":["hasPermission","user","requiredPermission","roles","Array","isArray","role","permissions","permission","name"],"mappings":"AAEA;;;;;;;CAOC,GACD,OAAO,MAAMA,gBAAgB,CAC3BC,MACAC;IAEA,IAAI,CAACD,QAAQ,CAACA,KAAKE,KAAK,IAAI,CAACC,MAAMC,OAAO,CAACJ,KAAKE,KAAK,GAAG;QACtD,OAAO;IACT;IAEA,KAAK,MAAMG,QAAQL,KAAKE,KAAK,CAAE;QAC7B,oFAAoF;QACpF,IAAI,OAAOG,SAAS,YAAYA,SAAS,MAAM;YAC7C;QACF;QAEA,MAAMC,cAAcD,KAAKC,WAAW;QACpC,IAAI,CAACA,eAAe,CAACH,MAAMC,OAAO,CAACE,cAAc;YAC/C;QACF;QAEA,KAAK,MAAMC,cAAcD,YAAa;YACpC,IAAI,OAAOC,eAAe,YAAYA,eAAe,MAAM;gBACzD,IAAI,UAAUA,cAAcA,WAAWC,IAAI,KAAKP,oBAAoB;oBAClE,OAAO;gBACT;YACF;QACF;IACF;IAEA,OAAO;AACT,EAAC"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { hasPermission } from './hasPermission';
|
|
2
3
|
describe('hasPermission', ()=>{
|
|
3
4
|
it('should return false if user is null', ()=>{
|
|
4
5
|
expect(hasPermission(null, 'read:posts')).toBe(false);
|
|
@@ -112,6 +113,7 @@ describe('hasPermission', ()=>{
|
|
|
112
113
|
]
|
|
113
114
|
};
|
|
114
115
|
expect(hasPermission(user, 'delete:posts')).toBe(true);
|
|
116
|
+
expect(hasPermission(user, 'delete:posts')).toBe(true);
|
|
115
117
|
expect(hasPermission(user, 'read:posts')).toBe(true);
|
|
116
118
|
expect(hasPermission(user, 'create:users')).toBe(false);
|
|
117
119
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utilities/hasPermission.spec.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/hasPermission.spec.ts"],"sourcesContent":["import type { PayloadRequest } from 'payload';\nimport { describe, expect, it } from 'vitest';\nimport { hasPermission } from './hasPermission';\n\ndescribe('hasPermission', () => {\n it('should return false if user is null', () => {\n expect(hasPermission(null, 'read:posts')).toBe(false)\n })\n\n it('should return false if user has no roles array', () => {\n const user = { id: '1' } as PayloadRequest['user']\n expect(hasPermission(user, 'read:posts')).toBe(false)\n })\n\n it('should return false if user roles is unpopulated (array of strings)', () => {\n const user = {\n id: '1',\n roles: ['role-id-1'],\n } as unknown as PayloadRequest['user']\n expect(hasPermission(user, 'read:posts')).toBe(false)\n })\n\n it('should return false if role has no permissions', () => {\n const user = {\n id: '1',\n roles: [{ id: 'role-1', name: 'admin' }],\n } as unknown as PayloadRequest['user']\n expect(hasPermission(user, 'read:posts')).toBe(false)\n })\n\n it('should return false if role permissions are unpopulated (array of strings)', () => {\n const user = {\n id: '1',\n roles: [{ id: 'role-1', name: 'admin', permissions: ['perm-id-1'] }],\n } as unknown as PayloadRequest['user']\n expect(hasPermission(user, 'read:posts')).toBe(false)\n })\n\n it('should return true if permission is found in populated roles', () => {\n const user = {\n id: '1',\n roles: [\n {\n id: 'role-1',\n name: 'admin',\n permissions: [\n { id: 'perm-1', name: 'read:posts' },\n { id: 'perm-2', name: 'write:posts' },\n ],\n },\n ],\n } as unknown as PayloadRequest['user']\n expect(hasPermission(user, 'write:posts')).toBe(true)\n })\n\n it('should return false if permission is not found in populated roles', () => {\n const user = {\n id: '1',\n roles: [\n {\n id: 'role-1',\n name: 'editor',\n permissions: [{ id: 'perm-1', name: 'read:posts' }],\n },\n ],\n } as unknown as PayloadRequest['user']\n expect(hasPermission(user, 'delete:posts')).toBe(false)\n })\n\n it('should correctly search through multiple roles', () => {\n const user = {\n id: '1',\n roles: [\n {\n id: 'role-1',\n name: 'editor',\n permissions: [{ id: 'perm-1', name: 'read:posts' }],\n },\n {\n id: 'role-2',\n name: 'manager',\n permissions: [{ id: 'perm-2', name: 'delete:posts' }],\n },\n ],\n } as unknown as PayloadRequest['user']\n expect(hasPermission(user, 'delete:posts')).toBe(true)\n expect(hasPermission(user, 'delete:posts')).toBe(true)\n expect(hasPermission(user, 'read:posts')).toBe(true)\n expect(hasPermission(user, 'create:users')).toBe(false)\n })\n})\n"],"names":["describe","expect","it","hasPermission","toBe","user","id","roles","name","permissions"],"mappings":"AACA,SAASA,QAAQ,EAAEC,MAAM,EAAEC,EAAE,QAAQ,SAAS;AAC9C,SAASC,aAAa,QAAQ,kBAAkB;AAEhDH,SAAS,iBAAiB;IACxBE,GAAG,uCAAuC;QACxCD,OAAOE,cAAc,MAAM,eAAeC,IAAI,CAAC;IACjD;IAEAF,GAAG,kDAAkD;QACnD,MAAMG,OAAO;YAAEC,IAAI;QAAI;QACvBL,OAAOE,cAAcE,MAAM,eAAeD,IAAI,CAAC;IACjD;IAEAF,GAAG,uEAAuE;QACxE,MAAMG,OAAO;YACXC,IAAI;YACJC,OAAO;gBAAC;aAAY;QACtB;QACAN,OAAOE,cAAcE,MAAM,eAAeD,IAAI,CAAC;IACjD;IAEAF,GAAG,kDAAkD;QACnD,MAAMG,OAAO;YACXC,IAAI;YACJC,OAAO;gBAAC;oBAAED,IAAI;oBAAUE,MAAM;gBAAQ;aAAE;QAC1C;QACAP,OAAOE,cAAcE,MAAM,eAAeD,IAAI,CAAC;IACjD;IAEAF,GAAG,8EAA8E;QAC/E,MAAMG,OAAO;YACXC,IAAI;YACJC,OAAO;gBAAC;oBAAED,IAAI;oBAAUE,MAAM;oBAASC,aAAa;wBAAC;qBAAY;gBAAC;aAAE;QACtE;QACAR,OAAOE,cAAcE,MAAM,eAAeD,IAAI,CAAC;IACjD;IAEAF,GAAG,gEAAgE;QACjE,MAAMG,OAAO;YACXC,IAAI;YACJC,OAAO;gBACL;oBACED,IAAI;oBACJE,MAAM;oBACNC,aAAa;wBACX;4BAAEH,IAAI;4BAAUE,MAAM;wBAAa;wBACnC;4BAAEF,IAAI;4BAAUE,MAAM;wBAAc;qBACrC;gBACH;aACD;QACH;QACAP,OAAOE,cAAcE,MAAM,gBAAgBD,IAAI,CAAC;IAClD;IAEAF,GAAG,qEAAqE;QACtE,MAAMG,OAAO;YACXC,IAAI;YACJC,OAAO;gBACL;oBACED,IAAI;oBACJE,MAAM;oBACNC,aAAa;wBAAC;4BAAEH,IAAI;4BAAUE,MAAM;wBAAa;qBAAE;gBACrD;aACD;QACH;QACAP,OAAOE,cAAcE,MAAM,iBAAiBD,IAAI,CAAC;IACnD;IAEAF,GAAG,kDAAkD;QACnD,MAAMG,OAAO;YACXC,IAAI;YACJC,OAAO;gBACL;oBACED,IAAI;oBACJE,MAAM;oBACNC,aAAa;wBAAC;4BAAEH,IAAI;4BAAUE,MAAM;wBAAa;qBAAE;gBACrD;gBACA;oBACEF,IAAI;oBACJE,MAAM;oBACNC,aAAa;wBAAC;4BAAEH,IAAI;4BAAUE,MAAM;wBAAe;qBAAE;gBACvD;aACD;QACH;QACAP,OAAOE,cAAcE,MAAM,iBAAiBD,IAAI,CAAC;QACjDH,OAAOE,cAAcE,MAAM,iBAAiBD,IAAI,CAAC;QACjDH,OAAOE,cAAcE,MAAM,eAAeD,IAAI,CAAC;QAC/CH,OAAOE,cAAcE,MAAM,iBAAiBD,IAAI,CAAC;IACnD;AACF"}
|
package/dist/utilities/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utilities/index.ts"],"sourcesContent":["export {
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/index.ts"],"sourcesContent":["export { checkPermission } from './checkPermission';\nexport { hasPermission } from './hasPermission';\n\n"],"names":["checkPermission","hasPermission"],"mappings":"AAAA,SAASA,eAAe,QAAQ,oBAAoB;AACpD,SAASC,aAAa,QAAQ,kBAAkB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "payload-rbac-plugin",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "RBAC plugin for payloadcms",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -30,44 +30,26 @@
|
|
|
30
30
|
"type": "module",
|
|
31
31
|
"exports": {
|
|
32
32
|
".": {
|
|
33
|
-
"import": "./
|
|
34
|
-
"types": "./
|
|
35
|
-
"default": "./
|
|
33
|
+
"import": "./dist/index.js",
|
|
34
|
+
"types": "./dist/index.d.ts",
|
|
35
|
+
"default": "./dist/index.js"
|
|
36
36
|
},
|
|
37
37
|
"./client": {
|
|
38
|
-
"import": "./
|
|
39
|
-
"types": "./
|
|
40
|
-
"default": "./
|
|
38
|
+
"import": "./dist/exports/client.js",
|
|
39
|
+
"types": "./dist/exports/client.d.ts",
|
|
40
|
+
"default": "./dist/exports/client.js"
|
|
41
41
|
},
|
|
42
42
|
"./rsc": {
|
|
43
|
-
"import": "./
|
|
44
|
-
"types": "./
|
|
45
|
-
"default": "./
|
|
43
|
+
"import": "./dist/exports/rsc.js",
|
|
44
|
+
"types": "./dist/exports/rsc.d.ts",
|
|
45
|
+
"default": "./dist/exports/rsc.js"
|
|
46
46
|
}
|
|
47
47
|
},
|
|
48
|
-
"main": "./
|
|
49
|
-
"types": "./
|
|
48
|
+
"main": "./dist/index.js",
|
|
49
|
+
"types": "./dist/index.d.ts",
|
|
50
50
|
"files": [
|
|
51
51
|
"dist"
|
|
52
52
|
],
|
|
53
|
-
"scripts": {
|
|
54
|
-
"build": "pnpm copyfiles && pnpm build:types && pnpm build:swc",
|
|
55
|
-
"build:swc": "swc ./src -d ./dist --config-file .swcrc --strip-leading-paths",
|
|
56
|
-
"build:types": "tsc --outDir dist --rootDir ./src",
|
|
57
|
-
"clean": "rimraf {dist,*.tsbuildinfo}",
|
|
58
|
-
"copyfiles": "copyfiles -u 1 \"src/**/*.{html,css,scss,ttf,woff,woff2,eot,svg,jpg,png,json}\" dist/",
|
|
59
|
-
"dev": "next dev dev --turbo",
|
|
60
|
-
"dev:generate-importmap": "pnpm dev:payload generate:importmap",
|
|
61
|
-
"dev:generate-types": "pnpm dev:payload generate:types",
|
|
62
|
-
"dev:payload": "cross-env PAYLOAD_CONFIG_PATH=./dev/payload.config.ts payload",
|
|
63
|
-
"generate:importmap": "pnpm dev:generate-importmap",
|
|
64
|
-
"generate:types": "pnpm dev:generate-types",
|
|
65
|
-
"lint": "eslint",
|
|
66
|
-
"lint:fix": "eslint ./src --fix",
|
|
67
|
-
"test": "pnpm test:int && pnpm test:e2e",
|
|
68
|
-
"test:e2e": "playwright test",
|
|
69
|
-
"test:int": "vitest"
|
|
70
|
-
},
|
|
71
53
|
"devDependencies": {
|
|
72
54
|
"@eslint/eslintrc": "^3.2.0",
|
|
73
55
|
"@payloadcms/db-mongodb": "3.84.1",
|
|
@@ -110,33 +92,23 @@
|
|
|
110
92
|
"node": "^18.20.2 || >=20.9.0",
|
|
111
93
|
"pnpm": "^9 || ^10"
|
|
112
94
|
},
|
|
113
|
-
"
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
},
|
|
134
|
-
"pnpm": {
|
|
135
|
-
"onlyBuiltDependencies": [
|
|
136
|
-
"sharp",
|
|
137
|
-
"esbuild",
|
|
138
|
-
"unrs-resolver"
|
|
139
|
-
]
|
|
140
|
-
},
|
|
141
|
-
"registry": "https://registry.npmjs.org/"
|
|
142
|
-
}
|
|
95
|
+
"registry": "https://registry.npmjs.org/",
|
|
96
|
+
"scripts": {
|
|
97
|
+
"build": "pnpm copyfiles && pnpm build:types && pnpm build:swc",
|
|
98
|
+
"build:swc": "swc ./src -d ./dist --config-file .swcrc --strip-leading-paths",
|
|
99
|
+
"build:types": "tsc --outDir dist --rootDir ./src",
|
|
100
|
+
"clean": "rimraf {dist,*.tsbuildinfo}",
|
|
101
|
+
"copyfiles": "copyfiles -u 1 \"src/**/*.{html,css,scss,ttf,woff,woff2,eot,svg,jpg,png,json}\" dist/",
|
|
102
|
+
"dev": "next dev dev --turbo",
|
|
103
|
+
"dev:generate-importmap": "pnpm dev:payload generate:importmap",
|
|
104
|
+
"dev:generate-types": "pnpm dev:payload generate:types",
|
|
105
|
+
"dev:payload": "cross-env PAYLOAD_CONFIG_PATH=./dev/payload.config.ts payload",
|
|
106
|
+
"generate:importmap": "pnpm dev:generate-importmap",
|
|
107
|
+
"generate:types": "pnpm dev:generate-types",
|
|
108
|
+
"lint": "eslint",
|
|
109
|
+
"lint:fix": "eslint ./src --fix",
|
|
110
|
+
"test": "pnpm test:int && pnpm test:e2e",
|
|
111
|
+
"test:e2e": "playwright test",
|
|
112
|
+
"test:int": "vitest"
|
|
113
|
+
}
|
|
114
|
+
}
|