@webiny/app-admin 6.1.0 → 6.2.0-beta.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.
Files changed (126) hide show
  1. package/base/Admin.js +2 -0
  2. package/base/Admin.js.map +1 -1
  3. package/base/Base/DefaultFieldRenderers.d.ts +2 -0
  4. package/base/Base/DefaultFieldRenderers.js +15 -0
  5. package/base/Base/DefaultFieldRenderers.js.map +1 -0
  6. package/base/Base/FieldRenderers/SelectRenderer.d.ts +5 -0
  7. package/base/Base/FieldRenderers/SelectRenderer.js +24 -0
  8. package/base/Base/FieldRenderers/SelectRenderer.js.map +1 -0
  9. package/base/Base/FieldRenderers/TextRenderer.d.ts +5 -0
  10. package/base/Base/FieldRenderers/TextRenderer.js +21 -0
  11. package/base/Base/FieldRenderers/TextRenderer.js.map +1 -0
  12. package/base/Base/Menus.js +7 -0
  13. package/base/Base/Menus.js.map +1 -1
  14. package/base/Base.js +2 -1
  15. package/base/Base.js.map +1 -1
  16. package/base/createRootContainer.js +2 -0
  17. package/base/createRootContainer.js.map +1 -1
  18. package/components/Dialogs/DialogParamsContext.d.ts +6 -0
  19. package/components/Dialogs/DialogParamsContext.js +11 -0
  20. package/components/Dialogs/DialogParamsContext.js.map +1 -0
  21. package/components/Dialogs/DialogsContext.d.ts +2 -0
  22. package/components/Dialogs/DialogsContext.js +32 -4
  23. package/components/Dialogs/DialogsContext.js.map +1 -1
  24. package/components/OptionsMenu/OptionsMenu.d.ts +6 -0
  25. package/components/OptionsMenu/OptionsMenu.js +3 -3
  26. package/components/OptionsMenu/OptionsMenu.js.map +1 -1
  27. package/components/RegisterFeature.js +5 -5
  28. package/components/RegisterFeature.js.map +1 -1
  29. package/components/Wcp.d.ts +2 -0
  30. package/components/Wcp.js +7 -0
  31. package/components/Wcp.js.map +1 -1
  32. package/config/AdminConfig/Dialog.d.ts +10 -0
  33. package/config/AdminConfig/Dialog.js +21 -0
  34. package/config/AdminConfig/Dialog.js.map +1 -0
  35. package/config/AdminConfig/FieldRenderer.d.ts +11 -0
  36. package/config/AdminConfig/FieldRenderer.js +21 -0
  37. package/config/AdminConfig/FieldRenderer.js.map +1 -0
  38. package/config/AdminConfig/Form.d.ts +3 -0
  39. package/config/AdminConfig/Form.js +6 -0
  40. package/config/AdminConfig/Form.js.map +1 -0
  41. package/config/AdminConfig.d.ts +10 -0
  42. package/config/AdminConfig.js +7 -1
  43. package/config/AdminConfig.js.map +1 -1
  44. package/exports/admin/security.d.ts +6 -0
  45. package/exports/admin/security.js +5 -0
  46. package/exports/admin/security.js.map +1 -1
  47. package/exports/admin/ui.d.ts +2 -0
  48. package/exports/admin/ui.js +2 -0
  49. package/exports/admin/ui.js.map +1 -1
  50. package/exports/admin.d.ts +0 -3
  51. package/exports/admin.js +0 -3
  52. package/exports/admin.js.map +1 -1
  53. package/features/formModel/Field.d.ts +52 -0
  54. package/features/formModel/Field.js +201 -0
  55. package/features/formModel/Field.js.map +1 -0
  56. package/features/formModel/FieldBuilder.d.ts +45 -0
  57. package/features/formModel/FieldBuilder.js +158 -0
  58. package/features/formModel/FieldBuilder.js.map +1 -0
  59. package/features/formModel/FieldBuilder.test.js +106 -0
  60. package/features/formModel/FieldBuilder.test.js.map +1 -0
  61. package/features/formModel/FormModel.d.ts +61 -0
  62. package/features/formModel/FormModel.js +573 -0
  63. package/features/formModel/FormModel.js.map +1 -0
  64. package/features/formModel/FormModel.test.d.ts +1 -0
  65. package/features/formModel/FormModel.test.js +1140 -0
  66. package/features/formModel/FormModel.test.js.map +1 -0
  67. package/features/formModel/FormModelFactory.d.ts +9 -0
  68. package/features/formModel/FormModelFactory.js +13 -0
  69. package/features/formModel/FormModelFactory.js.map +1 -0
  70. package/features/formModel/FormView.d.ts +23 -0
  71. package/features/formModel/FormView.js +138 -0
  72. package/features/formModel/FormView.js.map +1 -0
  73. package/features/formModel/abstractions.d.ts +286 -0
  74. package/features/formModel/abstractions.js +54 -0
  75. package/features/formModel/abstractions.js.map +1 -0
  76. package/features/formModel/feature.d.ts +3 -0
  77. package/features/formModel/feature.js +16 -0
  78. package/features/formModel/feature.js.map +1 -0
  79. package/features/formModel/index.d.ts +10 -0
  80. package/features/formModel/index.js +14 -0
  81. package/features/formModel/index.js.map +1 -0
  82. package/features/formModel/useFieldRenderers.d.ts +2 -0
  83. package/features/formModel/useFieldRenderers.js +19 -0
  84. package/features/formModel/useFieldRenderers.js.map +1 -0
  85. package/features/security/LogIn/LogInGateway.d.ts +2 -2
  86. package/features/security/LogIn/LogInGateway.js +2 -2
  87. package/features/security/LogIn/LogInGateway.js.map +1 -1
  88. package/features/wcp/WcpGateway.d.ts +2 -2
  89. package/features/wcp/WcpGateway.js +2 -2
  90. package/features/wcp/WcpGateway.js.map +1 -1
  91. package/hooks/index.d.ts +1 -0
  92. package/hooks/index.js +1 -0
  93. package/hooks/index.js.map +1 -1
  94. package/hooks/useDialog.d.ts +9 -29
  95. package/hooks/useDialog.js +16 -24
  96. package/hooks/useDialog.js.map +1 -1
  97. package/hooks/useOpenDialog.d.ts +7 -0
  98. package/hooks/useOpenDialog.js +18 -0
  99. package/hooks/useOpenDialog.js.map +1 -0
  100. package/index.d.ts +5 -0
  101. package/index.js +5 -0
  102. package/index.js.map +1 -1
  103. package/package.json +30 -30
  104. package/permissions/createHasPermission.d.ts +3 -2
  105. package/permissions/createHasPermission.js +4 -8
  106. package/permissions/createHasPermission.js.map +1 -1
  107. package/permissions/createPermissions.d.ts +6 -0
  108. package/permissions/createPermissions.js +201 -0
  109. package/permissions/createPermissions.js.map +1 -0
  110. package/permissions/createPermissions.test.d.ts +1 -0
  111. package/permissions/createPermissions.test.js +177 -0
  112. package/permissions/createPermissions.test.js.map +1 -0
  113. package/permissions/index.d.ts +1 -0
  114. package/permissions/index.js +1 -0
  115. package/permissions/index.js.map +1 -1
  116. package/permissions/types.d.ts +5 -0
  117. package/permissions/types.js.map +1 -1
  118. package/permissions/usePermissions.d.ts +2 -1
  119. package/permissions/usePermissions.js +4 -175
  120. package/permissions/usePermissions.js.map +1 -1
  121. package/presentation/installation/presenters/SystemInstaller/SystemInstallerGateway.d.ts +2 -2
  122. package/presentation/installation/presenters/SystemInstaller/SystemInstallerGateway.js +2 -2
  123. package/presentation/installation/presenters/SystemInstaller/SystemInstallerGateway.js.map +1 -1
  124. package/permissions/createHasPermission.test.js +0 -206
  125. package/permissions/createHasPermission.test.js.map +0 -1
  126. /package/{permissions/createHasPermission.test.d.ts → features/formModel/FieldBuilder.test.d.ts} +0 -0
@@ -0,0 +1,177 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { Container } from "@webiny/di";
3
+ import { createPermissionsAbstraction, createPermissionsFeature } from "./createPermissions.js";
4
+ import { createPermissionSchema } from "./createPermissionSchema.js";
5
+ import { IdentityContext } from "../features/security/IdentityContext/abstractions.js";
6
+ import { IdentityContext as IdentityContextImpl } from "../features/security/IdentityContext/IdentityContext.js";
7
+ import { Identity } from "../domain/Identity.js";
8
+ const TEST_SCHEMA = createPermissionSchema({
9
+ prefix: "test",
10
+ fullAccess: true,
11
+ entities: [{
12
+ id: "page",
13
+ title: "Page",
14
+ permission: "test.page",
15
+ scopes: ["full", "own"],
16
+ actions: [{
17
+ name: "rwd"
18
+ }, {
19
+ name: "pw"
20
+ }]
21
+ }]
22
+ });
23
+ const TestPermissions = createPermissionsAbstraction(TEST_SCHEMA);
24
+ const TestPermissionsFeature = createPermissionsFeature(TEST_SCHEMA, TestPermissions);
25
+ function resolve(permissions) {
26
+ const container = new Container();
27
+ container.register(IdentityContextImpl).inSingletonScope();
28
+ TestPermissionsFeature.register(container);
29
+ const identityContext = container.resolve(IdentityContext);
30
+ identityContext.setIdentity(Identity.createAuthenticated({
31
+ id: "test-user",
32
+ displayName: "Test User",
33
+ type: "admin",
34
+ roles: [],
35
+ teams: [],
36
+ permissions,
37
+ profile: {
38
+ external: false
39
+ },
40
+ currentTenant: {
41
+ id: "root",
42
+ name: "Root"
43
+ },
44
+ defaultTenant: {
45
+ id: "root",
46
+ name: "Root"
47
+ }
48
+ }));
49
+ return container.resolve(TestPermissions);
50
+ }
51
+ describe("SchemaPermissions", () => {
52
+ describe("full access", () => {
53
+ it("grants everything with unrestricted wildcard", () => {
54
+ const p = resolve([{
55
+ name: "test.*"
56
+ }]);
57
+ expect(p.canAccess("page")).toBe(true);
58
+ expect(p.canRead("page")).toBe(true);
59
+ expect(p.canCreate("page")).toBe(true);
60
+ expect(p.canEdit("page")).toBe(true);
61
+ expect(p.canDelete("page")).toBe(true);
62
+ expect(p.canPublish("page")).toBe(true);
63
+ expect(p.canUnpublish("page")).toBe(true);
64
+ });
65
+ it("rejects wildcard with rwd restriction as non-full access", () => {
66
+ const p = resolve([{
67
+ name: "test.*",
68
+ rwd: "r"
69
+ }]);
70
+ expect(p.canCreate("page")).toBe(false);
71
+ expect(p.canDelete("page")).toBe(false);
72
+ });
73
+ });
74
+ describe("entity-level access", () => {
75
+ it("grants access when entity permission exists", () => {
76
+ const p = resolve([{
77
+ name: "test.page"
78
+ }]);
79
+ expect(p.canAccess("page")).toBe(true);
80
+ });
81
+ it("denies access when no permission exists", () => {
82
+ const p = resolve([]);
83
+ expect(p.canAccess("page")).toBe(false);
84
+ });
85
+ });
86
+ describe("rwd actions", () => {
87
+ it("respects read permission", () => {
88
+ const p = resolve([{
89
+ name: "test.page",
90
+ rwd: "r"
91
+ }]);
92
+ expect(p.canRead("page")).toBe(true);
93
+ expect(p.canCreate("page")).toBe(false);
94
+ expect(p.canDelete("page")).toBe(false);
95
+ });
96
+ it("respects write permission", () => {
97
+ const p = resolve([{
98
+ name: "test.page",
99
+ rwd: "rw"
100
+ }]);
101
+ expect(p.canRead("page")).toBe(true);
102
+ expect(p.canCreate("page")).toBe(true);
103
+ expect(p.canEdit("page")).toBe(true);
104
+ expect(p.canDelete("page")).toBe(false);
105
+ });
106
+ it("respects delete permission", () => {
107
+ const p = resolve([{
108
+ name: "test.page",
109
+ rwd: "d"
110
+ }]);
111
+ expect(p.canDelete("page")).toBe(true);
112
+ expect(p.canRead("page")).toBe(false);
113
+ });
114
+ });
115
+ describe("publish/unpublish actions", () => {
116
+ it("grants publish when pw includes p", () => {
117
+ const p = resolve([{
118
+ name: "test.page",
119
+ pw: "p"
120
+ }]);
121
+ expect(p.canPublish("page")).toBe(true);
122
+ expect(p.canUnpublish("page")).toBe(false);
123
+ });
124
+ it("grants both when pw includes pu", () => {
125
+ const p = resolve([{
126
+ name: "test.page",
127
+ pw: "pu"
128
+ }]);
129
+ expect(p.canPublish("page")).toBe(true);
130
+ expect(p.canUnpublish("page")).toBe(true);
131
+ });
132
+ });
133
+ describe("own scope", () => {
134
+ it("allows edit when item is owned by the user", () => {
135
+ const p = resolve([{
136
+ name: "test.page",
137
+ own: true
138
+ }]);
139
+ expect(p.canEdit("page", {
140
+ createdBy: {
141
+ id: "test-user"
142
+ }
143
+ })).toBe(true);
144
+ });
145
+ it("denies edit when item is owned by someone else", () => {
146
+ const p = resolve([{
147
+ name: "test.page",
148
+ own: true
149
+ }]);
150
+ expect(p.canEdit("page", {
151
+ createdBy: {
152
+ id: "other-user"
153
+ }
154
+ })).toBe(false);
155
+ });
156
+ it("allows edit when no item is provided (optimistic)", () => {
157
+ const p = resolve([{
158
+ name: "test.page",
159
+ own: true
160
+ }]);
161
+ expect(p.canEdit("page")).toBe(true);
162
+ });
163
+ it("denies delete when item is owned by someone else", () => {
164
+ const p = resolve([{
165
+ name: "test.page",
166
+ own: true
167
+ }]);
168
+ expect(p.canDelete("page", {
169
+ createdBy: {
170
+ id: "other-user"
171
+ }
172
+ })).toBe(false);
173
+ });
174
+ });
175
+ });
176
+
177
+ //# sourceMappingURL=createPermissions.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["describe","it","expect","Container","createPermissionsAbstraction","createPermissionsFeature","createPermissionSchema","IdentityContext","IdentityContextImpl","Identity","TEST_SCHEMA","prefix","fullAccess","entities","id","title","permission","scopes","actions","name","TestPermissions","TestPermissionsFeature","resolve","permissions","container","register","inSingletonScope","identityContext","setIdentity","createAuthenticated","displayName","type","roles","teams","profile","external","currentTenant","defaultTenant","p","canAccess","toBe","canRead","canCreate","canEdit","canDelete","canPublish","canUnpublish","rwd","pw","own","createdBy"],"sources":["createPermissions.test.ts"],"sourcesContent":["import { describe, it, expect } from \"vitest\";\nimport { Container } from \"@webiny/di\";\nimport { createPermissionsAbstraction, createPermissionsFeature } from \"./createPermissions.js\";\nimport { createPermissionSchema } from \"./createPermissionSchema.js\";\nimport { IdentityContext } from \"~/features/security/IdentityContext/abstractions.js\";\nimport { IdentityContext as IdentityContextImpl } from \"~/features/security/IdentityContext/IdentityContext.js\";\nimport { Identity } from \"~/domain/Identity.js\";\n\nconst TEST_SCHEMA = createPermissionSchema({\n prefix: \"test\",\n fullAccess: true,\n entities: [\n {\n id: \"page\",\n title: \"Page\",\n permission: \"test.page\",\n scopes: [\"full\", \"own\"],\n actions: [{ name: \"rwd\" }, { name: \"pw\" }]\n }\n ]\n} as const);\n\nconst TestPermissions = createPermissionsAbstraction(TEST_SCHEMA);\nconst TestPermissionsFeature = createPermissionsFeature(TEST_SCHEMA, TestPermissions);\n\nfunction resolve(permissions: Array<{ name: string; [key: string]: any }>) {\n const container = new Container();\n container.register(IdentityContextImpl).inSingletonScope();\n TestPermissionsFeature.register(container);\n\n const identityContext = container.resolve(IdentityContext);\n identityContext.setIdentity(\n Identity.createAuthenticated({\n id: \"test-user\",\n displayName: \"Test User\",\n type: \"admin\",\n roles: [],\n teams: [],\n permissions,\n profile: { external: false },\n currentTenant: { id: \"root\", name: \"Root\" },\n defaultTenant: { id: \"root\", name: \"Root\" }\n })\n );\n\n return container.resolve(TestPermissions);\n}\n\ndescribe(\"SchemaPermissions\", () => {\n describe(\"full access\", () => {\n it(\"grants everything with unrestricted wildcard\", () => {\n const p = resolve([{ name: \"test.*\" }]);\n expect(p.canAccess(\"page\")).toBe(true);\n expect(p.canRead(\"page\")).toBe(true);\n expect(p.canCreate(\"page\")).toBe(true);\n expect(p.canEdit(\"page\")).toBe(true);\n expect(p.canDelete(\"page\")).toBe(true);\n expect(p.canPublish(\"page\")).toBe(true);\n expect(p.canUnpublish(\"page\")).toBe(true);\n });\n\n it(\"rejects wildcard with rwd restriction as non-full access\", () => {\n const p = resolve([{ name: \"test.*\", rwd: \"r\" }]);\n expect(p.canCreate(\"page\")).toBe(false);\n expect(p.canDelete(\"page\")).toBe(false);\n });\n });\n\n describe(\"entity-level access\", () => {\n it(\"grants access when entity permission exists\", () => {\n const p = resolve([{ name: \"test.page\" }]);\n expect(p.canAccess(\"page\")).toBe(true);\n });\n\n it(\"denies access when no permission exists\", () => {\n const p = resolve([]);\n expect(p.canAccess(\"page\")).toBe(false);\n });\n });\n\n describe(\"rwd actions\", () => {\n it(\"respects read permission\", () => {\n const p = resolve([{ name: \"test.page\", rwd: \"r\" }]);\n expect(p.canRead(\"page\")).toBe(true);\n expect(p.canCreate(\"page\")).toBe(false);\n expect(p.canDelete(\"page\")).toBe(false);\n });\n\n it(\"respects write permission\", () => {\n const p = resolve([{ name: \"test.page\", rwd: \"rw\" }]);\n expect(p.canRead(\"page\")).toBe(true);\n expect(p.canCreate(\"page\")).toBe(true);\n expect(p.canEdit(\"page\")).toBe(true);\n expect(p.canDelete(\"page\")).toBe(false);\n });\n\n it(\"respects delete permission\", () => {\n const p = resolve([{ name: \"test.page\", rwd: \"d\" }]);\n expect(p.canDelete(\"page\")).toBe(true);\n expect(p.canRead(\"page\")).toBe(false);\n });\n });\n\n describe(\"publish/unpublish actions\", () => {\n it(\"grants publish when pw includes p\", () => {\n const p = resolve([{ name: \"test.page\", pw: \"p\" }]);\n expect(p.canPublish(\"page\")).toBe(true);\n expect(p.canUnpublish(\"page\")).toBe(false);\n });\n\n it(\"grants both when pw includes pu\", () => {\n const p = resolve([{ name: \"test.page\", pw: \"pu\" }]);\n expect(p.canPublish(\"page\")).toBe(true);\n expect(p.canUnpublish(\"page\")).toBe(true);\n });\n });\n\n describe(\"own scope\", () => {\n it(\"allows edit when item is owned by the user\", () => {\n const p = resolve([{ name: \"test.page\", own: true }]);\n expect(p.canEdit(\"page\", { createdBy: { id: \"test-user\" } })).toBe(true);\n });\n\n it(\"denies edit when item is owned by someone else\", () => {\n const p = resolve([{ name: \"test.page\", own: true }]);\n expect(p.canEdit(\"page\", { createdBy: { id: \"other-user\" } })).toBe(false);\n });\n\n it(\"allows edit when no item is provided (optimistic)\", () => {\n const p = resolve([{ name: \"test.page\", own: true }]);\n expect(p.canEdit(\"page\")).toBe(true);\n });\n\n it(\"denies delete when item is owned by someone else\", () => {\n const p = resolve([{ name: \"test.page\", own: true }]);\n expect(p.canDelete(\"page\", { createdBy: { id: \"other-user\" } })).toBe(false);\n });\n });\n});\n"],"mappings":"AAAA,SAASA,QAAQ,EAAEC,EAAE,EAAEC,MAAM,QAAQ,QAAQ;AAC7C,SAASC,SAAS,QAAQ,YAAY;AACtC,SAASC,4BAA4B,EAAEC,wBAAwB;AAC/D,SAASC,sBAAsB;AAC/B,SAASC,eAAe;AACxB,SAASA,eAAe,IAAIC,mBAAmB;AAC/C,SAASC,QAAQ;AAEjB,MAAMC,WAAW,GAAGJ,sBAAsB,CAAC;EACvCK,MAAM,EAAE,MAAM;EACdC,UAAU,EAAE,IAAI;EAChBC,QAAQ,EAAE,CACN;IACIC,EAAE,EAAE,MAAM;IACVC,KAAK,EAAE,MAAM;IACbC,UAAU,EAAE,WAAW;IACvBC,MAAM,EAAE,CAAC,MAAM,EAAE,KAAK,CAAC;IACvBC,OAAO,EAAE,CAAC;MAAEC,IAAI,EAAE;IAAM,CAAC,EAAE;MAAEA,IAAI,EAAE;IAAK,CAAC;EAC7C,CAAC;AAET,CAAU,CAAC;AAEX,MAAMC,eAAe,GAAGhB,4BAA4B,CAACM,WAAW,CAAC;AACjE,MAAMW,sBAAsB,GAAGhB,wBAAwB,CAACK,WAAW,EAAEU,eAAe,CAAC;AAErF,SAASE,OAAOA,CAACC,WAAwD,EAAE;EACvE,MAAMC,SAAS,GAAG,IAAIrB,SAAS,CAAC,CAAC;EACjCqB,SAAS,CAACC,QAAQ,CAACjB,mBAAmB,CAAC,CAACkB,gBAAgB,CAAC,CAAC;EAC1DL,sBAAsB,CAACI,QAAQ,CAACD,SAAS,CAAC;EAE1C,MAAMG,eAAe,GAAGH,SAAS,CAACF,OAAO,CAACf,eAAe,CAAC;EAC1DoB,eAAe,CAACC,WAAW,CACvBnB,QAAQ,CAACoB,mBAAmB,CAAC;IACzBf,EAAE,EAAE,WAAW;IACfgB,WAAW,EAAE,WAAW;IACxBC,IAAI,EAAE,OAAO;IACbC,KAAK,EAAE,EAAE;IACTC,KAAK,EAAE,EAAE;IACTV,WAAW;IACXW,OAAO,EAAE;MAAEC,QAAQ,EAAE;IAAM,CAAC;IAC5BC,aAAa,EAAE;MAAEtB,EAAE,EAAE,MAAM;MAAEK,IAAI,EAAE;IAAO,CAAC;IAC3CkB,aAAa,EAAE;MAAEvB,EAAE,EAAE,MAAM;MAAEK,IAAI,EAAE;IAAO;EAC9C,CAAC,CACL,CAAC;EAED,OAAOK,SAAS,CAACF,OAAO,CAACF,eAAe,CAAC;AAC7C;AAEApB,QAAQ,CAAC,mBAAmB,EAAE,MAAM;EAChCA,QAAQ,CAAC,aAAa,EAAE,MAAM;IAC1BC,EAAE,CAAC,8CAA8C,EAAE,MAAM;MACrD,MAAMqC,CAAC,GAAGhB,OAAO,CAAC,CAAC;QAAEH,IAAI,EAAE;MAAS,CAAC,CAAC,CAAC;MACvCjB,MAAM,CAACoC,CAAC,CAACC,SAAS,CAAC,MAAM,CAAC,CAAC,CAACC,IAAI,CAAC,IAAI,CAAC;MACtCtC,MAAM,CAACoC,CAAC,CAACG,OAAO,CAAC,MAAM,CAAC,CAAC,CAACD,IAAI,CAAC,IAAI,CAAC;MACpCtC,MAAM,CAACoC,CAAC,CAACI,SAAS,CAAC,MAAM,CAAC,CAAC,CAACF,IAAI,CAAC,IAAI,CAAC;MACtCtC,MAAM,CAACoC,CAAC,CAACK,OAAO,CAAC,MAAM,CAAC,CAAC,CAACH,IAAI,CAAC,IAAI,CAAC;MACpCtC,MAAM,CAACoC,CAAC,CAACM,SAAS,CAAC,MAAM,CAAC,CAAC,CAACJ,IAAI,CAAC,IAAI,CAAC;MACtCtC,MAAM,CAACoC,CAAC,CAACO,UAAU,CAAC,MAAM,CAAC,CAAC,CAACL,IAAI,CAAC,IAAI,CAAC;MACvCtC,MAAM,CAACoC,CAAC,CAACQ,YAAY,CAAC,MAAM,CAAC,CAAC,CAACN,IAAI,CAAC,IAAI,CAAC;IAC7C,CAAC,CAAC;IAEFvC,EAAE,CAAC,0DAA0D,EAAE,MAAM;MACjE,MAAMqC,CAAC,GAAGhB,OAAO,CAAC,CAAC;QAAEH,IAAI,EAAE,QAAQ;QAAE4B,GAAG,EAAE;MAAI,CAAC,CAAC,CAAC;MACjD7C,MAAM,CAACoC,CAAC,CAACI,SAAS,CAAC,MAAM,CAAC,CAAC,CAACF,IAAI,CAAC,KAAK,CAAC;MACvCtC,MAAM,CAACoC,CAAC,CAACM,SAAS,CAAC,MAAM,CAAC,CAAC,CAACJ,IAAI,CAAC,KAAK,CAAC;IAC3C,CAAC,CAAC;EACN,CAAC,CAAC;EAEFxC,QAAQ,CAAC,qBAAqB,EAAE,MAAM;IAClCC,EAAE,CAAC,6CAA6C,EAAE,MAAM;MACpD,MAAMqC,CAAC,GAAGhB,OAAO,CAAC,CAAC;QAAEH,IAAI,EAAE;MAAY,CAAC,CAAC,CAAC;MAC1CjB,MAAM,CAACoC,CAAC,CAACC,SAAS,CAAC,MAAM,CAAC,CAAC,CAACC,IAAI,CAAC,IAAI,CAAC;IAC1C,CAAC,CAAC;IAEFvC,EAAE,CAAC,yCAAyC,EAAE,MAAM;MAChD,MAAMqC,CAAC,GAAGhB,OAAO,CAAC,EAAE,CAAC;MACrBpB,MAAM,CAACoC,CAAC,CAACC,SAAS,CAAC,MAAM,CAAC,CAAC,CAACC,IAAI,CAAC,KAAK,CAAC;IAC3C,CAAC,CAAC;EACN,CAAC,CAAC;EAEFxC,QAAQ,CAAC,aAAa,EAAE,MAAM;IAC1BC,EAAE,CAAC,0BAA0B,EAAE,MAAM;MACjC,MAAMqC,CAAC,GAAGhB,OAAO,CAAC,CAAC;QAAEH,IAAI,EAAE,WAAW;QAAE4B,GAAG,EAAE;MAAI,CAAC,CAAC,CAAC;MACpD7C,MAAM,CAACoC,CAAC,CAACG,OAAO,CAAC,MAAM,CAAC,CAAC,CAACD,IAAI,CAAC,IAAI,CAAC;MACpCtC,MAAM,CAACoC,CAAC,CAACI,SAAS,CAAC,MAAM,CAAC,CAAC,CAACF,IAAI,CAAC,KAAK,CAAC;MACvCtC,MAAM,CAACoC,CAAC,CAACM,SAAS,CAAC,MAAM,CAAC,CAAC,CAACJ,IAAI,CAAC,KAAK,CAAC;IAC3C,CAAC,CAAC;IAEFvC,EAAE,CAAC,2BAA2B,EAAE,MAAM;MAClC,MAAMqC,CAAC,GAAGhB,OAAO,CAAC,CAAC;QAAEH,IAAI,EAAE,WAAW;QAAE4B,GAAG,EAAE;MAAK,CAAC,CAAC,CAAC;MACrD7C,MAAM,CAACoC,CAAC,CAACG,OAAO,CAAC,MAAM,CAAC,CAAC,CAACD,IAAI,CAAC,IAAI,CAAC;MACpCtC,MAAM,CAACoC,CAAC,CAACI,SAAS,CAAC,MAAM,CAAC,CAAC,CAACF,IAAI,CAAC,IAAI,CAAC;MACtCtC,MAAM,CAACoC,CAAC,CAACK,OAAO,CAAC,MAAM,CAAC,CAAC,CAACH,IAAI,CAAC,IAAI,CAAC;MACpCtC,MAAM,CAACoC,CAAC,CAACM,SAAS,CAAC,MAAM,CAAC,CAAC,CAACJ,IAAI,CAAC,KAAK,CAAC;IAC3C,CAAC,CAAC;IAEFvC,EAAE,CAAC,4BAA4B,EAAE,MAAM;MACnC,MAAMqC,CAAC,GAAGhB,OAAO,CAAC,CAAC;QAAEH,IAAI,EAAE,WAAW;QAAE4B,GAAG,EAAE;MAAI,CAAC,CAAC,CAAC;MACpD7C,MAAM,CAACoC,CAAC,CAACM,SAAS,CAAC,MAAM,CAAC,CAAC,CAACJ,IAAI,CAAC,IAAI,CAAC;MACtCtC,MAAM,CAACoC,CAAC,CAACG,OAAO,CAAC,MAAM,CAAC,CAAC,CAACD,IAAI,CAAC,KAAK,CAAC;IACzC,CAAC,CAAC;EACN,CAAC,CAAC;EAEFxC,QAAQ,CAAC,2BAA2B,EAAE,MAAM;IACxCC,EAAE,CAAC,mCAAmC,EAAE,MAAM;MAC1C,MAAMqC,CAAC,GAAGhB,OAAO,CAAC,CAAC;QAAEH,IAAI,EAAE,WAAW;QAAE6B,EAAE,EAAE;MAAI,CAAC,CAAC,CAAC;MACnD9C,MAAM,CAACoC,CAAC,CAACO,UAAU,CAAC,MAAM,CAAC,CAAC,CAACL,IAAI,CAAC,IAAI,CAAC;MACvCtC,MAAM,CAACoC,CAAC,CAACQ,YAAY,CAAC,MAAM,CAAC,CAAC,CAACN,IAAI,CAAC,KAAK,CAAC;IAC9C,CAAC,CAAC;IAEFvC,EAAE,CAAC,iCAAiC,EAAE,MAAM;MACxC,MAAMqC,CAAC,GAAGhB,OAAO,CAAC,CAAC;QAAEH,IAAI,EAAE,WAAW;QAAE6B,EAAE,EAAE;MAAK,CAAC,CAAC,CAAC;MACpD9C,MAAM,CAACoC,CAAC,CAACO,UAAU,CAAC,MAAM,CAAC,CAAC,CAACL,IAAI,CAAC,IAAI,CAAC;MACvCtC,MAAM,CAACoC,CAAC,CAACQ,YAAY,CAAC,MAAM,CAAC,CAAC,CAACN,IAAI,CAAC,IAAI,CAAC;IAC7C,CAAC,CAAC;EACN,CAAC,CAAC;EAEFxC,QAAQ,CAAC,WAAW,EAAE,MAAM;IACxBC,EAAE,CAAC,4CAA4C,EAAE,MAAM;MACnD,MAAMqC,CAAC,GAAGhB,OAAO,CAAC,CAAC;QAAEH,IAAI,EAAE,WAAW;QAAE8B,GAAG,EAAE;MAAK,CAAC,CAAC,CAAC;MACrD/C,MAAM,CAACoC,CAAC,CAACK,OAAO,CAAC,MAAM,EAAE;QAAEO,SAAS,EAAE;UAAEpC,EAAE,EAAE;QAAY;MAAE,CAAC,CAAC,CAAC,CAAC0B,IAAI,CAAC,IAAI,CAAC;IAC5E,CAAC,CAAC;IAEFvC,EAAE,CAAC,gDAAgD,EAAE,MAAM;MACvD,MAAMqC,CAAC,GAAGhB,OAAO,CAAC,CAAC;QAAEH,IAAI,EAAE,WAAW;QAAE8B,GAAG,EAAE;MAAK,CAAC,CAAC,CAAC;MACrD/C,MAAM,CAACoC,CAAC,CAACK,OAAO,CAAC,MAAM,EAAE;QAAEO,SAAS,EAAE;UAAEpC,EAAE,EAAE;QAAa;MAAE,CAAC,CAAC,CAAC,CAAC0B,IAAI,CAAC,KAAK,CAAC;IAC9E,CAAC,CAAC;IAEFvC,EAAE,CAAC,mDAAmD,EAAE,MAAM;MAC1D,MAAMqC,CAAC,GAAGhB,OAAO,CAAC,CAAC;QAAEH,IAAI,EAAE,WAAW;QAAE8B,GAAG,EAAE;MAAK,CAAC,CAAC,CAAC;MACrD/C,MAAM,CAACoC,CAAC,CAACK,OAAO,CAAC,MAAM,CAAC,CAAC,CAACH,IAAI,CAAC,IAAI,CAAC;IACxC,CAAC,CAAC;IAEFvC,EAAE,CAAC,kDAAkD,EAAE,MAAM;MACzD,MAAMqC,CAAC,GAAGhB,OAAO,CAAC,CAAC;QAAEH,IAAI,EAAE,WAAW;QAAE8B,GAAG,EAAE;MAAK,CAAC,CAAC,CAAC;MACrD/C,MAAM,CAACoC,CAAC,CAACM,SAAS,CAAC,MAAM,EAAE;QAAEM,SAAS,EAAE;UAAEpC,EAAE,EAAE;QAAa;MAAE,CAAC,CAAC,CAAC,CAAC0B,IAAI,CAAC,KAAK,CAAC;IAChF,CAAC,CAAC;EACN,CAAC,CAAC;AACN,CAAC,CAAC","ignoreList":[]}
@@ -1,4 +1,5 @@
1
1
  export { createPermissionSchema } from "./createPermissionSchema.js";
2
+ export { createPermissionsAbstraction, createPermissionsFeature } from "./createPermissions.js";
2
3
  export { createUsePermissions } from "./usePermissions.js";
3
4
  export { usePermissionForm, deserializePermissions, serializePermissions } from "./usePermissionForm.js";
4
5
  export { PermissionRenderer } from "./PermissionRenderer.js";
@@ -1,4 +1,5 @@
1
1
  export { createPermissionSchema } from "./createPermissionSchema.js";
2
+ export { createPermissionsAbstraction, createPermissionsFeature } from "./createPermissions.js";
2
3
  export { createUsePermissions } from "./usePermissions.js";
3
4
  export { usePermissionForm, deserializePermissions, serializePermissions } from "./usePermissionForm.js";
4
5
  export { PermissionRenderer } from "./PermissionRenderer.js";
@@ -1 +1 @@
1
- {"version":3,"names":["createPermissionSchema","createUsePermissions","usePermissionForm","deserializePermissions","serializePermissions","PermissionRenderer","usePermissionValue","PermissionValueProvider","createHasPermission"],"sources":["index.ts"],"sourcesContent":["export { createPermissionSchema } from \"./createPermissionSchema.js\";\nexport { createUsePermissions } from \"./usePermissions.js\";\nexport {\n usePermissionForm,\n deserializePermissions,\n serializePermissions\n} from \"./usePermissionForm.js\";\nexport { PermissionRenderer } from \"./PermissionRenderer.js\";\nexport type { PermissionRendererProps } from \"./PermissionRenderer.js\";\nexport { usePermissionValue, PermissionValueProvider } from \"./PermissionValueContext.js\";\nexport { createHasPermission } from \"./createHasPermission.js\";\nexport type {\n Permission,\n ActionDefinition,\n EntityDefinition,\n OwnableItem,\n PermissionSchemaConfig,\n PermissionSchema,\n UsePermissionFormOptions,\n UsePermissionFormResult,\n UsePermissionsResult,\n PermissionRendererConfig,\n HasPermissionAction,\n HasPermissionProps\n} from \"./types.js\";\n"],"mappings":"AAAA,SAASA,sBAAsB;AAC/B,SAASC,oBAAoB;AAC7B,SACIC,iBAAiB,EACjBC,sBAAsB,EACtBC,oBAAoB;AAExB,SAASC,kBAAkB;AAE3B,SAASC,kBAAkB,EAAEC,uBAAuB;AACpD,SAASC,mBAAmB","ignoreList":[]}
1
+ {"version":3,"names":["createPermissionSchema","createPermissionsAbstraction","createPermissionsFeature","createUsePermissions","usePermissionForm","deserializePermissions","serializePermissions","PermissionRenderer","usePermissionValue","PermissionValueProvider","createHasPermission"],"sources":["index.ts"],"sourcesContent":["export { createPermissionSchema } from \"./createPermissionSchema.js\";\nexport { createPermissionsAbstraction, createPermissionsFeature } from \"./createPermissions.js\";\nexport { createUsePermissions } from \"./usePermissions.js\";\nexport {\n usePermissionForm,\n deserializePermissions,\n serializePermissions\n} from \"./usePermissionForm.js\";\nexport { PermissionRenderer } from \"./PermissionRenderer.js\";\nexport type { PermissionRendererProps } from \"./PermissionRenderer.js\";\nexport { usePermissionValue, PermissionValueProvider } from \"./PermissionValueContext.js\";\nexport { createHasPermission } from \"./createHasPermission.js\";\nexport type {\n Permission,\n ActionDefinition,\n EntityDefinition,\n OwnableItem,\n PermissionSchemaConfig,\n PermissionSchema,\n UsePermissionFormOptions,\n UsePermissionFormResult,\n UsePermissionsResult,\n PermissionRendererConfig,\n HasPermissionAction,\n HasPermissionProps\n} from \"./types.js\";\n"],"mappings":"AAAA,SAASA,sBAAsB;AAC/B,SAASC,4BAA4B,EAAEC,wBAAwB;AAC/D,SAASC,oBAAoB;AAC7B,SACIC,iBAAiB,EACjBC,sBAAsB,EACtBC,oBAAoB;AAExB,SAASC,kBAAkB;AAE3B,SAASC,kBAAkB,EAAEC,uBAAuB;AACpD,SAASC,mBAAmB","ignoreList":[]}
@@ -177,6 +177,11 @@ export type CustomActionNames<S extends PermissionSchemaConfig> = Exclude<Entiti
177
177
  * When the schema is dynamically typed, all methods accept `string`.
178
178
  */
179
179
  export type UsePermissionsResult<S extends PermissionSchemaConfig> = string extends AllEntityIds<S> ? UsePermissionsResultUntyped : UsePermissionsResultTyped<S>;
180
+ /**
181
+ * Canonical type for DI-resolved permissions.
182
+ * Same underlying type as `UsePermissionsResult<S>`.
183
+ */
184
+ export type Permissions<S extends PermissionSchemaConfig> = UsePermissionsResult<S>;
180
185
  export interface UsePermissionsResultUntyped {
181
186
  canAccess: (entityId: string) => boolean;
182
187
  canRead: (entityId: string) => boolean;
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["types.ts"],"sourcesContent":["import type React from \"react\";\nimport type { NonEmptyArray } from \"@webiny/app/types.js\";\n\n/**\n * A single permission object from the API.\n */\nexport interface Permission {\n name: string;\n [key: string]: any;\n}\n\n/**\n * An action definition on an entity.\n *\n * Built-in actions:\n * - `{ name: \"rwd\" }` — read/write/delete single-select (serialized as joined string, e.g. \"rw\")\n * - `{ name: \"pw\" }` — publish/unpublish multi-select (serialized as joined string, e.g. \"pu\")\n *\n * Custom actions:\n * - `{ name: \"install\", label: \"Install\" }` — boolean flag (serialized as `install: true`)\n */\nexport interface ActionDefinition {\n /** Key on the permission object (e.g. \"rwd\", \"pw\", \"install\") */\n name: string;\n /** Display label for the UI. Required for custom actions; ignored for built-in \"rwd\"/\"pw\". */\n label?: string;\n}\n\n/**\n * Defines an entity within a permission schema.\n */\nexport interface EntityDefinition {\n /** Unique ID, used for form field naming: ${id}AccessScope, ${id}RWD, etc. */\n id: string;\n /** Display title for the UI renderer (e.g. \"Files\", \"Settings\") */\n title?: string;\n /** Permission name emitted for this entity (e.g. \"fm.file\") */\n permission: string;\n /** Available access scopes */\n scopes: (\"full\" | \"own\")[];\n /** Action definitions for this entity */\n actions?: ActionDefinition[];\n /** Dependency on another entity */\n dependsOn?: {\n /** ID of parent entity */\n entity: string;\n /** Required action character (e.g. \"r\") */\n requires: string;\n };\n}\n\n/**\n * Configuration for creating a permission schema.\n */\nexport interface PermissionSchemaConfig {\n /** Permission prefix — used to filter permissions from the array */\n prefix: string;\n /**\n * Full access configuration.\n * - `true` — emits `{ name: \"${prefix}.*\" }`.\n * - `{ ...extras }` — emits `{ name: \"${prefix}.*\", ...extras }`.\n */\n fullAccess: boolean | { [key: string]: any };\n /**\n * Read-only access configuration. When defined, the schema supports a read-only tier.\n * - `true` — emits `{ name: \"${prefix}.*\", rwd: \"r\" }`.\n * - `Permission[]` — emits the array as-is.\n */\n readOnlyAccess?: boolean | Permission[];\n /** Entity definitions (optional — simple apps have none) */\n entities?: EntityDefinition[];\n}\n\n/**\n * A compiled permission schema returned by `createPermissionSchema`.\n */\nexport interface PermissionSchema {\n prefix: string;\n /**\n * Full access configuration.\n * - `true` — emits `{ name: \"${prefix}.*\" }`.\n * - `{ ...extras }` — emits `{ name: \"${prefix}.*\", ...extras }`.\n */\n fullAccess: boolean | { [key: string]: any };\n /**\n * Read-only access configuration. When defined, the schema supports a read-only tier.\n * - `true` — emits `{ name: \"${prefix}.*\", rwd: \"r\" }`.\n * - `Permission[]` — emits the array as-is.\n */\n readOnlyAccess?: boolean | Permission[];\n entities?: EntityDefinition[];\n}\n\n/**\n * Options passed to the `usePermissionForm` hook.\n */\nexport interface UsePermissionFormOptions {\n value: Permission[];\n onChange: (value: Permission[]) => void;\n /** Merge extra fields into deserialized form data (for CMS endpoints, resource scopes, etc.) */\n deserialize?: (permissions: Permission[]) => Record<string, any>;\n /** Transform or extend the core-serialized permissions (for CMS endpoints, resource scopes, etc.) */\n serialize?: (formData: Record<string, any>, corePermissions: Permission[]) => Permission[];\n}\n\n/**\n * Return value of `usePermissionForm`.\n */\nexport interface UsePermissionFormResult {\n formData: Record<string, any>;\n onFormChange: (data: Record<string, any>) => void;\n}\n\n/**\n * Configuration for a permission renderer registered via AdminConfig.\n *\n * Either `schema` or `element` must be provided:\n * - `schema`: uses the built-in PermissionRenderer for auto-generated UI.\n * - `element`: uses a custom React element for full control.\n */\nexport type PermissionRendererConfig = PermissionRendererConfigBase &\n (\n | { schema: PermissionSchema; element?: never }\n | { schema?: never; element: React.ReactElement }\n );\n\ninterface PermissionRendererConfigBase {\n name: string;\n title: string;\n description?: string;\n icon?: React.ReactElement;\n system?: boolean;\n}\n\n/**\n * Item that may have an owner (used for own-scope permission checks).\n */\nexport interface OwnableItem {\n createdBy?: { id: string } | null;\n}\n\n/**\n * Extract the union of entity definitions from a schema config type.\n */\ntype EntitiesOf<S extends PermissionSchemaConfig> = S extends {\n entities: ReadonlyArray<infer E extends EntityDefinition>;\n}\n ? E\n : never;\n\n/**\n * Extract entity IDs whose actions array contains an action with the given name.\n */\ntype EntityIdWithAction<S extends PermissionSchemaConfig, A extends string> = {\n [K in EntitiesOf<S> as K extends { actions: ReadonlyArray<infer Act> }\n ? Act extends { name: A }\n ? K[\"id\"]\n : never\n : never]: never;\n} extends infer M\n ? keyof M & string\n : never;\n\n/**\n * Entity IDs that have the \"rwd\" action.\n */\nexport type RwdEntityId<S extends PermissionSchemaConfig> = EntityIdWithAction<S, \"rwd\">;\n\n/**\n * Entity IDs that have the \"pw\" action.\n */\nexport type PwEntityId<S extends PermissionSchemaConfig> = EntityIdWithAction<S, \"pw\">;\n\n/**\n * All entity IDs in the schema.\n */\nexport type AllEntityIds<S extends PermissionSchemaConfig> = EntitiesOf<S>[\"id\"];\n\n/**\n * Custom (non-builtin) action names across all entities.\n */\nexport type CustomActionNames<S extends PermissionSchemaConfig> = Exclude<\n EntitiesOf<S> extends { actions: ReadonlyArray<infer Act extends ActionDefinition> }\n ? Act[\"name\"]\n : never,\n \"rwd\" | \"pw\"\n>;\n\n/**\n * The return type of `usePermissions(schema)`.\n *\n * When the schema has literal entity types, methods are narrowed to only accept valid entity IDs.\n * When the schema is dynamically typed, all methods accept `string`.\n */\nexport type UsePermissionsResult<S extends PermissionSchemaConfig> =\n string extends AllEntityIds<S> ? UsePermissionsResultUntyped : UsePermissionsResultTyped<S>;\n\nexport interface UsePermissionsResultUntyped {\n canAccess: (entityId: string) => boolean;\n canRead: (entityId: string) => boolean;\n canCreate: (entityId: string) => boolean;\n canEdit: (entityId: string, item?: OwnableItem) => boolean;\n canDelete: (entityId: string, item?: OwnableItem) => boolean;\n canPublish: (entityId: string) => boolean;\n canUnpublish: (entityId: string) => boolean;\n canAction: (action: string, entityId: string) => boolean;\n}\n\n/**\n * Action values accepted by `HasPermission`.\n *\n * Built-in actions are always available; custom action names from the schema are inferred automatically.\n */\nexport type HasPermissionAction<S extends PermissionSchemaConfig> =\n | \"read\"\n | \"create\"\n | \"edit\"\n | \"delete\"\n | \"publish\"\n | \"unpublish\"\n | CustomActionNames<S>;\n\n/**\n * Action constraint for `HasPermission`.\n *\n * Exactly one of `action`, `someActions`, or `allActions` may be provided:\n * - `action` — single action; grants access if it passes.\n * - `someActions` — array; grants access if ANY action passes (OR).\n * - `allActions` — array; grants access only if ALL actions pass (AND).\n */\ntype ActionConstraint<S extends PermissionSchemaConfig> =\n | { action?: HasPermissionAction<S>; someActions?: never; allActions?: never }\n | { action?: never; someActions: NonEmptyArray<HasPermissionAction<S>>; allActions?: never }\n | { action?: never; someActions?: never; allActions: NonEmptyArray<HasPermissionAction<S>> };\n\n/**\n * Props for a schema-bound `HasPermission` component created via `createHasPermission`.\n *\n * Exactly one of `entity`, `any`, or `all` must be provided.\n * Optionally combine with `action`, `someActions`, or `allActions`.\n */\nexport type HasPermissionProps<S extends PermissionSchemaConfig> = (\n | SingleEntityProps<S>\n | AnyEntitiesProps<S>\n | AllEntitiesProps<S>\n) &\n ActionConstraint<S>;\n\ninterface SingleEntityProps<S extends PermissionSchemaConfig> {\n entity: AllEntityIds<S>;\n any?: never;\n all?: never;\n children: React.ReactNode;\n}\n\ninterface AnyEntitiesProps<S extends PermissionSchemaConfig> {\n entity?: never;\n any: AllEntityIds<S>[];\n all?: never;\n children: React.ReactNode;\n}\n\ninterface AllEntitiesProps<S extends PermissionSchemaConfig> {\n entity?: never;\n any?: never;\n all: AllEntityIds<S>[];\n children: React.ReactNode;\n}\n\ntype UsePermissionsResultTyped<S extends PermissionSchemaConfig> = {\n canAccess: (entityId: AllEntityIds<S>) => boolean;\n canAction: (\n action: CustomActionNames<S> extends never ? string : CustomActionNames<S>,\n entityId: AllEntityIds<S>\n ) => boolean;\n} & ([RwdEntityId<S>] extends [never]\n ? {\n canRead: (entityId: string) => boolean;\n canCreate: (entityId: string) => boolean;\n canEdit: (entityId: string, item?: OwnableItem) => boolean;\n canDelete: (entityId: string, item?: OwnableItem) => boolean;\n }\n : {\n canRead: (entityId: RwdEntityId<S>) => boolean;\n canCreate: (entityId: RwdEntityId<S>) => boolean;\n canEdit: (entityId: RwdEntityId<S>, item?: OwnableItem) => boolean;\n canDelete: (entityId: RwdEntityId<S>, item?: OwnableItem) => boolean;\n }) &\n ([PwEntityId<S>] extends [never]\n ? {\n canPublish: (entityId: string) => boolean;\n canUnpublish: (entityId: string) => boolean;\n }\n : {\n canPublish: (entityId: PwEntityId<S>) => boolean;\n canUnpublish: (entityId: PwEntityId<S>) => boolean;\n });\n"],"mappings":"","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["types.ts"],"sourcesContent":["import type React from \"react\";\nimport type { NonEmptyArray } from \"@webiny/app/types.js\";\n\n/**\n * A single permission object from the API.\n */\nexport interface Permission {\n name: string;\n [key: string]: any;\n}\n\n/**\n * An action definition on an entity.\n *\n * Built-in actions:\n * - `{ name: \"rwd\" }` — read/write/delete single-select (serialized as joined string, e.g. \"rw\")\n * - `{ name: \"pw\" }` — publish/unpublish multi-select (serialized as joined string, e.g. \"pu\")\n *\n * Custom actions:\n * - `{ name: \"install\", label: \"Install\" }` — boolean flag (serialized as `install: true`)\n */\nexport interface ActionDefinition {\n /** Key on the permission object (e.g. \"rwd\", \"pw\", \"install\") */\n name: string;\n /** Display label for the UI. Required for custom actions; ignored for built-in \"rwd\"/\"pw\". */\n label?: string;\n}\n\n/**\n * Defines an entity within a permission schema.\n */\nexport interface EntityDefinition {\n /** Unique ID, used for form field naming: ${id}AccessScope, ${id}RWD, etc. */\n id: string;\n /** Display title for the UI renderer (e.g. \"Files\", \"Settings\") */\n title?: string;\n /** Permission name emitted for this entity (e.g. \"fm.file\") */\n permission: string;\n /** Available access scopes */\n scopes: (\"full\" | \"own\")[];\n /** Action definitions for this entity */\n actions?: ActionDefinition[];\n /** Dependency on another entity */\n dependsOn?: {\n /** ID of parent entity */\n entity: string;\n /** Required action character (e.g. \"r\") */\n requires: string;\n };\n}\n\n/**\n * Configuration for creating a permission schema.\n */\nexport interface PermissionSchemaConfig {\n /** Permission prefix — used to filter permissions from the array */\n prefix: string;\n /**\n * Full access configuration.\n * - `true` — emits `{ name: \"${prefix}.*\" }`.\n * - `{ ...extras }` — emits `{ name: \"${prefix}.*\", ...extras }`.\n */\n fullAccess: boolean | { [key: string]: any };\n /**\n * Read-only access configuration. When defined, the schema supports a read-only tier.\n * - `true` — emits `{ name: \"${prefix}.*\", rwd: \"r\" }`.\n * - `Permission[]` — emits the array as-is.\n */\n readOnlyAccess?: boolean | Permission[];\n /** Entity definitions (optional — simple apps have none) */\n entities?: EntityDefinition[];\n}\n\n/**\n * A compiled permission schema returned by `createPermissionSchema`.\n */\nexport interface PermissionSchema {\n prefix: string;\n /**\n * Full access configuration.\n * - `true` — emits `{ name: \"${prefix}.*\" }`.\n * - `{ ...extras }` — emits `{ name: \"${prefix}.*\", ...extras }`.\n */\n fullAccess: boolean | { [key: string]: any };\n /**\n * Read-only access configuration. When defined, the schema supports a read-only tier.\n * - `true` — emits `{ name: \"${prefix}.*\", rwd: \"r\" }`.\n * - `Permission[]` — emits the array as-is.\n */\n readOnlyAccess?: boolean | Permission[];\n entities?: EntityDefinition[];\n}\n\n/**\n * Options passed to the `usePermissionForm` hook.\n */\nexport interface UsePermissionFormOptions {\n value: Permission[];\n onChange: (value: Permission[]) => void;\n /** Merge extra fields into deserialized form data (for CMS endpoints, resource scopes, etc.) */\n deserialize?: (permissions: Permission[]) => Record<string, any>;\n /** Transform or extend the core-serialized permissions (for CMS endpoints, resource scopes, etc.) */\n serialize?: (formData: Record<string, any>, corePermissions: Permission[]) => Permission[];\n}\n\n/**\n * Return value of `usePermissionForm`.\n */\nexport interface UsePermissionFormResult {\n formData: Record<string, any>;\n onFormChange: (data: Record<string, any>) => void;\n}\n\n/**\n * Configuration for a permission renderer registered via AdminConfig.\n *\n * Either `schema` or `element` must be provided:\n * - `schema`: uses the built-in PermissionRenderer for auto-generated UI.\n * - `element`: uses a custom React element for full control.\n */\nexport type PermissionRendererConfig = PermissionRendererConfigBase &\n (\n | { schema: PermissionSchema; element?: never }\n | { schema?: never; element: React.ReactElement }\n );\n\ninterface PermissionRendererConfigBase {\n name: string;\n title: string;\n description?: string;\n icon?: React.ReactElement;\n system?: boolean;\n}\n\n/**\n * Item that may have an owner (used for own-scope permission checks).\n */\nexport interface OwnableItem {\n createdBy?: { id: string } | null;\n}\n\n/**\n * Extract the union of entity definitions from a schema config type.\n */\ntype EntitiesOf<S extends PermissionSchemaConfig> = S extends {\n entities: ReadonlyArray<infer E extends EntityDefinition>;\n}\n ? E\n : never;\n\n/**\n * Extract entity IDs whose actions array contains an action with the given name.\n */\ntype EntityIdWithAction<S extends PermissionSchemaConfig, A extends string> = {\n [K in EntitiesOf<S> as K extends { actions: ReadonlyArray<infer Act> }\n ? Act extends { name: A }\n ? K[\"id\"]\n : never\n : never]: never;\n} extends infer M\n ? keyof M & string\n : never;\n\n/**\n * Entity IDs that have the \"rwd\" action.\n */\nexport type RwdEntityId<S extends PermissionSchemaConfig> = EntityIdWithAction<S, \"rwd\">;\n\n/**\n * Entity IDs that have the \"pw\" action.\n */\nexport type PwEntityId<S extends PermissionSchemaConfig> = EntityIdWithAction<S, \"pw\">;\n\n/**\n * All entity IDs in the schema.\n */\nexport type AllEntityIds<S extends PermissionSchemaConfig> = EntitiesOf<S>[\"id\"];\n\n/**\n * Custom (non-builtin) action names across all entities.\n */\nexport type CustomActionNames<S extends PermissionSchemaConfig> = Exclude<\n EntitiesOf<S> extends { actions: ReadonlyArray<infer Act extends ActionDefinition> }\n ? Act[\"name\"]\n : never,\n \"rwd\" | \"pw\"\n>;\n\n/**\n * The return type of `usePermissions(schema)`.\n *\n * When the schema has literal entity types, methods are narrowed to only accept valid entity IDs.\n * When the schema is dynamically typed, all methods accept `string`.\n */\nexport type UsePermissionsResult<S extends PermissionSchemaConfig> =\n string extends AllEntityIds<S> ? UsePermissionsResultUntyped : UsePermissionsResultTyped<S>;\n\n/**\n * Canonical type for DI-resolved permissions.\n * Same underlying type as `UsePermissionsResult<S>`.\n */\nexport type Permissions<S extends PermissionSchemaConfig> = UsePermissionsResult<S>;\n\nexport interface UsePermissionsResultUntyped {\n canAccess: (entityId: string) => boolean;\n canRead: (entityId: string) => boolean;\n canCreate: (entityId: string) => boolean;\n canEdit: (entityId: string, item?: OwnableItem) => boolean;\n canDelete: (entityId: string, item?: OwnableItem) => boolean;\n canPublish: (entityId: string) => boolean;\n canUnpublish: (entityId: string) => boolean;\n canAction: (action: string, entityId: string) => boolean;\n}\n\n/**\n * Action values accepted by `HasPermission`.\n *\n * Built-in actions are always available; custom action names from the schema are inferred automatically.\n */\nexport type HasPermissionAction<S extends PermissionSchemaConfig> =\n | \"read\"\n | \"create\"\n | \"edit\"\n | \"delete\"\n | \"publish\"\n | \"unpublish\"\n | CustomActionNames<S>;\n\n/**\n * Action constraint for `HasPermission`.\n *\n * Exactly one of `action`, `someActions`, or `allActions` may be provided:\n * - `action` — single action; grants access if it passes.\n * - `someActions` — array; grants access if ANY action passes (OR).\n * - `allActions` — array; grants access only if ALL actions pass (AND).\n */\ntype ActionConstraint<S extends PermissionSchemaConfig> =\n | { action?: HasPermissionAction<S>; someActions?: never; allActions?: never }\n | { action?: never; someActions: NonEmptyArray<HasPermissionAction<S>>; allActions?: never }\n | { action?: never; someActions?: never; allActions: NonEmptyArray<HasPermissionAction<S>> };\n\n/**\n * Props for a schema-bound `HasPermission` component created via `createHasPermission`.\n *\n * Exactly one of `entity`, `any`, or `all` must be provided.\n * Optionally combine with `action`, `someActions`, or `allActions`.\n */\nexport type HasPermissionProps<S extends PermissionSchemaConfig> = (\n | SingleEntityProps<S>\n | AnyEntitiesProps<S>\n | AllEntitiesProps<S>\n) &\n ActionConstraint<S>;\n\ninterface SingleEntityProps<S extends PermissionSchemaConfig> {\n entity: AllEntityIds<S>;\n any?: never;\n all?: never;\n children: React.ReactNode;\n}\n\ninterface AnyEntitiesProps<S extends PermissionSchemaConfig> {\n entity?: never;\n any: AllEntityIds<S>[];\n all?: never;\n children: React.ReactNode;\n}\n\ninterface AllEntitiesProps<S extends PermissionSchemaConfig> {\n entity?: never;\n any?: never;\n all: AllEntityIds<S>[];\n children: React.ReactNode;\n}\n\ntype UsePermissionsResultTyped<S extends PermissionSchemaConfig> = {\n canAccess: (entityId: AllEntityIds<S>) => boolean;\n canAction: (\n action: CustomActionNames<S> extends never ? string : CustomActionNames<S>,\n entityId: AllEntityIds<S>\n ) => boolean;\n} & ([RwdEntityId<S>] extends [never]\n ? {\n canRead: (entityId: string) => boolean;\n canCreate: (entityId: string) => boolean;\n canEdit: (entityId: string, item?: OwnableItem) => boolean;\n canDelete: (entityId: string, item?: OwnableItem) => boolean;\n }\n : {\n canRead: (entityId: RwdEntityId<S>) => boolean;\n canCreate: (entityId: RwdEntityId<S>) => boolean;\n canEdit: (entityId: RwdEntityId<S>, item?: OwnableItem) => boolean;\n canDelete: (entityId: RwdEntityId<S>, item?: OwnableItem) => boolean;\n }) &\n ([PwEntityId<S>] extends [never]\n ? {\n canPublish: (entityId: string) => boolean;\n canUnpublish: (entityId: string) => boolean;\n }\n : {\n canPublish: (entityId: PwEntityId<S>) => boolean;\n canUnpublish: (entityId: PwEntityId<S>) => boolean;\n });\n"],"mappings":"","ignoreList":[]}
@@ -1,3 +1,4 @@
1
+ import type { Abstraction } from "@webiny/di";
1
2
  import type { PermissionSchemaConfig } from "./types.js";
2
3
  import type { UsePermissionsResult } from "./types.js";
3
- export declare function createUsePermissions<const S extends PermissionSchemaConfig>(schema: S): () => UsePermissionsResult<S>;
4
+ export declare function createUsePermissions<const S extends PermissionSchemaConfig>(abstraction: Abstraction<UsePermissionsResult<S>>): () => UsePermissionsResult<S>;
@@ -1,179 +1,8 @@
1
- import { useIdentity } from "../presentation/security/hooks/useIdentity.js";
2
- // Module-level cache: schema -> identityId -> result.
3
- const cache = new WeakMap();
4
- function buildEntityMap(schema) {
5
- const map = new Map();
6
- for (const entity of schema.entities ?? []) {
7
- const actions = new Set();
8
- for (const action of entity.actions ?? []) {
9
- actions.add(action.name);
10
- }
11
- map.set(entity.id, {
12
- permission: entity.permission,
13
- actions,
14
- hasOwn: entity.scopes.includes("own")
15
- });
16
- }
17
- return map;
18
- }
19
- function getEntity(entityMap, entityId) {
20
- const entity = entityMap.get(entityId);
21
- if (!entity) {
22
- throw new Error(`Unknown entity "${entityId}" in permission schema.`);
23
- }
24
- return entity;
25
- }
26
- function buildResult(schema, identity) {
27
- const fullAccessName = `${schema.prefix}.*`;
28
- const hasFullAccess = !!identity.getPermission(fullAccessName);
29
- const entityMap = buildEntityMap(schema);
30
- const canAccess = entityId => {
31
- if (hasFullAccess) {
32
- return true;
33
- }
34
- const entity = getEntity(entityMap, entityId);
35
- const permissions = identity.getPermissions(entity.permission);
36
- return permissions.length > 0;
37
- };
38
- const canRead = entityId => {
39
- if (hasFullAccess) {
40
- return true;
41
- }
42
- const entity = getEntity(entityMap, entityId);
43
- const permissions = identity.getPermissions(entity.permission);
44
- if (!permissions.length) {
45
- return false;
46
- }
47
- return permissions.some(permission => {
48
- if (typeof permission.rwd !== "string") {
49
- return true;
50
- }
51
- return permission.rwd.includes("r");
52
- });
53
- };
54
- const canCreate = entityId => {
55
- if (hasFullAccess) {
56
- return true;
57
- }
58
- const entity = getEntity(entityMap, entityId);
59
- const permissions = identity.getPermissions(entity.permission);
60
- if (!permissions.length) {
61
- return false;
62
- }
63
- return permissions.some(permission => {
64
- if (typeof permission.rwd !== "string") {
65
- return true;
66
- }
67
- return permission.rwd.includes("w");
68
- });
69
- };
70
- const canEdit = (entityId, item) => {
71
- if (hasFullAccess) {
72
- return true;
73
- }
74
- const entity = getEntity(entityMap, entityId);
75
- const permissions = identity.getPermissions(entity.permission);
76
- if (!permissions.length) {
77
- return false;
78
- }
79
- return permissions.some(permission => {
80
- if (permission.own) {
81
- if (!item?.createdBy) {
82
- return true;
83
- }
84
- return item.createdBy.id === identity.id;
85
- }
86
- if (typeof permission.rwd !== "string") {
87
- return true;
88
- }
89
- return permission.rwd.includes("w");
90
- });
91
- };
92
- const canDelete = (entityId, item) => {
93
- if (hasFullAccess) {
94
- return true;
95
- }
96
- const entity = getEntity(entityMap, entityId);
97
- const permissions = identity.getPermissions(entity.permission);
98
- if (!permissions.length) {
99
- return false;
100
- }
101
- return permissions.some(permission => {
102
- if (permission.own) {
103
- return item?.createdBy?.id === identity.id;
104
- }
105
- if (typeof permission.rwd !== "string") {
106
- return true;
107
- }
108
- return permission.rwd.includes("d");
109
- });
110
- };
111
- const canPublish = entityId => {
112
- if (hasFullAccess) {
113
- return true;
114
- }
115
- const entity = getEntity(entityMap, entityId);
116
- const permissions = identity.getPermissions(entity.permission);
117
- if (!permissions.length) {
118
- return false;
119
- }
120
- return permissions.some(permission => {
121
- return permission.pw?.includes("p");
122
- });
123
- };
124
- const canUnpublish = entityId => {
125
- if (hasFullAccess) {
126
- return true;
127
- }
128
- const entity = getEntity(entityMap, entityId);
129
- const permissions = identity.getPermissions(entity.permission);
130
- if (!permissions.length) {
131
- return false;
132
- }
133
- return permissions.some(permission => {
134
- return permission.pw?.includes("u");
135
- });
136
- };
137
- const canAction = (action, entityId) => {
138
- if (hasFullAccess) {
139
- return true;
140
- }
141
- const entity = getEntity(entityMap, entityId);
142
- const permissions = identity.getPermissions(entity.permission);
143
- if (!permissions.length) {
144
- return false;
145
- }
146
- return permissions.some(permission => {
147
- return permission[action] === true;
148
- });
149
- };
150
- return {
151
- canAccess,
152
- canRead,
153
- canCreate,
154
- canEdit,
155
- canDelete,
156
- canPublish,
157
- canUnpublish,
158
- canAction
159
- };
160
- }
161
- export function createUsePermissions(schema) {
1
+ import { useContainer } from "@webiny/app";
2
+ export function createUsePermissions(abstraction) {
162
3
  return function usePermissions() {
163
- const {
164
- identity
165
- } = useIdentity();
166
- let byIdentityId = cache.get(schema);
167
- if (!byIdentityId) {
168
- byIdentityId = new Map();
169
- cache.set(schema, byIdentityId);
170
- }
171
- let result = byIdentityId.get(identity.id);
172
- if (!result) {
173
- result = buildResult(schema, identity);
174
- byIdentityId.set(identity.id, result);
175
- }
176
- return result;
4
+ const container = useContainer();
5
+ return container.resolve(abstraction);
177
6
  };
178
7
  }
179
8
 
@@ -1 +1 @@
1
- {"version":3,"names":["useIdentity","cache","WeakMap","buildEntityMap","schema","map","Map","entity","entities","actions","Set","action","add","name","set","id","permission","hasOwn","scopes","includes","getEntity","entityMap","entityId","get","Error","buildResult","identity","fullAccessName","prefix","hasFullAccess","getPermission","canAccess","permissions","getPermissions","length","canRead","some","rwd","canCreate","canEdit","item","own","createdBy","canDelete","canPublish","pw","canUnpublish","canAction","createUsePermissions","usePermissions","byIdentityId","result"],"sources":["usePermissions.ts"],"sourcesContent":["import { useIdentity } from \"~/presentation/security/hooks/useIdentity.js\";\nimport type { Identity } from \"~/domain/Identity.js\";\nimport type { PermissionSchemaConfig } from \"./types.js\";\nimport type { OwnableItem } from \"./types.js\";\nimport type { UsePermissionsResult } from \"./types.js\";\n\ninterface EntityLookup {\n permission: string;\n actions: Set<string>;\n hasOwn: boolean;\n}\n\n// Module-level cache: schema -> identityId -> result.\nconst cache = new WeakMap<PermissionSchemaConfig, Map<string, UsePermissionsResult<any>>>();\n\nfunction buildEntityMap(schema: PermissionSchemaConfig): Map<string, EntityLookup> {\n const map = new Map<string, EntityLookup>();\n for (const entity of schema.entities ?? []) {\n const actions = new Set<string>();\n for (const action of entity.actions ?? []) {\n actions.add(action.name);\n }\n map.set(entity.id, {\n permission: entity.permission,\n actions,\n hasOwn: entity.scopes.includes(\"own\")\n });\n }\n return map;\n}\n\nfunction getEntity(entityMap: Map<string, EntityLookup>, entityId: string): EntityLookup {\n const entity = entityMap.get(entityId);\n if (!entity) {\n throw new Error(`Unknown entity \"${entityId}\" in permission schema.`);\n }\n return entity;\n}\n\nfunction buildResult<S extends PermissionSchemaConfig>(\n schema: S,\n identity: Identity\n): UsePermissionsResult<S> {\n const fullAccessName = `${schema.prefix}.*`;\n const hasFullAccess = !!identity.getPermission(fullAccessName);\n const entityMap = buildEntityMap(schema);\n\n const canAccess = (entityId: string): boolean => {\n if (hasFullAccess) {\n return true;\n }\n const entity = getEntity(entityMap, entityId);\n const permissions = identity.getPermissions(entity.permission);\n return permissions.length > 0;\n };\n\n const canRead = (entityId: string): boolean => {\n if (hasFullAccess) {\n return true;\n }\n const entity = getEntity(entityMap, entityId);\n const permissions = identity.getPermissions(entity.permission);\n if (!permissions.length) {\n return false;\n }\n return permissions.some(permission => {\n if (typeof permission.rwd !== \"string\") {\n return true;\n }\n return permission.rwd.includes(\"r\");\n });\n };\n\n const canCreate = (entityId: string): boolean => {\n if (hasFullAccess) {\n return true;\n }\n const entity = getEntity(entityMap, entityId);\n const permissions = identity.getPermissions(entity.permission);\n if (!permissions.length) {\n return false;\n }\n return permissions.some(permission => {\n if (typeof permission.rwd !== \"string\") {\n return true;\n }\n return permission.rwd.includes(\"w\");\n });\n };\n\n const canEdit = (entityId: string, item?: OwnableItem): boolean => {\n if (hasFullAccess) {\n return true;\n }\n const entity = getEntity(entityMap, entityId);\n const permissions = identity.getPermissions(entity.permission);\n if (!permissions.length) {\n return false;\n }\n return permissions.some(permission => {\n if (permission.own) {\n if (!item?.createdBy) {\n return true;\n }\n return item.createdBy.id === identity.id;\n }\n if (typeof permission.rwd !== \"string\") {\n return true;\n }\n return permission.rwd.includes(\"w\");\n });\n };\n\n const canDelete = (entityId: string, item?: OwnableItem): boolean => {\n if (hasFullAccess) {\n return true;\n }\n const entity = getEntity(entityMap, entityId);\n const permissions = identity.getPermissions(entity.permission);\n if (!permissions.length) {\n return false;\n }\n return permissions.some(permission => {\n if (permission.own) {\n return item?.createdBy?.id === identity.id;\n }\n if (typeof permission.rwd !== \"string\") {\n return true;\n }\n return permission.rwd.includes(\"d\");\n });\n };\n\n const canPublish = (entityId: string): boolean => {\n if (hasFullAccess) {\n return true;\n }\n const entity = getEntity(entityMap, entityId);\n const permissions = identity.getPermissions(entity.permission);\n if (!permissions.length) {\n return false;\n }\n return permissions.some(permission => {\n return permission.pw?.includes(\"p\");\n });\n };\n\n const canUnpublish = (entityId: string): boolean => {\n if (hasFullAccess) {\n return true;\n }\n const entity = getEntity(entityMap, entityId);\n const permissions = identity.getPermissions(entity.permission);\n if (!permissions.length) {\n return false;\n }\n return permissions.some(permission => {\n return permission.pw?.includes(\"u\");\n });\n };\n\n const canAction = (action: string, entityId: string): boolean => {\n if (hasFullAccess) {\n return true;\n }\n const entity = getEntity(entityMap, entityId);\n const permissions = identity.getPermissions(entity.permission);\n if (!permissions.length) {\n return false;\n }\n return permissions.some(permission => {\n return permission[action] === true;\n });\n };\n\n return {\n canAccess,\n canRead,\n canCreate,\n canEdit,\n canDelete,\n canPublish,\n canUnpublish,\n canAction\n } as UsePermissionsResult<S>;\n}\n\nexport function createUsePermissions<const S extends PermissionSchemaConfig>(\n schema: S\n): () => UsePermissionsResult<S> {\n return function usePermissions(): UsePermissionsResult<S> {\n const { identity } = useIdentity();\n\n let byIdentityId = cache.get(schema);\n if (!byIdentityId) {\n byIdentityId = new Map();\n cache.set(schema, byIdentityId);\n }\n\n let result = byIdentityId.get(identity.id) as UsePermissionsResult<S> | undefined;\n if (!result) {\n result = buildResult(schema, identity);\n byIdentityId.set(identity.id, result as UsePermissionsResult<any>);\n }\n\n return result;\n };\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["useContainer","createUsePermissions","abstraction","usePermissions","container","resolve"],"sources":["usePermissions.ts"],"sourcesContent":["import { useContainer } from \"@webiny/app\";\nimport type { Abstraction } from \"@webiny/di\";\nimport type { PermissionSchemaConfig } from \"./types.js\";\nimport type { UsePermissionsResult } from \"./types.js\";\n\nexport function createUsePermissions<const S extends PermissionSchemaConfig>(\n abstraction: Abstraction<UsePermissionsResult<S>>\n): () => UsePermissionsResult<S> {\n return function usePermissions(): UsePermissionsResult<S> {\n const container = useContainer();\n return container.resolve(abstraction);\n };\n}\n"],"mappings":"AAAA,SAASA,YAAY,QAAQ,aAAa;AAK1C,OAAO,SAASC,oBAAoBA,CAChCC,WAAiD,EACpB;EAC7B,OAAO,SAASC,cAAcA,CAAA,EAA4B;IACtD,MAAMC,SAAS,GAAGJ,YAAY,CAAC,CAAC;IAChC,OAAOI,SAAS,CAACC,OAAO,CAACH,WAAW,CAAC;EACzC,CAAC;AACL","ignoreList":[]}
@@ -1,8 +1,8 @@
1
- import { GraphQLClient } from "@webiny/app/features/graphqlClient";
1
+ import { MainGraphQLClient } from "@webiny/app/features/mainGraphQLClient/index.js";
2
2
  import { type InstallationInput, SystemInstallerGateway as Abstraction } from "./abstractions.js";
3
3
  declare class SystemInstallerGraphQLGateway implements Abstraction.Interface {
4
4
  private client;
5
- constructor(client: GraphQLClient.Interface);
5
+ constructor(client: MainGraphQLClient.Interface);
6
6
  isSystemInstalled(): Promise<boolean>;
7
7
  installSystem(data: InstallationInput): Promise<void>;
8
8
  }
@@ -1,5 +1,5 @@
1
1
  import { createImplementation } from "@webiny/di";
2
- import { GraphQLClient } from "@webiny/app/features/graphqlClient";
2
+ import { MainGraphQLClient } from "@webiny/app/features/mainGraphQLClient/index.js";
3
3
  import { SystemInstallerGateway as Abstraction } from "./abstractions.js";
4
4
  const IS_SYSTEM_INSTALLED = /* GraphQL */`
5
5
  query IsSystemInstalled {
@@ -57,7 +57,7 @@ class SystemInstallerGraphQLGateway {
57
57
  export const SystemInstallerGateway = createImplementation({
58
58
  abstraction: Abstraction,
59
59
  implementation: SystemInstallerGraphQLGateway,
60
- dependencies: [GraphQLClient]
60
+ dependencies: [MainGraphQLClient]
61
61
  });
62
62
 
63
63
  //# sourceMappingURL=SystemInstallerGateway.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["createImplementation","GraphQLClient","SystemInstallerGateway","Abstraction","IS_SYSTEM_INSTALLED","INSTALL_SYSTEM","SystemInstallerGraphQLGateway","constructor","client","isSystemInstalled","response","execute","query","system","error","Error","message","data","installSystem","variables","installationInput","abstraction","implementation","dependencies"],"sources":["SystemInstallerGateway.ts"],"sourcesContent":["import { createImplementation } from \"@webiny/di\";\nimport { GraphQLClient } from \"@webiny/app/features/graphqlClient\";\nimport { type InstallationInput, SystemInstallerGateway as Abstraction } from \"./abstractions.js\";\n\nconst IS_SYSTEM_INSTALLED = /* GraphQL */ `\n query IsSystemInstalled {\n system {\n isSystemInstalled {\n data\n error {\n message\n code\n data\n }\n }\n }\n }\n`;\n\nconst INSTALL_SYSTEM = /* GraphQL */ `\n mutation InstallSystem($installationInput: JSON!) {\n system {\n installSystem(installationInput: $installationInput) {\n data\n error {\n message\n code\n data\n }\n }\n }\n }\n`;\n\ninterface IsSystemInstalledResponse {\n system: {\n isSystemInstalled: {\n data: boolean;\n error?: {\n message: string;\n code: string;\n data: any;\n };\n };\n };\n}\n\ninterface InstallSystemResponse {\n system: {\n installSystem: {\n data: boolean;\n error?: {\n message: string;\n code: string;\n data: any;\n };\n };\n };\n}\n\nclass SystemInstallerGraphQLGateway implements Abstraction.Interface {\n constructor(private client: GraphQLClient.Interface) {}\n\n async isSystemInstalled(): Promise<boolean> {\n const response = await this.client.execute<IsSystemInstalledResponse>({\n query: IS_SYSTEM_INSTALLED\n });\n\n if (response.system.isSystemInstalled.error) {\n throw new Error(response.system.isSystemInstalled.error.message);\n }\n\n return response.system.isSystemInstalled.data;\n }\n\n async installSystem(data: InstallationInput): Promise<void> {\n const response = await this.client.execute<InstallSystemResponse>({\n query: INSTALL_SYSTEM,\n variables: {\n installationInput: data\n }\n });\n\n if (response.system.installSystem.error) {\n throw response.system.installSystem.error;\n }\n }\n}\n\nexport const SystemInstallerGateway = createImplementation({\n abstraction: Abstraction,\n implementation: SystemInstallerGraphQLGateway,\n dependencies: [GraphQLClient]\n});\n"],"mappings":"AAAA,SAASA,oBAAoB,QAAQ,YAAY;AACjD,SAASC,aAAa,QAAQ,oCAAoC;AAClE,SAAiCC,sBAAsB,IAAIC,WAAW;AAEtE,MAAMC,mBAAmB,GAAG,aAAc;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;AAED,MAAMC,cAAc,GAAG,aAAc;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;AA4BD,MAAMC,6BAA6B,CAAkC;EACjEC,WAAWA,CAASC,MAA+B,EAAE;IAAA,KAAjCA,MAA+B,GAA/BA,MAA+B;EAAG;EAEtD,MAAMC,iBAAiBA,CAAA,EAAqB;IACxC,MAAMC,QAAQ,GAAG,MAAM,IAAI,CAACF,MAAM,CAACG,OAAO,CAA4B;MAClEC,KAAK,EAAER;IACX,CAAC,CAAC;IAEF,IAAIM,QAAQ,CAACG,MAAM,CAACJ,iBAAiB,CAACK,KAAK,EAAE;MACzC,MAAM,IAAIC,KAAK,CAACL,QAAQ,CAACG,MAAM,CAACJ,iBAAiB,CAACK,KAAK,CAACE,OAAO,CAAC;IACpE;IAEA,OAAON,QAAQ,CAACG,MAAM,CAACJ,iBAAiB,CAACQ,IAAI;EACjD;EAEA,MAAMC,aAAaA,CAACD,IAAuB,EAAiB;IACxD,MAAMP,QAAQ,GAAG,MAAM,IAAI,CAACF,MAAM,CAACG,OAAO,CAAwB;MAC9DC,KAAK,EAAEP,cAAc;MACrBc,SAAS,EAAE;QACPC,iBAAiB,EAAEH;MACvB;IACJ,CAAC,CAAC;IAEF,IAAIP,QAAQ,CAACG,MAAM,CAACK,aAAa,CAACJ,KAAK,EAAE;MACrC,MAAMJ,QAAQ,CAACG,MAAM,CAACK,aAAa,CAACJ,KAAK;IAC7C;EACJ;AACJ;AAEA,OAAO,MAAMZ,sBAAsB,GAAGF,oBAAoB,CAAC;EACvDqB,WAAW,EAAElB,WAAW;EACxBmB,cAAc,EAAEhB,6BAA6B;EAC7CiB,YAAY,EAAE,CAACtB,aAAa;AAChC,CAAC,CAAC","ignoreList":[]}
1
+ {"version":3,"names":["createImplementation","MainGraphQLClient","SystemInstallerGateway","Abstraction","IS_SYSTEM_INSTALLED","INSTALL_SYSTEM","SystemInstallerGraphQLGateway","constructor","client","isSystemInstalled","response","execute","query","system","error","Error","message","data","installSystem","variables","installationInput","abstraction","implementation","dependencies"],"sources":["SystemInstallerGateway.ts"],"sourcesContent":["import { createImplementation } from \"@webiny/di\";\nimport { MainGraphQLClient } from \"@webiny/app/features/mainGraphQLClient/index.js\";\nimport { type InstallationInput, SystemInstallerGateway as Abstraction } from \"./abstractions.js\";\n\nconst IS_SYSTEM_INSTALLED = /* GraphQL */ `\n query IsSystemInstalled {\n system {\n isSystemInstalled {\n data\n error {\n message\n code\n data\n }\n }\n }\n }\n`;\n\nconst INSTALL_SYSTEM = /* GraphQL */ `\n mutation InstallSystem($installationInput: JSON!) {\n system {\n installSystem(installationInput: $installationInput) {\n data\n error {\n message\n code\n data\n }\n }\n }\n }\n`;\n\ninterface IsSystemInstalledResponse {\n system: {\n isSystemInstalled: {\n data: boolean;\n error?: {\n message: string;\n code: string;\n data: any;\n };\n };\n };\n}\n\ninterface InstallSystemResponse {\n system: {\n installSystem: {\n data: boolean;\n error?: {\n message: string;\n code: string;\n data: any;\n };\n };\n };\n}\n\nclass SystemInstallerGraphQLGateway implements Abstraction.Interface {\n constructor(private client: MainGraphQLClient.Interface) {}\n\n async isSystemInstalled(): Promise<boolean> {\n const response = await this.client.execute<IsSystemInstalledResponse>({\n query: IS_SYSTEM_INSTALLED\n });\n\n if (response.system.isSystemInstalled.error) {\n throw new Error(response.system.isSystemInstalled.error.message);\n }\n\n return response.system.isSystemInstalled.data;\n }\n\n async installSystem(data: InstallationInput): Promise<void> {\n const response = await this.client.execute<InstallSystemResponse>({\n query: INSTALL_SYSTEM,\n variables: {\n installationInput: data\n }\n });\n\n if (response.system.installSystem.error) {\n throw response.system.installSystem.error;\n }\n }\n}\n\nexport const SystemInstallerGateway = createImplementation({\n abstraction: Abstraction,\n implementation: SystemInstallerGraphQLGateway,\n dependencies: [MainGraphQLClient]\n});\n"],"mappings":"AAAA,SAASA,oBAAoB,QAAQ,YAAY;AACjD,SAASC,iBAAiB,QAAQ,iDAAiD;AACnF,SAAiCC,sBAAsB,IAAIC,WAAW;AAEtE,MAAMC,mBAAmB,GAAG,aAAc;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;AAED,MAAMC,cAAc,GAAG,aAAc;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;AA4BD,MAAMC,6BAA6B,CAAkC;EACjEC,WAAWA,CAASC,MAAmC,EAAE;IAAA,KAArCA,MAAmC,GAAnCA,MAAmC;EAAG;EAE1D,MAAMC,iBAAiBA,CAAA,EAAqB;IACxC,MAAMC,QAAQ,GAAG,MAAM,IAAI,CAACF,MAAM,CAACG,OAAO,CAA4B;MAClEC,KAAK,EAAER;IACX,CAAC,CAAC;IAEF,IAAIM,QAAQ,CAACG,MAAM,CAACJ,iBAAiB,CAACK,KAAK,EAAE;MACzC,MAAM,IAAIC,KAAK,CAACL,QAAQ,CAACG,MAAM,CAACJ,iBAAiB,CAACK,KAAK,CAACE,OAAO,CAAC;IACpE;IAEA,OAAON,QAAQ,CAACG,MAAM,CAACJ,iBAAiB,CAACQ,IAAI;EACjD;EAEA,MAAMC,aAAaA,CAACD,IAAuB,EAAiB;IACxD,MAAMP,QAAQ,GAAG,MAAM,IAAI,CAACF,MAAM,CAACG,OAAO,CAAwB;MAC9DC,KAAK,EAAEP,cAAc;MACrBc,SAAS,EAAE;QACPC,iBAAiB,EAAEH;MACvB;IACJ,CAAC,CAAC;IAEF,IAAIP,QAAQ,CAACG,MAAM,CAACK,aAAa,CAACJ,KAAK,EAAE;MACrC,MAAMJ,QAAQ,CAACG,MAAM,CAACK,aAAa,CAACJ,KAAK;IAC7C;EACJ;AACJ;AAEA,OAAO,MAAMZ,sBAAsB,GAAGF,oBAAoB,CAAC;EACvDqB,WAAW,EAAElB,WAAW;EACxBmB,cAAc,EAAEhB,6BAA6B;EAC7CiB,YAAY,EAAE,CAACtB,iBAAiB;AACpC,CAAC,CAAC","ignoreList":[]}