@webiny/api-aco 6.4.11 → 6.6.0-alpha.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 (157) hide show
  1. package/AcoFeature.d.ts +5 -0
  2. package/AcoFeature.js +129 -0
  3. package/AcoFeature.js.map +1 -0
  4. package/AcoFolderSchemaFactory.d.ts +30 -0
  5. package/AcoFolderSchemaFactory.js +64 -0
  6. package/AcoFolderSchemaFactory.js.map +1 -0
  7. package/createAcoGraphQL.d.ts +8 -4
  8. package/createAcoGraphQL.js +56 -96
  9. package/createAcoGraphQL.js.map +1 -1
  10. package/domain/folder/abstractions.d.ts +12 -5
  11. package/domain/folder/abstractions.js +2 -2
  12. package/domain/folder/abstractions.js.map +1 -1
  13. package/exports/api/aco/folder.d.ts +1 -1
  14. package/exports/api/aco/folder.js +1 -1
  15. package/features/ai/CreateFolderTool.d.ts +44 -0
  16. package/features/ai/CreateFolderTool.js +49 -0
  17. package/features/ai/CreateFolderTool.js.map +1 -0
  18. package/features/ai/CreateTeamTool.d.ts +43 -0
  19. package/features/ai/CreateTeamTool.js +47 -0
  20. package/features/ai/CreateTeamTool.js.map +1 -0
  21. package/features/ai/GrantFolderAccessTool.d.ts +72 -0
  22. package/features/ai/GrantFolderAccessTool.js +71 -0
  23. package/features/ai/GrantFolderAccessTool.js.map +1 -0
  24. package/features/ai/ListFoldersTool.d.ts +42 -0
  25. package/features/ai/ListFoldersTool.js +48 -0
  26. package/features/ai/ListFoldersTool.js.map +1 -0
  27. package/features/ai/ListRolesTool.d.ts +34 -0
  28. package/features/ai/ListRolesTool.js +39 -0
  29. package/features/ai/ListRolesTool.js.map +1 -0
  30. package/features/ai/ListTeamsTool.d.ts +34 -0
  31. package/features/ai/ListTeamsTool.js +39 -0
  32. package/features/ai/ListTeamsTool.js.map +1 -0
  33. package/features/ai/RevokeFolderAccessTool.d.ts +58 -0
  34. package/features/ai/RevokeFolderAccessTool.js +60 -0
  35. package/features/ai/RevokeFolderAccessTool.js.map +1 -0
  36. package/features/ai/assertTargetIsUsable.d.ts +10 -0
  37. package/features/ai/assertTargetIsUsable.js +14 -0
  38. package/features/ai/assertTargetIsUsable.js.map +1 -0
  39. package/features/ai/feature.d.ts +12 -0
  40. package/features/ai/feature.js +23 -0
  41. package/features/ai/feature.js.map +1 -0
  42. package/features/ai/index.d.ts +8 -0
  43. package/features/ai/index.js +8 -0
  44. package/features/ai/loadFolderPermissions.d.ts +16 -0
  45. package/features/ai/loadFolderPermissions.js +14 -0
  46. package/features/ai/loadFolderPermissions.js.map +1 -0
  47. package/features/cms/decorators/MoveEntryWithFlpDecorator.d.ts +1 -1
  48. package/features/flp/CreateFlp/CreateFlpUseCase.d.ts +3 -3
  49. package/features/flp/CreateFlp/CreateFlpUseCase.js +4 -4
  50. package/features/flp/CreateFlp/CreateFlpUseCase.js.map +1 -1
  51. package/features/flp/CreateFlp/feature.d.ts +1 -6
  52. package/features/flp/CreateFlp/feature.js +3 -2
  53. package/features/flp/CreateFlp/feature.js.map +1 -1
  54. package/features/flp/DeleteFlp/DeleteFlpUseCase.d.ts +3 -3
  55. package/features/flp/DeleteFlp/DeleteFlpUseCase.js +3 -3
  56. package/features/flp/DeleteFlp/DeleteFlpUseCase.js.map +1 -1
  57. package/features/flp/DeleteFlp/feature.d.ts +1 -6
  58. package/features/flp/DeleteFlp/feature.js +3 -2
  59. package/features/flp/DeleteFlp/feature.js.map +1 -1
  60. package/features/flp/FolderLevelPermissions/FolderLevelPermissions.d.ts +3 -3
  61. package/features/flp/FolderLevelPermissions/FolderLevelPermissions.js +6 -6
  62. package/features/flp/FolderLevelPermissions/FolderLevelPermissions.js.map +1 -1
  63. package/features/flp/FolderLevelPermissions/NoopFolderLevelPermissions.d.ts +25 -0
  64. package/features/flp/FolderLevelPermissions/NoopFolderLevelPermissions.js +48 -0
  65. package/features/flp/FolderLevelPermissions/NoopFolderLevelPermissions.js.map +1 -0
  66. package/features/flp/FolderLevelPermissions/index.d.ts +1 -0
  67. package/features/flp/FolderLevelPermissions/index.js +1 -0
  68. package/features/flp/GetFlp/feature.d.ts +1 -1
  69. package/features/flp/GetFlp/feature.js +3 -2
  70. package/features/flp/GetFlp/feature.js.map +1 -1
  71. package/features/flp/ListFlps/feature.d.ts +1 -1
  72. package/features/flp/ListFlps/feature.js +3 -2
  73. package/features/flp/ListFlps/feature.js.map +1 -1
  74. package/features/flp/UpdateFlp/UpdateFlpUseCase.d.ts +11 -3
  75. package/features/flp/UpdateFlp/UpdateFlpUseCase.js +15 -13
  76. package/features/flp/UpdateFlp/UpdateFlpUseCase.js.map +1 -1
  77. package/features/flp/UpdateFlp/feature.d.ts +1 -6
  78. package/features/flp/UpdateFlp/feature.js +7 -2
  79. package/features/flp/UpdateFlp/feature.js.map +1 -1
  80. package/features/folder/CreateFolder/CreateFolderRepository.d.ts +3 -3
  81. package/features/folder/CreateFolder/CreateFolderRepository.js +10 -7
  82. package/features/folder/CreateFolder/CreateFolderRepository.js.map +1 -1
  83. package/features/folder/DeleteFolder/DeleteFolderRepository.d.ts +3 -3
  84. package/features/folder/DeleteFolder/DeleteFolderRepository.js +6 -5
  85. package/features/folder/DeleteFolder/DeleteFolderRepository.js.map +1 -1
  86. package/features/folder/DeleteFolder/decorators/DeleteFolderWithFolderLevelPermissions.d.ts +1 -1
  87. package/features/folder/EnsureFolderIsEmpty/EnsureFolderIsEmpty.d.ts +1 -3
  88. package/features/folder/EnsureFolderIsEmpty/EnsureFolderIsEmpty.js +4 -7
  89. package/features/folder/EnsureFolderIsEmpty/EnsureFolderIsEmpty.js.map +1 -1
  90. package/features/folder/EnsureHcmsFolderIsEmptyOnDelete/ModelFolderBeforeDeleteHandler.js +4 -1
  91. package/features/folder/EnsureHcmsFolderIsEmptyOnDelete/ModelFolderBeforeDeleteHandler.js.map +1 -1
  92. package/features/folder/FolderModelProvider.d.ts +26 -0
  93. package/features/folder/FolderModelProvider.js +22 -0
  94. package/features/folder/FolderModelProvider.js.map +1 -0
  95. package/features/folder/GetAncestors/GetAncestorsRepository.d.ts +3 -3
  96. package/features/folder/GetAncestors/GetAncestorsRepository.js +6 -5
  97. package/features/folder/GetAncestors/GetAncestorsRepository.js.map +1 -1
  98. package/features/folder/GetFolder/GetFolderRepository.d.ts +3 -3
  99. package/features/folder/GetFolder/GetFolderRepository.js +6 -5
  100. package/features/folder/GetFolder/GetFolderRepository.js.map +1 -1
  101. package/features/folder/GetFolder/decorators/GetFolderWithFolderLevelPermissions.d.ts +8 -8
  102. package/features/folder/GetFolderHierarchy/GetFolderHierarchyRepository.d.ts +3 -3
  103. package/features/folder/GetFolderHierarchy/GetFolderHierarchyRepository.js +10 -8
  104. package/features/folder/GetFolderHierarchy/GetFolderHierarchyRepository.js.map +1 -1
  105. package/features/folder/ListFolders/ListFoldersRepository.d.ts +3 -3
  106. package/features/folder/ListFolders/ListFoldersRepository.js +8 -7
  107. package/features/folder/ListFolders/ListFoldersRepository.js.map +1 -1
  108. package/features/folder/UpdateFolder/UpdateFolderRepository.d.ts +3 -3
  109. package/features/folder/UpdateFolder/UpdateFolderRepository.js +11 -8
  110. package/features/folder/UpdateFolder/UpdateFolderRepository.js.map +1 -1
  111. package/features/folder/shared/abstractions.d.ts +14 -0
  112. package/features/folder/shared/abstractions.js +4 -1
  113. package/features/folder/shared/abstractions.js.map +1 -1
  114. package/filter/filter.gql.d.ts +2 -3
  115. package/filter/filter.gql.js +61 -27
  116. package/filter/filter.gql.js.map +1 -1
  117. package/filter/filter.so.d.ts +10 -2
  118. package/filter/filter.so.js +2 -2
  119. package/filter/filter.so.js.map +1 -1
  120. package/flp/index.d.ts +0 -1
  121. package/flp/index.js +0 -1
  122. package/flp/tasks/createFlp.task.d.ts +2 -2
  123. package/flp/tasks/deleteFlp.task.d.ts +2 -2
  124. package/flp/tasks/index.d.ts +0 -1
  125. package/flp/tasks/index.js +1 -14
  126. package/flp/tasks/index.js.map +1 -1
  127. package/flp/tasks/syncFlp.task.d.ts +2 -2
  128. package/flp/tasks/syncFlp.task.js +7 -1
  129. package/flp/tasks/syncFlp.task.js.map +1 -1
  130. package/flp/tasks/updateFlp.task.d.ts +2 -2
  131. package/folder/folder.gql.d.ts +1 -1
  132. package/folder/folder.gql.js +10 -4
  133. package/folder/folder.gql.js.map +1 -1
  134. package/index.d.ts +1 -6
  135. package/index.js +1 -11
  136. package/package.json +24 -25
  137. package/utils/createOperationsWrapper.d.ts +5 -2
  138. package/utils/createOperationsWrapper.js +2 -2
  139. package/utils/createOperationsWrapper.js.map +1 -1
  140. package/utils/decorators/CmsEntriesCrudDecorators.js +9 -5
  141. package/utils/decorators/CmsEntriesCrudDecorators.js.map +1 -1
  142. package/utils/resolve.d.ts +2 -2
  143. package/utils/resolve.js +1 -1
  144. package/utils/resolve.js.map +1 -1
  145. package/createAcoContext.d.ts +0 -9
  146. package/createAcoContext.js +0 -108
  147. package/createAcoContext.js.map +0 -1
  148. package/createAcoStorageOperations.d.ts +0 -12
  149. package/createAcoStorageOperations.js +0 -9
  150. package/createAcoStorageOperations.js.map +0 -1
  151. package/createAcoTasks.d.ts +0 -1
  152. package/createAcoTasks.js +0 -14
  153. package/createAcoTasks.js.map +0 -1
  154. package/flp/flp.so.d.ts +0 -20
  155. package/flp/flp.so.js +0 -183
  156. package/flp/flp.so.js.map +0 -1
  157. package/index.js.map +0 -1
@@ -0,0 +1,5 @@
1
+ import type { Container } from "@webiny/di";
2
+ export declare const AcoFeature: {
3
+ name: string;
4
+ register(container: Container): void;
5
+ };
package/AcoFeature.js ADDED
@@ -0,0 +1,129 @@
1
+ import { createFeature } from "@webiny/feature/api";
2
+ import { GraphQLSchemaFactory } from "@webiny/api-graphql/graphql/abstractions.js";
3
+ import { IdentityContext } from "@webiny/api-core/features/security/IdentityContext/abstractions.js";
4
+ import { TenantContext } from "@webiny/api-core/features/tenancy/TenantContext/index.js";
5
+ import { HeadlessCms } from "@webiny/api-headless-cms/features/shared/abstractions.js";
6
+ import { addAcoBaseSchema } from "./createAcoGraphQL.js";
7
+ import { addFilterSchema } from "./filter/filter.gql.js";
8
+ import { AcoFolderSchemaFactory } from "./AcoFolderSchemaFactory.js";
9
+ import { FolderModelProvider } from "./features/folder/FolderModelProvider.js";
10
+ import { CmsFlpFeature } from "./features/cms/index.js";
11
+ import { FeatureFlags } from "@webiny/api-core/features/featureFlags/abstractions.js";
12
+ import { CreateFlpTask } from "./flp/tasks/createFlp.task.js";
13
+ import { UpdateFlpTask } from "./flp/tasks/updateFlp.task.js";
14
+ import { DeleteFlpTask } from "./flp/tasks/deleteFlp.task.js";
15
+ import { SyncFlpTask } from "./flp/tasks/syncFlp.task.js";
16
+ import { FolderModel } from "./domain/folder/folder.model.js";
17
+ import { FilterPrivateModel } from "./filter/filter.model.js";
18
+ import { createFilterOperations } from "./filter/filter.so.js";
19
+ import { createFilterCrudMethods } from "./filter/filter.crud.js";
20
+ import { createFlpCrudMethods } from "./flp/index.js";
21
+ import { FolderLevelPermissions, FolderLevelPermissionsFeature } from "./features/flp/FolderLevelPermissions/index.js";
22
+ import { UpdateFolderFeature } from "./features/folder/UpdateFolder/index.js";
23
+ import { DeleteFolderFeature } from "./features/folder/DeleteFolder/index.js";
24
+ import { CreateFolderFeature } from "./features/folder/CreateFolder/index.js";
25
+ import { GetFolderFeature } from "./features/folder/GetFolder/index.js";
26
+ import { ListFoldersFeature } from "./features/folder/ListFolders/index.js";
27
+ import { GetFolderHierarchyFeature } from "./features/folder/GetFolderHierarchy/index.js";
28
+ import { GetAncestorsFeature } from "./features/folder/GetAncestors/index.js";
29
+ import { UpdateFlpOnFolderUpdatedFeature } from "./features/flp/UpdateFlpOnFolderUpdated/index.js";
30
+ import { DeleteFlpOnFolderDeletedFeature } from "./features/flp/DeleteFlpOnFolderDeleted/index.js";
31
+ import { EnsureHcmsFolderIsEmptyOnDeleteFeature } from "./features/folder/EnsureHcmsFolderIsEmptyOnDelete/index.js";
32
+ import { CreateFlpFeature } from "./features/flp/CreateFlp/index.js";
33
+ import { DeleteFlpFeature } from "./features/flp/DeleteFlp/index.js";
34
+ import { UpdateFlpFeature } from "./features/flp/UpdateFlp/index.js";
35
+ import { EnsureFolderIsEmptyOnDeleteFeature } from "./features/folder/EnsureFolderIsEmptyOnDelete/index.js";
36
+ import { AcoFilterCrud, AcoFlpCrud, FilterStorageOperations, FlpStorageOperations } from "./features/folder/shared/abstractions.js";
37
+ import { ListFlpsFeature } from "./features/flp/ListFlps/feature.js";
38
+ import { GetFlpFeature } from "./features/flp/GetFlp/feature.js";
39
+ import { ListFolderLevelPermissionsTargetsFeature } from "./features/folder/ListFolderLevelPermissionsTargets/feature.js";
40
+ import { CreateFlpOnFolderCreatedFeature } from "./features/flp/CreateFlpOnFolderCreated/index.js";
41
+ import { EnsureFolderIsEmptyFeature } from "./features/folder/EnsureFolderIsEmpty/feature.js";
42
+ import { AcoAiToolsFeature } from "./features/ai/index.js";
43
+ class AcoSchemaFactoryImpl {
44
+ async execute(builder) {
45
+ addAcoBaseSchema(builder);
46
+ addFilterSchema(builder);
47
+ return builder;
48
+ }
49
+ }
50
+ const AcoSchemaFactory = GraphQLSchemaFactory.createImplementation({
51
+ implementation: AcoSchemaFactoryImpl,
52
+ dependencies: []
53
+ });
54
+ const AcoFeature = createFeature({
55
+ name: "Aco",
56
+ register (container) {
57
+ container.register(FolderModel);
58
+ AcoAiToolsFeature.register(container);
59
+ container.register(FilterPrivateModel);
60
+ container.register(CreateFlpTask);
61
+ container.register(UpdateFlpTask);
62
+ container.register(DeleteFlpTask);
63
+ container.register(SyncFlpTask);
64
+ FolderLevelPermissionsFeature.register(container);
65
+ CreateFolderFeature.register(container);
66
+ UpdateFolderFeature.register(container);
67
+ DeleteFolderFeature.register(container);
68
+ GetFolderFeature.register(container);
69
+ ListFoldersFeature.register(container);
70
+ ListFolderLevelPermissionsTargetsFeature.register(container);
71
+ GetFolderHierarchyFeature.register(container);
72
+ GetAncestorsFeature.register(container);
73
+ EnsureFolderIsEmptyFeature.register(container);
74
+ CreateFlpFeature.register(container);
75
+ UpdateFlpFeature.register(container);
76
+ DeleteFlpFeature.register(container);
77
+ ListFlpsFeature.register(container);
78
+ GetFlpFeature.register(container);
79
+ CreateFlpOnFolderCreatedFeature.register(container);
80
+ UpdateFlpOnFolderUpdatedFeature.register(container);
81
+ DeleteFlpOnFolderDeletedFeature.register(container);
82
+ EnsureFolderIsEmptyOnDeleteFeature.register(container);
83
+ EnsureHcmsFolderIsEmptyOnDeleteFeature.register(container);
84
+ const getTenant = ()=>container.resolve(TenantContext).getTenant();
85
+ let storageOperations;
86
+ const getStorageOperations = ()=>{
87
+ if (!storageOperations) {
88
+ const cms = container.resolve(HeadlessCms);
89
+ const identityContext = container.resolve(IdentityContext);
90
+ storageOperations = {
91
+ filter: createFilterOperations({
92
+ cms,
93
+ identityContext,
94
+ container
95
+ }),
96
+ flp: container.resolve(FlpStorageOperations)
97
+ };
98
+ }
99
+ return storageOperations;
100
+ };
101
+ let flpCrudMethods;
102
+ const getFlpCrudMethods = ()=>{
103
+ if (!flpCrudMethods) flpCrudMethods = createFlpCrudMethods({
104
+ getTenant,
105
+ storageOperations: getStorageOperations()
106
+ });
107
+ return flpCrudMethods;
108
+ };
109
+ container.registerFactory(AcoFlpCrud, ()=>getFlpCrudMethods());
110
+ container.registerFactory(FilterStorageOperations, ()=>getStorageOperations().filter);
111
+ let filterCrudMethods;
112
+ container.registerFactory(AcoFilterCrud, ()=>{
113
+ if (!filterCrudMethods) filterCrudMethods = createFilterCrudMethods({
114
+ container,
115
+ getTenant,
116
+ storageOperations: getStorageOperations(),
117
+ folderLevelPermissions: container.resolve(FolderLevelPermissions)
118
+ });
119
+ return filterCrudMethods;
120
+ });
121
+ container.register(FolderModelProvider);
122
+ if (container.resolve(FeatureFlags).get().isEnabled("advancedAccessControlLayer.folderLevelPermissions")) CmsFlpFeature.register(container);
123
+ container.register(AcoSchemaFactory);
124
+ container.register(AcoFolderSchemaFactory);
125
+ }
126
+ });
127
+ export { AcoFeature };
128
+
129
+ //# sourceMappingURL=AcoFeature.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AcoFeature.js","sources":["../src/AcoFeature.ts"],"sourcesContent":["import { createFeature } from \"@webiny/feature/api\";\nimport { GraphQLSchemaFactory } from \"@webiny/api-graphql/graphql/abstractions.js\";\nimport type { IGraphQLSchemaBuilder } from \"@webiny/api-graphql/features/GraphQLSchemaBuilder/abstractions.js\";\nimport type { Container } from \"@webiny/di\";\nimport { IdentityContext } from \"@webiny/api-core/features/security/IdentityContext/abstractions.js\";\nimport { TenantContext } from \"@webiny/api-core/features/tenancy/TenantContext/index.js\";\nimport { HeadlessCms } from \"@webiny/api-headless-cms/features/shared/abstractions.js\";\nimport { addAcoBaseSchema } from \"./createAcoGraphQL.js\";\nimport { addFilterSchema } from \"~/filter/filter.gql.js\";\nimport { AcoFolderSchemaFactory } from \"./AcoFolderSchemaFactory.js\";\nimport { FolderModelProvider } from \"~/features/folder/FolderModelProvider.js\";\nimport { CmsFlpFeature } from \"~/features/cms/index.js\";\nimport { FeatureFlags } from \"@webiny/api-core/features/featureFlags/abstractions.js\";\nimport { CreateFlpTask } from \"~/flp/tasks/createFlp.task.js\";\nimport { UpdateFlpTask } from \"~/flp/tasks/updateFlp.task.js\";\nimport { DeleteFlpTask } from \"~/flp/tasks/deleteFlp.task.js\";\nimport { SyncFlpTask } from \"~/flp/tasks/syncFlp.task.js\";\nimport type { AcoStorageOperations } from \"~/types.js\";\nimport type { Tenant } from \"@webiny/api-core/types/tenancy.js\";\nimport { FolderModel } from \"~/domain/folder/folder.model.js\";\nimport { FilterPrivateModel } from \"~/filter/filter.model.js\";\n// Facade wiring (moved here from createAcoContext so the ACO facade can be a lazy DI factory).\nimport { createFilterOperations } from \"~/filter/filter.so.js\";\nimport { createFilterCrudMethods } from \"~/filter/filter.crud.js\";\nimport { createFlpCrudMethods } from \"~/flp/index.js\";\nimport {\n FolderLevelPermissions,\n FolderLevelPermissionsFeature\n} from \"~/features/flp/FolderLevelPermissions/index.js\";\nimport { UpdateFolderFeature } from \"~/features/folder/UpdateFolder/index.js\";\nimport { DeleteFolderFeature } from \"~/features/folder/DeleteFolder/index.js\";\nimport { CreateFolderFeature } from \"~/features/folder/CreateFolder/index.js\";\nimport { GetFolderFeature } from \"~/features/folder/GetFolder/index.js\";\nimport { ListFoldersFeature } from \"~/features/folder/ListFolders/index.js\";\nimport { GetFolderHierarchyFeature } from \"~/features/folder/GetFolderHierarchy/index.js\";\nimport { GetAncestorsFeature } from \"~/features/folder/GetAncestors/index.js\";\nimport { UpdateFlpOnFolderUpdatedFeature } from \"~/features/flp/UpdateFlpOnFolderUpdated/index.js\";\nimport { DeleteFlpOnFolderDeletedFeature } from \"~/features/flp/DeleteFlpOnFolderDeleted/index.js\";\nimport { EnsureHcmsFolderIsEmptyOnDeleteFeature } from \"~/features/folder/EnsureHcmsFolderIsEmptyOnDelete/index.js\";\nimport { CreateFlpFeature } from \"~/features/flp/CreateFlp/index.js\";\nimport { DeleteFlpFeature } from \"~/features/flp/DeleteFlp/index.js\";\nimport { UpdateFlpFeature } from \"~/features/flp/UpdateFlp/index.js\";\nimport { EnsureFolderIsEmptyOnDeleteFeature } from \"~/features/folder/EnsureFolderIsEmptyOnDelete/index.js\";\nimport {\n AcoFilterCrud,\n AcoFlpCrud,\n FilterStorageOperations,\n FlpStorageOperations\n} from \"~/features/folder/shared/abstractions.js\";\nimport { ListFlpsFeature } from \"~/features/flp/ListFlps/feature.js\";\nimport { GetFlpFeature } from \"~/features/flp/GetFlp/feature.js\";\nimport { ListFolderLevelPermissionsTargetsFeature } from \"~/features/folder/ListFolderLevelPermissionsTargets/feature.js\";\nimport { CreateFlpOnFolderCreatedFeature } from \"~/features/flp/CreateFlpOnFolderCreated/index.js\";\nimport { EnsureFolderIsEmptyFeature } from \"~/features/folder/EnsureFolderIsEmpty/feature.js\";\nimport { AcoAiToolsFeature } from \"~/features/ai/index.js\";\n\nclass AcoSchemaFactoryImpl implements GraphQLSchemaFactory.Interface {\n async execute(builder: IGraphQLSchemaBuilder): Promise<IGraphQLSchemaBuilder> {\n // Static ACO base + filter schema (DI-native contributors declaring their deps). The\n // dynamic, per-tenant folder schema is built by AcoFolderSchemaFactory.\n addAcoBaseSchema(builder);\n addFilterSchema(builder);\n return builder;\n }\n}\n\nconst AcoSchemaFactory = GraphQLSchemaFactory.createImplementation({\n implementation: AcoSchemaFactoryImpl,\n dependencies: []\n});\n\nexport const AcoFeature = createFeature({\n name: \"Aco\",\n register(container: Container) {\n container.register(FolderModel);\n AcoAiToolsFeature.register(container);\n container.register(FilterPrivateModel);\n\n // Background task definitions — pure wiring, no tenant/identity needed.\n container.register(CreateFlpTask);\n container.register(UpdateFlpTask);\n container.register(DeleteFlpTask);\n container.register(SyncFlpTask);\n\n // Folder + FLP use-case features — pure DI wiring (all lazy). Moved out of the per-request\n // initializer so they're registered for every event, not only GraphQL requests.\n FolderLevelPermissionsFeature.register(container);\n CreateFolderFeature.register(container);\n UpdateFolderFeature.register(container);\n DeleteFolderFeature.register(container);\n GetFolderFeature.register(container);\n ListFoldersFeature.register(container);\n ListFolderLevelPermissionsTargetsFeature.register(container);\n GetFolderHierarchyFeature.register(container);\n GetAncestorsFeature.register(container);\n EnsureFolderIsEmptyFeature.register(container);\n CreateFlpFeature.register(container);\n UpdateFlpFeature.register(container);\n DeleteFlpFeature.register(container);\n ListFlpsFeature.register(container);\n GetFlpFeature.register(container);\n CreateFlpOnFolderCreatedFeature.register(container);\n UpdateFlpOnFolderUpdatedFeature.register(container);\n DeleteFlpOnFolderDeletedFeature.register(container);\n EnsureFolderIsEmptyOnDeleteFeature.register(container);\n EnsureHcmsFolderIsEmptyOnDeleteFeature.register(container);\n\n // ===== Lazy ACO facade =====\n // Built on first resolve (post-auth) so the HeadlessCms facade (also lazy) is resolved on\n // demand. Memoised per request container. Consumers resolve AcoFlpCrud / AcoFilterCrud /\n // FilterStorageOperations via DI.\n const getTenant = (): Tenant => container.resolve(TenantContext).getTenant();\n\n let storageOperations: AcoStorageOperations | undefined;\n const getStorageOperations = (): AcoStorageOperations => {\n if (!storageOperations) {\n const cms = container.resolve(HeadlessCms);\n const identityContext = container.resolve(IdentityContext);\n storageOperations = {\n filter: createFilterOperations({ cms, identityContext, container }),\n flp: container.resolve(FlpStorageOperations)\n };\n }\n return storageOperations;\n };\n\n let flpCrudMethods: ReturnType<typeof createFlpCrudMethods> | undefined;\n const getFlpCrudMethods = () => {\n if (!flpCrudMethods) {\n flpCrudMethods = createFlpCrudMethods({\n getTenant,\n storageOperations: getStorageOperations()\n });\n }\n return flpCrudMethods;\n };\n container.registerFactory(AcoFlpCrud, () => getFlpCrudMethods());\n container.registerFactory(FilterStorageOperations, () => getStorageOperations().filter);\n\n let filterCrudMethods: ReturnType<typeof createFilterCrudMethods> | undefined;\n container.registerFactory(AcoFilterCrud, () => {\n if (!filterCrudMethods) {\n filterCrudMethods = createFilterCrudMethods({\n container,\n getTenant,\n storageOperations: getStorageOperations(),\n folderLevelPermissions: container.resolve(FolderLevelPermissions)\n });\n }\n return filterCrudMethods;\n });\n\n // The per-tenant folder model is resolved on demand — see FolderModelProvider.\n container.register(FolderModelProvider);\n\n // CMS-entry folder-level-permission decorators, feature-flag gated. These must be\n // registered before any CMS-entry abstraction they wrap is first resolved, which is why\n // they used to sit in a pre-resolver initializer. Register time is strictly earlier and the\n // gate is valid here: the WCP license is refreshed before any feature registers (see\n // registerApiRequestStack).\n if (\n container\n .resolve(FeatureFlags)\n .get()\n .isEnabled(\"advancedAccessControlLayer.folderLevelPermissions\")\n ) {\n CmsFlpFeature.register(container);\n }\n\n container.register(AcoSchemaFactory);\n container.register(AcoFolderSchemaFactory);\n }\n});\n"],"names":["AcoSchemaFactoryImpl","builder","addAcoBaseSchema","addFilterSchema","AcoSchemaFactory","GraphQLSchemaFactory","AcoFeature","createFeature","container","FolderModel","AcoAiToolsFeature","FilterPrivateModel","CreateFlpTask","UpdateFlpTask","DeleteFlpTask","SyncFlpTask","FolderLevelPermissionsFeature","CreateFolderFeature","UpdateFolderFeature","DeleteFolderFeature","GetFolderFeature","ListFoldersFeature","ListFolderLevelPermissionsTargetsFeature","GetFolderHierarchyFeature","GetAncestorsFeature","EnsureFolderIsEmptyFeature","CreateFlpFeature","UpdateFlpFeature","DeleteFlpFeature","ListFlpsFeature","GetFlpFeature","CreateFlpOnFolderCreatedFeature","UpdateFlpOnFolderUpdatedFeature","DeleteFlpOnFolderDeletedFeature","EnsureFolderIsEmptyOnDeleteFeature","EnsureHcmsFolderIsEmptyOnDeleteFeature","getTenant","TenantContext","storageOperations","getStorageOperations","cms","HeadlessCms","identityContext","IdentityContext","createFilterOperations","FlpStorageOperations","flpCrudMethods","getFlpCrudMethods","createFlpCrudMethods","AcoFlpCrud","FilterStorageOperations","filterCrudMethods","AcoFilterCrud","createFilterCrudMethods","FolderLevelPermissions","FolderModelProvider","FeatureFlags","CmsFlpFeature","AcoFolderSchemaFactory"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwDA,MAAMA;IACF,MAAM,QAAQC,OAA8B,EAAkC;QAG1EC,iBAAiBD;QACjBE,gBAAgBF;QAChB,OAAOA;IACX;AACJ;AAEA,MAAMG,mBAAmBC,qBAAqB,oBAAoB,CAAC;IAC/D,gBAAgBL;IAChB,cAAc,EAAE;AACpB;AAEO,MAAMM,aAAaC,cAAc;IACpC,MAAM;IACN,UAASC,SAAoB;QACzBA,UAAU,QAAQ,CAACC;QACnBC,kBAAkB,QAAQ,CAACF;QAC3BA,UAAU,QAAQ,CAACG;QAGnBH,UAAU,QAAQ,CAACI;QACnBJ,UAAU,QAAQ,CAACK;QACnBL,UAAU,QAAQ,CAACM;QACnBN,UAAU,QAAQ,CAACO;QAInBC,8BAA8B,QAAQ,CAACR;QACvCS,oBAAoB,QAAQ,CAACT;QAC7BU,oBAAoB,QAAQ,CAACV;QAC7BW,oBAAoB,QAAQ,CAACX;QAC7BY,iBAAiB,QAAQ,CAACZ;QAC1Ba,mBAAmB,QAAQ,CAACb;QAC5Bc,yCAAyC,QAAQ,CAACd;QAClDe,0BAA0B,QAAQ,CAACf;QACnCgB,oBAAoB,QAAQ,CAAChB;QAC7BiB,2BAA2B,QAAQ,CAACjB;QACpCkB,iBAAiB,QAAQ,CAAClB;QAC1BmB,iBAAiB,QAAQ,CAACnB;QAC1BoB,iBAAiB,QAAQ,CAACpB;QAC1BqB,gBAAgB,QAAQ,CAACrB;QACzBsB,cAAc,QAAQ,CAACtB;QACvBuB,gCAAgC,QAAQ,CAACvB;QACzCwB,gCAAgC,QAAQ,CAACxB;QACzCyB,gCAAgC,QAAQ,CAACzB;QACzC0B,mCAAmC,QAAQ,CAAC1B;QAC5C2B,uCAAuC,QAAQ,CAAC3B;QAMhD,MAAM4B,YAAY,IAAc5B,UAAU,OAAO,CAAC6B,eAAe,SAAS;QAE1E,IAAIC;QACJ,MAAMC,uBAAuB;YACzB,IAAI,CAACD,mBAAmB;gBACpB,MAAME,MAAMhC,UAAU,OAAO,CAACiC;gBAC9B,MAAMC,kBAAkBlC,UAAU,OAAO,CAACmC;gBAC1CL,oBAAoB;oBAChB,QAAQM,uBAAuB;wBAAEJ;wBAAKE;wBAAiBlC;oBAAU;oBACjE,KAAKA,UAAU,OAAO,CAACqC;gBAC3B;YACJ;YACA,OAAOP;QACX;QAEA,IAAIQ;QACJ,MAAMC,oBAAoB;YACtB,IAAI,CAACD,gBACDA,iBAAiBE,qBAAqB;gBAClCZ;gBACA,mBAAmBG;YACvB;YAEJ,OAAOO;QACX;QACAtC,UAAU,eAAe,CAACyC,YAAY,IAAMF;QAC5CvC,UAAU,eAAe,CAAC0C,yBAAyB,IAAMX,uBAAuB,MAAM;QAEtF,IAAIY;QACJ3C,UAAU,eAAe,CAAC4C,eAAe;YACrC,IAAI,CAACD,mBACDA,oBAAoBE,wBAAwB;gBACxC7C;gBACA4B;gBACA,mBAAmBG;gBACnB,wBAAwB/B,UAAU,OAAO,CAAC8C;YAC9C;YAEJ,OAAOH;QACX;QAGA3C,UAAU,QAAQ,CAAC+C;QAOnB,IACI/C,UACK,OAAO,CAACgD,cACR,GAAG,GACH,SAAS,CAAC,sDAEfC,cAAc,QAAQ,CAACjD;QAG3BA,UAAU,QAAQ,CAACJ;QACnBI,UAAU,QAAQ,CAACkD;IACvB;AACJ"}
@@ -0,0 +1,30 @@
1
+ import { CoreGraphQLSchemaFactory } from "@webiny/api-graphql/graphql/abstractions.js";
2
+ import type { IGraphQLSchemaBuilder } from "@webiny/api-graphql/features/GraphQLSchemaBuilder/abstractions.js";
3
+ import { TenantContext } from "@webiny/api-core/features/tenancy/TenantContext/index.js";
4
+ import { IdentityContext } from "@webiny/api-core/features/security/IdentityContext/abstractions.js";
5
+ import { ListModelsUseCase } from "@webiny/api-headless-cms/features/contentModel/ListModels/index.js";
6
+ import { CmsModelFieldToGraphQLRegistry } from "@webiny/api-headless-cms/exports/api/cms/graphql.js";
7
+ import { FolderModelProvider } from "./domain/folder/abstractions.js";
8
+ /**
9
+ * Builds the dynamic folder GraphQL schema — the `Folder` type's fields are rendered from the
10
+ * tenant's folder model, so the shape differs per tenant.
11
+ *
12
+ * Previously done by `AcoInitializer`, which had to run as a per-request hook before any resolver:
13
+ * it fetched the model, then registered one `CoreGraphQLSchemaFactory` per generated plugin. That
14
+ * indirection is unnecessary — `CoreGraphQLSchemaFactory.execute()` is already awaited by
15
+ * `GraphQLSchemaComposer`, so this factory can be registered once at compose time and do its async
16
+ * work inside `execute()`, at the moment the schema is actually built.
17
+ */
18
+ declare class AcoFolderSchemaFactoryImpl implements CoreGraphQLSchemaFactory.Interface {
19
+ private folderModelProvider;
20
+ private listModels;
21
+ private fieldRegistry;
22
+ private identityContext;
23
+ private tenantContext;
24
+ constructor(folderModelProvider: FolderModelProvider.Interface, listModels: ListModelsUseCase.Interface, fieldRegistry: CmsModelFieldToGraphQLRegistry.Interface, identityContext: IdentityContext.Interface, tenantContext: TenantContext.Interface);
25
+ execute(builder: IGraphQLSchemaBuilder): Promise<IGraphQLSchemaBuilder>;
26
+ }
27
+ export declare const AcoFolderSchemaFactory: typeof AcoFolderSchemaFactoryImpl & {
28
+ __abstraction: import("@webiny/di").Abstraction<import("@webiny/api-graphql/graphql/abstractions.core").ICoreGraphQLSchemaFactory>;
29
+ };
30
+ export {};
@@ -0,0 +1,64 @@
1
+ import { GraphQLSchemaPlugin } from "@webiny/api-graphql";
2
+ import { CoreGraphQLSchemaFactory } from "@webiny/api-graphql/graphql/abstractions.js";
3
+ import { TenantContext } from "@webiny/api-core/features/tenancy/TenantContext/index.js";
4
+ import { IdentityContext } from "@webiny/api-core/features/security/IdentityContext/abstractions.js";
5
+ import { ListModelsUseCase } from "@webiny/api-headless-cms/features/contentModel/ListModels/index.js";
6
+ import { CmsModelFieldToGraphQLRegistry } from "@webiny/api-headless-cms/exports/api/cms/graphql.js";
7
+ import { createGraphQLSchemaPluginFromFieldPlugins } from "@webiny/api-headless-cms/utils/getSchemaFromFieldPlugins.js";
8
+ import { FolderModelProvider } from "./domain/folder/abstractions.js";
9
+ import { createFoldersSchema } from "./folder/folder.gql.js";
10
+ class AcoFolderSchemaFactoryImpl {
11
+ constructor(folderModelProvider, listModels, fieldRegistry, identityContext, tenantContext){
12
+ this.folderModelProvider = folderModelProvider;
13
+ this.listModels = listModels;
14
+ this.fieldRegistry = fieldRegistry;
15
+ this.identityContext = identityContext;
16
+ this.tenantContext = tenantContext;
17
+ }
18
+ async execute(builder) {
19
+ if (!this.tenantContext.getTenant()) return builder;
20
+ const model = await this.folderModelProvider.get();
21
+ const models = await this.identityContext.withoutAuthorization(async ()=>{
22
+ const result = await this.listModels.execute();
23
+ if (result.isFail()) throw result.error;
24
+ return result.value;
25
+ });
26
+ const fieldPlugins = createGraphQLSchemaPluginFromFieldPlugins({
27
+ models,
28
+ type: "manage",
29
+ fieldRegistry: this.fieldRegistry,
30
+ createPlugin: ({ schema, type, fieldType })=>{
31
+ const plugin = new GraphQLSchemaPlugin(schema);
32
+ plugin.name = `aco.graphql.folder.schema.${type}.field.${fieldType}`;
33
+ return plugin;
34
+ }
35
+ });
36
+ const folderPlugin = createFoldersSchema({
37
+ model,
38
+ models,
39
+ fieldRegistry: this.fieldRegistry
40
+ });
41
+ for (const plugin of [
42
+ ...fieldPlugins,
43
+ folderPlugin
44
+ ]){
45
+ if (plugin.schema.typeDefs) builder.addTypeDefs(plugin.schema.typeDefs);
46
+ if (plugin.schema.resolvers) builder.addLegacyResolvers(plugin.schema.resolvers);
47
+ if (plugin.schema.resolverDecorators) for (const [path, decorators] of Object.entries(plugin.schema.resolverDecorators))for (const decorator of decorators)builder.addResolverDecorator(path, decorator);
48
+ }
49
+ return builder;
50
+ }
51
+ }
52
+ const AcoFolderSchemaFactory = CoreGraphQLSchemaFactory.createImplementation({
53
+ implementation: AcoFolderSchemaFactoryImpl,
54
+ dependencies: [
55
+ FolderModelProvider,
56
+ ListModelsUseCase,
57
+ CmsModelFieldToGraphQLRegistry,
58
+ IdentityContext,
59
+ TenantContext
60
+ ]
61
+ });
62
+ export { AcoFolderSchemaFactory };
63
+
64
+ //# sourceMappingURL=AcoFolderSchemaFactory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AcoFolderSchemaFactory.js","sources":["../src/AcoFolderSchemaFactory.ts"],"sourcesContent":["import { GraphQLSchemaPlugin } from \"@webiny/api-graphql\";\nimport { CoreGraphQLSchemaFactory } from \"@webiny/api-graphql/graphql/abstractions.js\";\nimport type { IGraphQLSchemaBuilder } from \"@webiny/api-graphql/features/GraphQLSchemaBuilder/abstractions.js\";\nimport type { IGraphQLSchemaPlugin } from \"@webiny/api-graphql/plugins/GraphQLSchemaPlugin.js\";\nimport { TenantContext } from \"@webiny/api-core/features/tenancy/TenantContext/index.js\";\nimport { IdentityContext } from \"@webiny/api-core/features/security/IdentityContext/abstractions.js\";\nimport { ListModelsUseCase } from \"@webiny/api-headless-cms/features/contentModel/ListModels/index.js\";\nimport { CmsModelFieldToGraphQLRegistry } from \"@webiny/api-headless-cms/exports/api/cms/graphql.js\";\nimport { createGraphQLSchemaPluginFromFieldPlugins } from \"@webiny/api-headless-cms/utils/getSchemaFromFieldPlugins.js\";\nimport { FolderModelProvider } from \"~/domain/folder/abstractions.js\";\nimport { createFoldersSchema } from \"~/folder/folder.gql.js\";\n\n/**\n * Builds the dynamic folder GraphQL schema — the `Folder` type's fields are rendered from the\n * tenant's folder model, so the shape differs per tenant.\n *\n * Previously done by `AcoInitializer`, which had to run as a per-request hook before any resolver:\n * it fetched the model, then registered one `CoreGraphQLSchemaFactory` per generated plugin. That\n * indirection is unnecessary — `CoreGraphQLSchemaFactory.execute()` is already awaited by\n * `GraphQLSchemaComposer`, so this factory can be registered once at compose time and do its async\n * work inside `execute()`, at the moment the schema is actually built.\n */\nclass AcoFolderSchemaFactoryImpl implements CoreGraphQLSchemaFactory.Interface {\n constructor(\n private folderModelProvider: FolderModelProvider.Interface,\n private listModels: ListModelsUseCase.Interface,\n private fieldRegistry: CmsModelFieldToGraphQLRegistry.Interface,\n private identityContext: IdentityContext.Interface,\n private tenantContext: TenantContext.Interface\n ) {}\n\n async execute(builder: IGraphQLSchemaBuilder): Promise<IGraphQLSchemaBuilder> {\n // On a fresh project there is no tenant until installation completes, and there is no model\n // to render a schema from. (This is what `isHeadlessCmsReady` checked in the initializer.)\n if (!this.tenantContext.getTenant()) {\n return builder;\n }\n\n const model = await this.folderModelProvider.get();\n\n // The model list feeds `ref` field rendering, so it must be the COMPLETE set — access\n // control filters models by permission, which would otherwise make the generated schema\n // vary by identity. Hence the unauthorized read, exactly as the initializer did.\n const models = await this.identityContext.withoutAuthorization(async () => {\n const result = await this.listModels.execute();\n if (result.isFail()) {\n throw result.error;\n }\n return result.value;\n });\n\n const fieldPlugins = createGraphQLSchemaPluginFromFieldPlugins({\n models,\n type: \"manage\",\n fieldRegistry: this.fieldRegistry,\n createPlugin: ({ schema, type, fieldType }) => {\n const plugin = new GraphQLSchemaPlugin(schema);\n plugin.name = `aco.graphql.folder.schema.${type}.field.${fieldType}`;\n return plugin;\n }\n });\n\n const folderPlugin = createFoldersSchema({\n model,\n models,\n fieldRegistry: this.fieldRegistry\n });\n\n for (const plugin of [...fieldPlugins, folderPlugin] as IGraphQLSchemaPlugin[]) {\n if (plugin.schema.typeDefs) {\n builder.addTypeDefs(plugin.schema.typeDefs);\n }\n if (plugin.schema.resolvers) {\n builder.addLegacyResolvers(plugin.schema.resolvers as Record<string, any>);\n }\n if (plugin.schema.resolverDecorators) {\n for (const [path, decorators] of Object.entries(plugin.schema.resolverDecorators)) {\n for (const decorator of decorators as any[]) {\n builder.addResolverDecorator(path, decorator);\n }\n }\n }\n }\n\n return builder;\n }\n}\n\nexport const AcoFolderSchemaFactory = CoreGraphQLSchemaFactory.createImplementation({\n implementation: AcoFolderSchemaFactoryImpl,\n dependencies: [\n FolderModelProvider,\n ListModelsUseCase,\n CmsModelFieldToGraphQLRegistry,\n IdentityContext,\n TenantContext\n ]\n});\n"],"names":["AcoFolderSchemaFactoryImpl","folderModelProvider","listModels","fieldRegistry","identityContext","tenantContext","builder","model","models","result","fieldPlugins","createGraphQLSchemaPluginFromFieldPlugins","schema","type","fieldType","plugin","GraphQLSchemaPlugin","folderPlugin","createFoldersSchema","path","decorators","Object","decorator","AcoFolderSchemaFactory","CoreGraphQLSchemaFactory","FolderModelProvider","ListModelsUseCase","CmsModelFieldToGraphQLRegistry","IdentityContext","TenantContext"],"mappings":";;;;;;;;;AAsBA,MAAMA;IACF,YACYC,mBAAkD,EAClDC,UAAuC,EACvCC,aAAuD,EACvDC,eAA0C,EAC1CC,aAAsC,CAChD;aALUJ,mBAAmB,GAAnBA;aACAC,UAAU,GAAVA;aACAC,aAAa,GAAbA;aACAC,eAAe,GAAfA;aACAC,aAAa,GAAbA;IACT;IAEH,MAAM,QAAQC,OAA8B,EAAkC;QAG1E,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,SAAS,IAC7B,OAAOA;QAGX,MAAMC,QAAQ,MAAM,IAAI,CAAC,mBAAmB,CAAC,GAAG;QAKhD,MAAMC,SAAS,MAAM,IAAI,CAAC,eAAe,CAAC,oBAAoB,CAAC;YAC3D,MAAMC,SAAS,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO;YAC5C,IAAIA,OAAO,MAAM,IACb,MAAMA,OAAO,KAAK;YAEtB,OAAOA,OAAO,KAAK;QACvB;QAEA,MAAMC,eAAeC,0CAA0C;YAC3DH;YACA,MAAM;YACN,eAAe,IAAI,CAAC,aAAa;YACjC,cAAc,CAAC,EAAEI,MAAM,EAAEC,IAAI,EAAEC,SAAS,EAAE;gBACtC,MAAMC,SAAS,IAAIC,oBAAoBJ;gBACvCG,OAAO,IAAI,GAAG,CAAC,0BAA0B,EAAEF,KAAK,OAAO,EAAEC,WAAW;gBACpE,OAAOC;YACX;QACJ;QAEA,MAAME,eAAeC,oBAAoB;YACrCX;YACAC;YACA,eAAe,IAAI,CAAC,aAAa;QACrC;QAEA,KAAK,MAAMO,UAAU;eAAIL;YAAcO;SAAa,CAA4B;YAC5E,IAAIF,OAAO,MAAM,CAAC,QAAQ,EACtBT,QAAQ,WAAW,CAACS,OAAO,MAAM,CAAC,QAAQ;YAE9C,IAAIA,OAAO,MAAM,CAAC,SAAS,EACvBT,QAAQ,kBAAkB,CAACS,OAAO,MAAM,CAAC,SAAS;YAEtD,IAAIA,OAAO,MAAM,CAAC,kBAAkB,EAChC,KAAK,MAAM,CAACI,MAAMC,WAAW,IAAIC,OAAO,OAAO,CAACN,OAAO,MAAM,CAAC,kBAAkB,EAC5E,KAAK,MAAMO,aAAaF,WACpBd,QAAQ,oBAAoB,CAACa,MAAMG;QAInD;QAEA,OAAOhB;IACX;AACJ;AAEO,MAAMiB,yBAAyBC,yBAAyB,oBAAoB,CAAC;IAChF,gBAAgBxB;IAChB,cAAc;QACVyB;QACAC;QACAC;QACAC;QACAC;KACH;AACL"}
@@ -1,4 +1,8 @@
1
- import { GraphQLSchemaPlugin } from "@webiny/handler-graphql";
2
- import type { AcoContext } from "./types.js";
3
- import { ContextPlugin } from "@webiny/api";
4
- export declare const createAcoGraphQL: () => (ContextPlugin<AcoContext> | GraphQLSchemaPlugin<AcoContext>)[];
1
+ import type { IGraphQLSchemaBuilder } from "@webiny/api-graphql/features/GraphQLSchemaBuilder/abstractions.js";
2
+ /**
3
+ * The static ACO base schema (root Query.aco / Mutation.aco wrappers + shared types). The dynamic
4
+ * folder schema (field plugins + folders schema) is built by AcoFolderSchemaFactory, which awaits
5
+ * the per-tenant folder model when the schema is built. The filter schema comes from
6
+ * addFilterSchema.
7
+ */
8
+ export declare const addAcoBaseSchema: (builder: IGraphQLSchemaBuilder) => void;
@@ -1,110 +1,70 @@
1
- import { GraphQLSchemaPlugin } from "@webiny/handler-graphql";
2
- import { filterSchema } from "./filter/filter.gql.js";
3
- import { createFoldersSchema } from "./folder/folder.gql.js";
4
- import { ContextPlugin } from "@webiny/api";
5
- import { isHeadlessCmsReady } from "@webiny/api-headless-cms";
6
- import { createGraphQLSchemaPluginFromFieldPlugins } from "@webiny/api-headless-cms/utils/getSchemaFromFieldPlugins.js";
7
- import { FOLDER_MODEL_ID } from "./domain/folder/folder.model.js";
8
- import { CmsModelFieldToGraphQLRegistry } from "@webiny/api-headless-cms/exports/api/cms/graphql.js";
9
- const emptyResolver = ()=>({});
10
- const baseSchema = new GraphQLSchemaPlugin({
11
- typeDefs: `
12
- type AcoQuery {
13
- _empty: String
14
- }
1
+ const BASE_TYPE_DEFS = `
2
+ type AcoQuery {
3
+ _empty: String
4
+ }
15
5
 
16
- type AcoMutation {
17
- _empty: String
18
- }
6
+ type AcoMutation {
7
+ _empty: String
8
+ }
19
9
 
20
- type AcoMeta {
21
- hasMoreItems: Boolean
22
- totalCount: Int
23
- cursor: String
24
- }
10
+ type AcoMeta {
11
+ hasMoreItems: Boolean
12
+ totalCount: Int
13
+ cursor: String
14
+ }
25
15
 
26
- type AcoUser {
27
- id: ID
28
- displayName: String
29
- type: String
30
- }
16
+ type AcoUser {
17
+ id: ID
18
+ displayName: String
19
+ type: String
20
+ }
31
21
 
32
- type AcoError {
33
- code: String
34
- message: String
35
- data: JSON
36
- stack: String
37
- }
22
+ type AcoError {
23
+ code: String
24
+ message: String
25
+ data: JSON
26
+ stack: String
27
+ }
38
28
 
39
- type AcoBooleanResponse {
40
- data: Boolean
41
- error: AcoError
42
- }
29
+ type AcoBooleanResponse {
30
+ data: Boolean
31
+ error: AcoError
32
+ }
43
33
 
44
- enum AcoSortDirection {
45
- ASC
46
- DESC
47
- }
34
+ enum AcoSortDirection {
35
+ ASC
36
+ DESC
37
+ }
48
38
 
49
- input AcoSort {
50
- id: AcoSortDirection
51
- createdOn: AcoSortDirection
52
- modifiedOn: AcoSortDirection
53
- savedOn: AcoSortDirection
54
- title: AcoSortDirection
55
- }
39
+ input AcoSort {
40
+ id: AcoSortDirection
41
+ createdOn: AcoSortDirection
42
+ modifiedOn: AcoSortDirection
43
+ savedOn: AcoSortDirection
44
+ title: AcoSortDirection
45
+ }
56
46
 
57
- extend type Query {
58
- aco: AcoQuery
59
- }
47
+ extend type Query {
48
+ aco: AcoQuery
49
+ }
60
50
 
61
- extend type Mutation {
62
- aco: AcoMutation
63
- }
64
- `,
65
- resolvers: {
66
- Query: {
67
- aco: emptyResolver
68
- },
69
- Mutation: {
70
- aco: emptyResolver
71
- }
51
+ extend type Mutation {
52
+ aco: AcoMutation
72
53
  }
73
- });
74
- const createAcoGraphQL = ()=>{
75
- const folderSchema = new ContextPlugin(async (context)=>{
76
- if (!await isHeadlessCmsReady(context)) return;
77
- const fieldRegistry = context.container.resolve(CmsModelFieldToGraphQLRegistry);
78
- await context.security.withoutAuthorization(async ()=>{
79
- const model = await context.cms.getModel(FOLDER_MODEL_ID);
80
- const models = await context.cms.listModels();
81
- const plugins = createGraphQLSchemaPluginFromFieldPlugins({
82
- models,
83
- type: "manage",
84
- fieldRegistry,
85
- createPlugin: ({ schema, type, fieldType })=>{
86
- const plugin = new GraphQLSchemaPlugin(schema);
87
- plugin.name = `aco.graphql.folder.schema.${type}.field.${fieldType}`;
88
- return plugin;
89
- }
90
- });
91
- const graphQlPlugin = createFoldersSchema({
92
- model,
93
- models,
94
- fieldRegistry
95
- });
96
- context.plugins.register([
97
- ...plugins,
98
- graphQlPlugin
99
- ]);
100
- });
54
+ `;
55
+ const addAcoBaseSchema = (builder)=>{
56
+ builder.addTypeDefs(BASE_TYPE_DEFS);
57
+ builder.addResolver({
58
+ path: "Query.aco",
59
+ dependencies: [],
60
+ resolver: ()=>()=>({})
61
+ });
62
+ builder.addResolver({
63
+ path: "Mutation.aco",
64
+ dependencies: [],
65
+ resolver: ()=>()=>({})
101
66
  });
102
- return [
103
- baseSchema,
104
- folderSchema,
105
- filterSchema
106
- ];
107
67
  };
108
- export { createAcoGraphQL };
68
+ export { addAcoBaseSchema };
109
69
 
110
70
  //# sourceMappingURL=createAcoGraphQL.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"createAcoGraphQL.js","sources":["../src/createAcoGraphQL.ts"],"sourcesContent":["import { GraphQLSchemaPlugin } from \"@webiny/handler-graphql\";\nimport { filterSchema } from \"~/filter/filter.gql.js\";\nimport { createFoldersSchema } from \"~/folder/folder.gql.js\";\nimport type { AcoContext } from \"~/types.js\";\nimport { ContextPlugin } from \"@webiny/api\";\nimport { isHeadlessCmsReady } from \"@webiny/api-headless-cms\";\nimport type { CmsModel } from \"@webiny/api-headless-cms/types/index.js\";\nimport { createGraphQLSchemaPluginFromFieldPlugins } from \"@webiny/api-headless-cms/utils/getSchemaFromFieldPlugins.js\";\nimport { FOLDER_MODEL_ID } from \"~/domain/folder/folder.model.js\";\nimport { CmsModelFieldToGraphQLRegistry } from \"@webiny/api-headless-cms/exports/api/cms/graphql.js\";\n\nconst emptyResolver = () => ({});\n\nconst baseSchema = new GraphQLSchemaPlugin({\n typeDefs: /* GraphQL */ `\n type AcoQuery {\n _empty: String\n }\n\n type AcoMutation {\n _empty: String\n }\n\n type AcoMeta {\n hasMoreItems: Boolean\n totalCount: Int\n cursor: String\n }\n\n type AcoUser {\n id: ID\n displayName: String\n type: String\n }\n\n type AcoError {\n code: String\n message: String\n data: JSON\n stack: String\n }\n\n type AcoBooleanResponse {\n data: Boolean\n error: AcoError\n }\n\n enum AcoSortDirection {\n ASC\n DESC\n }\n\n input AcoSort {\n id: AcoSortDirection\n createdOn: AcoSortDirection\n modifiedOn: AcoSortDirection\n savedOn: AcoSortDirection\n title: AcoSortDirection\n }\n\n extend type Query {\n aco: AcoQuery\n }\n\n extend type Mutation {\n aco: AcoMutation\n }\n `,\n resolvers: {\n Query: {\n aco: emptyResolver\n },\n Mutation: {\n aco: emptyResolver\n }\n }\n});\n\nexport const createAcoGraphQL = () => {\n const folderSchema = new ContextPlugin<AcoContext>(async context => {\n if (!(await isHeadlessCmsReady(context))) {\n return;\n }\n\n const fieldRegistry = context.container.resolve(CmsModelFieldToGraphQLRegistry);\n\n await context.security.withoutAuthorization(async () => {\n const model = (await context.cms.getModel(FOLDER_MODEL_ID)) as CmsModel;\n const models = await context.cms.listModels();\n /**\n * We need to register all plugins for all the CMS fields.\n */\n const plugins = createGraphQLSchemaPluginFromFieldPlugins({\n models,\n type: \"manage\",\n fieldRegistry,\n createPlugin: ({ schema, type, fieldType }) => {\n const plugin = new GraphQLSchemaPlugin(schema);\n plugin.name = `aco.graphql.folder.schema.${type}.field.${fieldType}`;\n return plugin;\n }\n });\n\n const graphQlPlugin = createFoldersSchema({\n model,\n models,\n fieldRegistry\n });\n\n context.plugins.register([...plugins, graphQlPlugin]);\n });\n });\n\n return [baseSchema, folderSchema, filterSchema];\n};\n"],"names":["emptyResolver","baseSchema","GraphQLSchemaPlugin","createAcoGraphQL","folderSchema","ContextPlugin","context","isHeadlessCmsReady","fieldRegistry","CmsModelFieldToGraphQLRegistry","model","FOLDER_MODEL_ID","models","plugins","createGraphQLSchemaPluginFromFieldPlugins","schema","type","fieldType","plugin","graphQlPlugin","createFoldersSchema","filterSchema"],"mappings":";;;;;;;;AAWA,MAAMA,gBAAgB,IAAO,EAAC;AAE9B,MAAMC,aAAa,IAAIC,oBAAoB;IACvC,UAAwB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAqDzB,CAAC;IACD,WAAW;QACP,OAAO;YACH,KAAKF;QACT;QACA,UAAU;YACN,KAAKA;QACT;IACJ;AACJ;AAEO,MAAMG,mBAAmB;IAC5B,MAAMC,eAAe,IAAIC,cAA0B,OAAMC;QACrD,IAAI,CAAE,MAAMC,mBAAmBD,UAC3B;QAGJ,MAAME,gBAAgBF,QAAQ,SAAS,CAAC,OAAO,CAACG;QAEhD,MAAMH,QAAQ,QAAQ,CAAC,oBAAoB,CAAC;YACxC,MAAMI,QAAS,MAAMJ,QAAQ,GAAG,CAAC,QAAQ,CAACK;YAC1C,MAAMC,SAAS,MAAMN,QAAQ,GAAG,CAAC,UAAU;YAI3C,MAAMO,UAAUC,0CAA0C;gBACtDF;gBACA,MAAM;gBACNJ;gBACA,cAAc,CAAC,EAAEO,MAAM,EAAEC,IAAI,EAAEC,SAAS,EAAE;oBACtC,MAAMC,SAAS,IAAIhB,oBAAoBa;oBACvCG,OAAO,IAAI,GAAG,CAAC,0BAA0B,EAAEF,KAAK,OAAO,EAAEC,WAAW;oBACpE,OAAOC;gBACX;YACJ;YAEA,MAAMC,gBAAgBC,oBAAoB;gBACtCV;gBACAE;gBACAJ;YACJ;YAEAF,QAAQ,OAAO,CAAC,QAAQ,CAAC;mBAAIO;gBAASM;aAAc;QACxD;IACJ;IAEA,OAAO;QAAClB;QAAYG;QAAciB;KAAa;AACnD"}
1
+ {"version":3,"file":"createAcoGraphQL.js","sources":["../src/createAcoGraphQL.ts"],"sourcesContent":["import type { IGraphQLSchemaBuilder } from \"@webiny/api-graphql/features/GraphQLSchemaBuilder/abstractions.js\";\n\nconst BASE_TYPE_DEFS = /* GraphQL */ `\n type AcoQuery {\n _empty: String\n }\n\n type AcoMutation {\n _empty: String\n }\n\n type AcoMeta {\n hasMoreItems: Boolean\n totalCount: Int\n cursor: String\n }\n\n type AcoUser {\n id: ID\n displayName: String\n type: String\n }\n\n type AcoError {\n code: String\n message: String\n data: JSON\n stack: String\n }\n\n type AcoBooleanResponse {\n data: Boolean\n error: AcoError\n }\n\n enum AcoSortDirection {\n ASC\n DESC\n }\n\n input AcoSort {\n id: AcoSortDirection\n createdOn: AcoSortDirection\n modifiedOn: AcoSortDirection\n savedOn: AcoSortDirection\n title: AcoSortDirection\n }\n\n extend type Query {\n aco: AcoQuery\n }\n\n extend type Mutation {\n aco: AcoMutation\n }\n`;\n\n/**\n * The static ACO base schema (root Query.aco / Mutation.aco wrappers + shared types). The dynamic\n * folder schema (field plugins + folders schema) is built by AcoFolderSchemaFactory, which awaits\n * the per-tenant folder model when the schema is built. The filter schema comes from\n * addFilterSchema.\n */\nexport const addAcoBaseSchema = (builder: IGraphQLSchemaBuilder): void => {\n builder.addTypeDefs(BASE_TYPE_DEFS);\n builder.addResolver({ path: \"Query.aco\", dependencies: [], resolver: () => () => ({}) });\n builder.addResolver({ path: \"Mutation.aco\", dependencies: [], resolver: () => () => ({}) });\n};\n"],"names":["BASE_TYPE_DEFS","addAcoBaseSchema","builder"],"mappings":"AAEA,MAAMA,iBAA+B,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqDtC,CAAC;AAQM,MAAMC,mBAAmB,CAACC;IAC7BA,QAAQ,WAAW,CAACF;IACpBE,QAAQ,WAAW,CAAC;QAAE,MAAM;QAAa,cAAc,EAAE;QAAE,UAAU,IAAM,IAAO,EAAC;IAAG;IACtFA,QAAQ,WAAW,CAAC;QAAE,MAAM;QAAgB,cAAc,EAAE;QAAE,UAAU,IAAM,IAAO,EAAC;IAAG;AAC7F"}
@@ -1,9 +1,16 @@
1
1
  import type { CmsModel } from "@webiny/api-headless-cms/types";
2
2
  /**
3
- * FolderModel abstraction - represents the ACO folder CMS model.
4
- * This will be registered via container.registerInstance in the composite feature.
3
+ * Provides the tenant's ACO folder CMS model.
4
+ *
5
+ * A provider rather than the model itself: fetching a model is asynchronous and tenant-dependent,
6
+ * while DI resolution is synchronous — so an already-resolved `CmsModel` could only be supplied by a
7
+ * per-request hook running before every consumer (what `AcoInitializer` used to do). Consumers
8
+ * `await get()` at the point of use.
5
9
  */
6
- export declare const FolderModel: import("@webiny/di").Abstraction<CmsModel>;
7
- export declare namespace FolderModel {
8
- type Interface = CmsModel;
10
+ export interface IFolderModelProvider {
11
+ get(): Promise<CmsModel>;
12
+ }
13
+ export declare const FolderModelProvider: import("@webiny/di").Abstraction<IFolderModelProvider>;
14
+ export declare namespace FolderModelProvider {
15
+ type Interface = IFolderModelProvider;
9
16
  }
@@ -1,5 +1,5 @@
1
1
  import { createAbstraction } from "@webiny/feature/api";
2
- const FolderModel = createAbstraction("FolderModel");
3
- export { FolderModel };
2
+ const FolderModelProvider = createAbstraction("FolderModelProvider");
3
+ export { FolderModelProvider };
4
4
 
5
5
  //# sourceMappingURL=abstractions.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"domain/folder/abstractions.js","sources":["../../../src/domain/folder/abstractions.ts"],"sourcesContent":["import { createAbstraction } from \"@webiny/feature/api\";\nimport type { CmsModel } from \"@webiny/api-headless-cms/types\";\n\n/**\n * FolderModel abstraction - represents the ACO folder CMS model.\n * This will be registered via container.registerInstance in the composite feature.\n */\nexport const FolderModel = createAbstraction<CmsModel>(\"FolderModel\");\n\nexport namespace FolderModel {\n export type Interface = CmsModel;\n}\n"],"names":["FolderModel","createAbstraction"],"mappings":";AAOO,MAAMA,cAAcC,kBAA4B"}
1
+ {"version":3,"file":"domain/folder/abstractions.js","sources":["../../../src/domain/folder/abstractions.ts"],"sourcesContent":["import { createAbstraction } from \"@webiny/feature/api\";\nimport type { CmsModel } from \"@webiny/api-headless-cms/types\";\n\n/**\n * Provides the tenant's ACO folder CMS model.\n *\n * A provider rather than the model itself: fetching a model is asynchronous and tenant-dependent,\n * while DI resolution is synchronous — so an already-resolved `CmsModel` could only be supplied by a\n * per-request hook running before every consumer (what `AcoInitializer` used to do). Consumers\n * `await get()` at the point of use.\n */\nexport interface IFolderModelProvider {\n get(): Promise<CmsModel>;\n}\n\nexport const FolderModelProvider = createAbstraction<IFolderModelProvider>(\"FolderModelProvider\");\n\nexport namespace FolderModelProvider {\n export type Interface = IFolderModelProvider;\n}\n"],"names":["FolderModelProvider","createAbstraction"],"mappings":";AAeO,MAAMA,sBAAsBC,kBAAwC"}
@@ -7,5 +7,5 @@ export { FolderAfterDeleteEventHandler, FolderBeforeDeleteEventHandler, DeleteFo
7
7
  export { FolderAfterUpdateEventHandler, FolderBeforeUpdateEventHandler, UpdateFolderRepository, UpdateFolderUseCase } from "../../../features/folder/UpdateFolder/abstractions.js";
8
8
  export { EnsureFolderIsEmpty } from "../../../features/folder/EnsureFolderIsEmpty/abstractions.js";
9
9
  export { ListFoldersUseCase, ListFoldersRepository } from "../../../features/folder/ListFolders/abstractions.js";
10
- export { FilterStorageOperations } from "../../../features/folder/shared/abstractions.js";
10
+ export { FilterStorageOperations, FlpStorageOperations } from "../../../features/folder/shared/abstractions.js";
11
11
  export type { Folder } from "../../../folder/folder.types.js";
@@ -7,4 +7,4 @@ export { DeleteFolderRepository, DeleteFolderUseCase, FolderAfterDeleteEventHand
7
7
  export { FolderAfterUpdateEventHandler, FolderBeforeUpdateEventHandler, UpdateFolderRepository, UpdateFolderUseCase } from "../../../features/folder/UpdateFolder/abstractions.js";
8
8
  export { EnsureFolderIsEmpty } from "../../../features/folder/EnsureFolderIsEmpty/abstractions.js";
9
9
  export { ListFoldersRepository, ListFoldersUseCase } from "../../../features/folder/ListFolders/abstractions.js";
10
- export { FilterStorageOperations } from "../../../features/folder/shared/abstractions.js";
10
+ export { FilterStorageOperations, FlpStorageOperations } from "../../../features/folder/shared/abstractions.js";
@@ -0,0 +1,44 @@
1
+ import { z } from "zod";
2
+ import type { IAiSdkTool } from "@webiny/api-core/features/ai/index.js";
3
+ import { CreateFolderUseCase } from "../../features/folder/CreateFolder/index.js";
4
+ declare const inputSchema: z.ZodObject<{
5
+ title: z.ZodString;
6
+ slug: z.ZodString;
7
+ type: z.ZodString;
8
+ parentId: z.ZodOptional<z.ZodString>;
9
+ }, z.core.$strip>;
10
+ type Input = z.infer<typeof inputSchema>;
11
+ interface CreatedFolder {
12
+ id: string;
13
+ title: string;
14
+ slug: string;
15
+ path: string;
16
+ type: string;
17
+ }
18
+ /**
19
+ * Creates a folder.
20
+ *
21
+ * Additive and reversible, so it is not flagged destructive — but it still changes the project, so it
22
+ * is not read-only either and therefore needs the user to approve the exact arguments.
23
+ */
24
+ declare class CreateFolderToolImpl implements IAiSdkTool<Input> {
25
+ private createFolder;
26
+ readonly name = "createFolder";
27
+ readonly title = "Create folder";
28
+ readonly description = "Creates a folder in the File Manager ('FmFile') or under a content model ('cms:<modelId>'). Call listFolders first to pick a parent, or omit parentId for the root. Requires user approval.";
29
+ readonly inputSchema: z.ZodObject<{
30
+ title: z.ZodString;
31
+ slug: z.ZodString;
32
+ type: z.ZodString;
33
+ parentId: z.ZodOptional<z.ZodString>;
34
+ }, z.core.$strip>;
35
+ readonly annotations: {
36
+ readOnlyHint: boolean;
37
+ };
38
+ constructor(createFolder: CreateFolderUseCase.Interface);
39
+ execute(input: Input): Promise<CreatedFolder>;
40
+ }
41
+ export declare const CreateFolderTool: typeof CreateFolderToolImpl & {
42
+ __abstraction: import("@webiny/di").Abstraction<IAiSdkTool<any>>;
43
+ };
44
+ export {};