@zealamic/payload-auth-rbac-plugin 1.0.0-beta.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.
Files changed (85) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +175 -0
  3. package/dist/collections/permission-actions/default-data.js +35 -0
  4. package/dist/collections/permission-actions/default-data.js.map +1 -0
  5. package/dist/collections/permission-actions/index.js +96 -0
  6. package/dist/collections/permission-actions/index.js.map +1 -0
  7. package/dist/collections/permission-actions/types.js +3 -0
  8. package/dist/collections/permission-actions/types.js.map +1 -0
  9. package/dist/collections/permission-features/default-data.js +29 -0
  10. package/dist/collections/permission-features/default-data.js.map +1 -0
  11. package/dist/collections/permission-features/index.js +82 -0
  12. package/dist/collections/permission-features/index.js.map +1 -0
  13. package/dist/collections/permission-features/types.js +3 -0
  14. package/dist/collections/permission-features/types.js.map +1 -0
  15. package/dist/collections/permissions/default-data.js +37 -0
  16. package/dist/collections/permissions/default-data.js.map +1 -0
  17. package/dist/collections/permissions/index.js +102 -0
  18. package/dist/collections/permissions/index.js.map +1 -0
  19. package/dist/collections/permissions/types.js +3 -0
  20. package/dist/collections/permissions/types.js.map +1 -0
  21. package/dist/collections/roles/default-data.js +44 -0
  22. package/dist/collections/roles/default-data.js.map +1 -0
  23. package/dist/collections/roles/hooks/sync-permission-matrix-draft.js +66 -0
  24. package/dist/collections/roles/hooks/sync-permission-matrix-draft.js.map +1 -0
  25. package/dist/collections/roles/index.js +122 -0
  26. package/dist/collections/roles/index.js.map +1 -0
  27. package/dist/collections/roles/types.js +3 -0
  28. package/dist/collections/roles/types.js.map +1 -0
  29. package/dist/collections/roles-permissions/default-data.js +27 -0
  30. package/dist/collections/roles-permissions/default-data.js.map +1 -0
  31. package/dist/collections/roles-permissions/index.js +75 -0
  32. package/dist/collections/roles-permissions/index.js.map +1 -0
  33. package/dist/collections/roles-permissions/types.js +3 -0
  34. package/dist/collections/roles-permissions/types.js.map +1 -0
  35. package/dist/collections/users/default-data.js +19 -0
  36. package/dist/collections/users/default-data.js.map +1 -0
  37. package/dist/collections/users/index.js +135 -0
  38. package/dist/collections/users/index.js.map +1 -0
  39. package/dist/collections/users/parent-path.js +210 -0
  40. package/dist/collections/users/parent-path.js.map +1 -0
  41. package/dist/collections/users/types.js +3 -0
  42. package/dist/collections/users/types.js.map +1 -0
  43. package/dist/components/role-permission-matrix-client/default-data.js +23 -0
  44. package/dist/components/role-permission-matrix-client/default-data.js.map +1 -0
  45. package/dist/components/role-permission-matrix-client/index.js +299 -0
  46. package/dist/components/role-permission-matrix-client/index.js.map +1 -0
  47. package/dist/components/role-permission-matrix-client/types.js +3 -0
  48. package/dist/components/role-permission-matrix-client/types.js.map +1 -0
  49. package/dist/endpoints/customEndpointHandler.js +7 -0
  50. package/dist/endpoints/customEndpointHandler.js.map +1 -0
  51. package/dist/exports/client.js +3 -0
  52. package/dist/exports/client.js.map +1 -0
  53. package/dist/exports/rsc.js +2 -0
  54. package/dist/exports/rsc.js.map +1 -0
  55. package/dist/general-types.d.js +2 -0
  56. package/dist/general-types.d.js.map +1 -0
  57. package/dist/index.js +184 -0
  58. package/dist/index.js.map +1 -0
  59. package/dist/lib/constants/general.js +3 -0
  60. package/dist/lib/constants/general.js.map +1 -0
  61. package/dist/lib/constants/index.js +16 -0
  62. package/dist/lib/constants/index.js.map +1 -0
  63. package/dist/lib/constants/permission-action.js +10 -0
  64. package/dist/lib/constants/permission-action.js.map +1 -0
  65. package/dist/lib/constants/permission-feature.js +6 -0
  66. package/dist/lib/constants/permission-feature.js.map +1 -0
  67. package/dist/lib/constants/permission.js +6 -0
  68. package/dist/lib/constants/permission.js.map +1 -0
  69. package/dist/lib/constants/role.js +11 -0
  70. package/dist/lib/constants/role.js.map +1 -0
  71. package/dist/lib/constants/user.js +3 -0
  72. package/dist/lib/constants/user.js.map +1 -0
  73. package/dist/lib/utils/access.js +452 -0
  74. package/dist/lib/utils/access.js.map +1 -0
  75. package/dist/lib/utils/data.js +7 -0
  76. package/dist/lib/utils/data.js.map +1 -0
  77. package/dist/lib/utils/fields.js +41 -0
  78. package/dist/lib/utils/fields.js.map +1 -0
  79. package/dist/lib/utils/index.js +6 -0
  80. package/dist/lib/utils/index.js.map +1 -0
  81. package/dist/lib/utils/localization.js +52 -0
  82. package/dist/lib/utils/localization.js.map +1 -0
  83. package/dist/types.js +10 -0
  84. package/dist/types.js.map +1 -0
  85. package/package.json +122 -0
@@ -0,0 +1,52 @@
1
+ /** Builds `{ [locale]: string }` from `getValue`, skipping empty values. */ export const toLocaleRecord = (locales, getValue)=>locales.reduce((acc, locale)=>{
2
+ const value = getValue(locale);
3
+ if (value) {
4
+ acc[locale] = value;
5
+ }
6
+ return acc;
7
+ }, {});
8
+ /**
9
+ * Select placeholder as per-locale strings (not `LabelFunction`) so it survives
10
+ * Next.js server → client serialization; Payload resolves it at render time.
11
+ */ export const toSelectPlaceholder = (locales, getValue)=>toLocaleRecord(locales, getValue);
12
+ const isPlainObject = (value)=>typeof value === "object" && value !== null && !Array.isArray(value);
13
+ /** Deep-merge translation trees; leaf overrides replace defaults. */ const mergeTranslationNodes = (defaultNode, overrideNode)=>{
14
+ if (isPlainObject(defaultNode) && isPlainObject(overrideNode)) {
15
+ const merged = {
16
+ ...defaultNode
17
+ };
18
+ for (const key of Object.keys(overrideNode)){
19
+ merged[key] = mergeTranslationNodes(defaultNode[key], overrideNode[key]);
20
+ }
21
+ return merged;
22
+ }
23
+ return overrideNode ?? defaultNode;
24
+ };
25
+ /** Plugin defaults merged with host `translations` overrides. */ export const getMergedTranslations = ({ defaultTranslations, translations })=>mergeTranslationNodes(defaultTranslations, translations);
26
+ /**
27
+ * Picks a nested branch from each locale, e.g. path `"collections.roles"`.
28
+ * Use `locales: "all"` or `["en", "vi"]`.
29
+ */ export const getAllTranslationsOfSpecificObject = ({ translations, path, locales = "all" })=>{
30
+ const segments = path.split(".");
31
+ const localeKeys = locales === "all" ? Object.keys(translations) : locales;
32
+ return localeKeys.reduce((acc, locale)=>{
33
+ const localeData = translations[locale];
34
+ if (!localeData) {
35
+ return acc;
36
+ }
37
+ let current = localeData;
38
+ for (const segment of segments){
39
+ if (typeof current !== "object" || current === null || !(segment in current)) {
40
+ current = undefined;
41
+ break;
42
+ }
43
+ current = current[segment];
44
+ }
45
+ if (current !== undefined) {
46
+ acc[locale] = current;
47
+ }
48
+ return acc;
49
+ }, {});
50
+ };
51
+
52
+ //# sourceMappingURL=localization.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/lib/utils/localization.ts"],"sourcesContent":["import type { SelectField } from \"payload\";\n\n/** Builds `{ [locale]: string }` from `getValue`, skipping empty values. */\nexport const toLocaleRecord = (\n locales: string[],\n getValue: (locale: string) => string | undefined,\n): Record<string, string> =>\n locales.reduce<Record<string, string>>((acc, locale) => {\n const value = getValue(locale);\n if (value) {\n acc[locale] = value;\n }\n return acc;\n }, {});\n\n/**\n * Select placeholder as per-locale strings (not `LabelFunction`) so it survives\n * Next.js server → client serialization; Payload resolves it at render time.\n */\nexport const toSelectPlaceholder = (\n locales: string[],\n getValue: (locale: string) => string | undefined,\n): NonNullable<SelectField[\"admin\"]>[\"placeholder\"] =>\n toLocaleRecord(locales, getValue) as unknown as NonNullable<\n SelectField[\"admin\"]\n >[\"placeholder\"];\n\ntype TranslationObject = {\n [key: string]: TranslationValue;\n};\n\ntype TranslationValue = TranslationObject | string | undefined;\n\nconst isPlainObject = (value: TranslationValue): value is TranslationObject =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\n/** Deep-merge translation trees; leaf overrides replace defaults. */\nconst mergeTranslationNodes = (\n defaultNode: TranslationValue,\n overrideNode: TranslationValue,\n): TranslationValue => {\n if (isPlainObject(defaultNode) && isPlainObject(overrideNode)) {\n const merged: TranslationObject = { ...defaultNode };\n\n for (const key of Object.keys(overrideNode)) {\n merged[key] = mergeTranslationNodes(defaultNode[key], overrideNode[key]);\n }\n\n return merged;\n }\n\n return overrideNode ?? defaultNode;\n};\n\n/** Plugin defaults merged with host `translations` overrides. */\nexport const getMergedTranslations = <\n T extends Record<string, TranslationValue>,\n>({\n defaultTranslations,\n translations,\n}: {\n defaultTranslations: T;\n translations: Partial<T>;\n}): T => mergeTranslationNodes(defaultTranslations, translations) as T;\n\n/**\n * Picks a nested branch from each locale, e.g. path `\"collections.roles\"`.\n * Use `locales: \"all\"` or `[\"en\", \"vi\"]`.\n */\nexport const getAllTranslationsOfSpecificObject = <T = unknown>({\n translations,\n path,\n locales = \"all\",\n}: {\n translations: Record<string, Record<string, unknown>>;\n path: string;\n locales?: \"all\" | string[];\n}): Record<string, T> => {\n const segments = path.split(\".\");\n const localeKeys = locales === \"all\" ? Object.keys(translations) : locales;\n\n return localeKeys.reduce<Record<string, T>>((acc, locale) => {\n const localeData = translations[locale];\n if (!localeData) {\n return acc;\n }\n\n let current: unknown = localeData;\n for (const segment of segments) {\n if (\n typeof current !== \"object\" ||\n current === null ||\n !(segment in current)\n ) {\n current = undefined;\n break;\n }\n current = (current as Record<string, unknown>)[segment];\n }\n\n if (current !== undefined) {\n acc[locale] = current as T;\n }\n return acc;\n }, {});\n};\n"],"names":["toLocaleRecord","locales","getValue","reduce","acc","locale","value","toSelectPlaceholder","isPlainObject","Array","isArray","mergeTranslationNodes","defaultNode","overrideNode","merged","key","Object","keys","getMergedTranslations","defaultTranslations","translations","getAllTranslationsOfSpecificObject","path","segments","split","localeKeys","localeData","current","segment","undefined"],"mappings":"AAEA,0EAA0E,GAC1E,OAAO,MAAMA,iBAAiB,CAC5BC,SACAC,WAEAD,QAAQE,MAAM,CAAyB,CAACC,KAAKC;QAC3C,MAAMC,QAAQJ,SAASG;QACvB,IAAIC,OAAO;YACTF,GAAG,CAACC,OAAO,GAAGC;QAChB;QACA,OAAOF;IACT,GAAG,CAAC,GAAG;AAET;;;CAGC,GACD,OAAO,MAAMG,sBAAsB,CACjCN,SACAC,WAEAF,eAAeC,SAASC,UAEP;AAQnB,MAAMM,gBAAgB,CAACF,QACrB,OAAOA,UAAU,YAAYA,UAAU,QAAQ,CAACG,MAAMC,OAAO,CAACJ;AAEhE,mEAAmE,GACnE,MAAMK,wBAAwB,CAC5BC,aACAC;IAEA,IAAIL,cAAcI,gBAAgBJ,cAAcK,eAAe;QAC7D,MAAMC,SAA4B;YAAE,GAAGF,WAAW;QAAC;QAEnD,KAAK,MAAMG,OAAOC,OAAOC,IAAI,CAACJ,cAAe;YAC3CC,MAAM,CAACC,IAAI,GAAGJ,sBAAsBC,WAAW,CAACG,IAAI,EAAEF,YAAY,CAACE,IAAI;QACzE;QAEA,OAAOD;IACT;IAEA,OAAOD,gBAAgBD;AACzB;AAEA,+DAA+D,GAC/D,OAAO,MAAMM,wBAAwB,CAEnC,EACAC,mBAAmB,EACnBC,YAAY,EAIb,GAAQT,sBAAsBQ,qBAAqBC,cAAmB;AAEvE;;;CAGC,GACD,OAAO,MAAMC,qCAAqC,CAAc,EAC9DD,YAAY,EACZE,IAAI,EACJrB,UAAU,KAAK,EAKhB;IACC,MAAMsB,WAAWD,KAAKE,KAAK,CAAC;IAC5B,MAAMC,aAAaxB,YAAY,QAAQe,OAAOC,IAAI,CAACG,gBAAgBnB;IAEnE,OAAOwB,WAAWtB,MAAM,CAAoB,CAACC,KAAKC;QAChD,MAAMqB,aAAaN,YAAY,CAACf,OAAO;QACvC,IAAI,CAACqB,YAAY;YACf,OAAOtB;QACT;QAEA,IAAIuB,UAAmBD;QACvB,KAAK,MAAME,WAAWL,SAAU;YAC9B,IACE,OAAOI,YAAY,YACnBA,YAAY,QACZ,CAAEC,CAAAA,WAAWD,OAAM,GACnB;gBACAA,UAAUE;gBACV;YACF;YACAF,UAAU,AAACA,OAAmC,CAACC,QAAQ;QACzD;QAEA,IAAID,YAAYE,WAAW;YACzBzB,GAAG,CAACC,OAAO,GAAGsB;QAChB;QACA,OAAOvB;IACT,GAAG,CAAC;AACN,EAAE"}
package/dist/types.js ADDED
@@ -0,0 +1,10 @@
1
+ // Collections types
2
+ export * from "./collections/permission-actions/types.js";
3
+ export * from "./collections/permission-features/types.js";
4
+ export * from "./collections/permissions/types.js";
5
+ export * from "./collections/roles/types.js";
6
+ export * from "./collections/roles-permissions/types.js";
7
+ export * from "./collections/users/types.js";
8
+ export * from "./components/role-permission-matrix-client/types.js";
9
+
10
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/types.ts"],"sourcesContent":["// Collections types\nimport type * as PermissionActionTypes from \"./collections/permission-actions/types.js\";\nimport type * as PermissionFeatureTypes from \"./collections/permission-features/types.js\";\nimport type * as PermissionTypes from \"./collections/permissions/types.js\";\nimport type * as RoleTypes from \"./collections/roles/types.js\";\nimport type * as RolePermissionTypes from \"./collections/roles-permissions/types.js\";\nimport type * as UsersTypes from \"./collections/users/types.js\";\n\n// Components types\nimport type * as RolePermissionMatrixClientTypes from \"./components/role-permission-matrix-client/types.js\";\n\nexport * from \"./collections/permission-actions/types.js\";\nexport * from \"./collections/permission-features/types.js\";\nexport * from \"./collections/permissions/types.js\";\nexport * from \"./collections/roles/types.js\";\nexport * from \"./collections/roles-permissions/types.js\";\nexport * from \"./collections/users/types.js\";\nexport * from \"./components/role-permission-matrix-client/types.js\";\n\nexport type RBACTranslations = {\n [locale: string]: {\n // Collections types\n collections?: {\n permissionActions?: PermissionActionTypes.PermissionActionsCollectionTranslations[string];\n permissionFeatures?: PermissionFeatureTypes.PermissionFeaturesCollectionTranslations[string];\n permissions?: PermissionTypes.PermissionsCollectionTranslations[string];\n roles?: RoleTypes.RolesCollectionTranslations[string];\n rolesPermissions?: RolePermissionTypes.RolesPermissionsCollectionTranslations[string];\n users?: UsersTypes.UsersModificationTranslations[string];\n };\n // Components types\n components?: {\n rolePermissionMatrix?: RolePermissionMatrixClientTypes.RolePermissionMatrixClientTranslations[string];\n };\n };\n};\n\nexport type PayloadAuthRbacPluginConfig = {\n /**\n * Collection slugs to augment (may include plugin-only collections absent from generated `CollectionSlug`).\n */\n collections?: Partial<\n Record<\n string,\n | Omit<\n PermissionActionTypes.PermissionActionsCollectionParams,\n \"translations\"\n >\n | Omit<\n PermissionFeatureTypes.PermissionFeaturesCollectionParams,\n \"translations\"\n >\n | Omit<PermissionTypes.PermissionsCollectionParams, \"translations\">\n | Omit<RoleTypes.RolesCollectionParams, \"translations\">\n | Omit<\n RolePermissionTypes.RolesPermissionsCollectionParams,\n \"translations\"\n >\n >\n >;\n disabled?: boolean;\n translations?: RBACTranslations;\n autoModifyUsersCollection?: boolean;\n};\n"],"names":[],"mappings":"AAAA,oBAAoB;AAWpB,cAAc,4CAA4C;AAC1D,cAAc,6CAA6C;AAC3D,cAAc,qCAAqC;AACnD,cAAc,+BAA+B;AAC7C,cAAc,2CAA2C;AACzD,cAAc,+BAA+B;AAC7C,cAAc,sDAAsD"}
package/package.json ADDED
@@ -0,0 +1,122 @@
1
+ {
2
+ "name": "@zealamic/payload-auth-rbac-plugin",
3
+ "version": "1.0.0-beta.1",
4
+ "description": "A plugin for Payload CMS to manage authentication and authorization",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "keywords": [
8
+ "payload",
9
+ "plugin",
10
+ "rbac",
11
+ "authentication",
12
+ "authorization"
13
+ ],
14
+ "exports": {
15
+ ".": {
16
+ "default": "./src/index.ts"
17
+ },
18
+ "./client": {
19
+ "default": "./src/exports/client.ts"
20
+ },
21
+ "./rsc": {
22
+ "default": "./src/exports/rsc.ts"
23
+ },
24
+ "./types": {
25
+ "default": "./src/types.ts"
26
+ },
27
+ "./utils": {
28
+ "default": "./src/lib/utils/index.ts"
29
+ }
30
+ },
31
+ "main": "./src/index.ts",
32
+ "types": "./src/general.d.ts",
33
+ "files": [
34
+ "dist",
35
+ "docs/cover-photo.jpg"
36
+ ],
37
+ "scripts": {
38
+ "build": "yarn copyfiles && yarn build:types && yarn build:swc",
39
+ "build:swc": "swc ./src -d ./dist --config-file .swcrc --strip-leading-paths",
40
+ "build:types": "tsc --outDir dist --rootDir ./src",
41
+ "clean": "rimraf {dist,*.tsbuildinfo}",
42
+ "copyfiles": "copyfiles -u 1 \"src/**/*.{html,css,scss,ttf,woff,woff2,eot,svg,jpg,png,json}\" dist/",
43
+ "dev": "next dev dev --turbo",
44
+ "dev:generate-importmap": "cross-env PAYLOAD_CONFIG_PATH=./dev/payload.config.ts TSX_TSCONFIG_PATH=./dev/tsconfig.json payload generate:importmap",
45
+ "dev:generate-types": "cross-env PAYLOAD_CONFIG_PATH=./dev/payload.config.ts TSX_TSCONFIG_PATH=./dev/tsconfig.json payload generate:types",
46
+ "dev:payload": "cross-env PAYLOAD_CONFIG_PATH=./dev/payload.config.ts TSX_TSCONFIG_PATH=./dev/tsconfig.json payload",
47
+ "generate:importmap": "yarn dev:generate-importmap",
48
+ "generate:types": "yarn dev:generate-types",
49
+ "lint": "biome check",
50
+ "lint:fix": "biome check --write",
51
+ "test": "yarn test:int && yarn test:e2e",
52
+ "test:e2e": "playwright test",
53
+ "test:int": "vitest"
54
+ },
55
+ "devDependencies": {
56
+ "@biomejs/biome": "2.4.15",
57
+ "@payloadcms/db-mongodb": "3.84.1",
58
+ "@payloadcms/db-postgres": "3.84.1",
59
+ "@payloadcms/db-sqlite": "3.84.1",
60
+ "@payloadcms/next": "3.84.1",
61
+ "@payloadcms/richtext-lexical": "3.84.1",
62
+ "@payloadcms/translations": "^3.84.1",
63
+ "@payloadcms/ui": "3.84.1",
64
+ "@playwright/test": "1.58.2",
65
+ "@swc-node/register": "1.10.9",
66
+ "@swc/cli": "0.6.0",
67
+ "@types/node": "22.19.9",
68
+ "@types/react": "19.2.14",
69
+ "@types/react-dom": "19.2.3",
70
+ "copyfiles": "2.4.1",
71
+ "cross-env": "^7.0.3",
72
+ "graphql": "^16.8.1",
73
+ "mongodb-memory-server": "10.1.4",
74
+ "next": "16.2.6",
75
+ "open": "^10.1.0",
76
+ "payload": "3.84.1",
77
+ "qs-esm": "8.0.1",
78
+ "react": "19.2.6",
79
+ "react-dom": "19.2.6",
80
+ "rimraf": "3.0.2",
81
+ "sharp": "0.34.2",
82
+ "sort-package-json": "^2.10.0",
83
+ "typescript": "5.7.3",
84
+ "vite-tsconfig-paths": "6.0.5",
85
+ "vitest": "4.0.18"
86
+ },
87
+ "peerDependencies": {
88
+ "payload": "^3.84.1"
89
+ },
90
+ "engines": {
91
+ "node": "^18.20.2 || >=20.9.0"
92
+ },
93
+ "publishConfig": {
94
+ "access": "public",
95
+ "main": "./dist/index.js",
96
+ "types": "./dist/index.d.ts",
97
+ "exports": {
98
+ ".": {
99
+ "types": "./dist/index.d.ts",
100
+ "default": "./dist/index.js"
101
+ },
102
+ "./client": {
103
+ "types": "./dist/exports/client.d.ts",
104
+ "default": "./dist/exports/client.js"
105
+ },
106
+ "./rsc": {
107
+ "types": "./dist/exports/rsc.d.ts",
108
+ "default": "./dist/exports/rsc.js"
109
+ },
110
+ "./types": {
111
+ "types": "./dist/types.d.ts",
112
+ "default": "./dist/types.js"
113
+ },
114
+ "./utils": {
115
+ "types": "./dist/lib/utils/index.d.ts",
116
+ "default": "./dist/lib/utils/index.js"
117
+ }
118
+ }
119
+ },
120
+ "registry": "https://registry.npmjs.org/",
121
+ "dependencies": {}
122
+ }