@webiny/app-admin 6.5.0-beta.0 → 6.5.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/base/Admin.js +2 -0
  2. package/base/Admin.js.map +1 -1
  3. package/base/Base/FieldRenderers/AutoCompleteRenderer.js +1 -0
  4. package/base/Base/FieldRenderers/AutoCompleteRenderer.js.map +1 -1
  5. package/base/Base/FieldRenderers/SelectRenderer.js +1 -0
  6. package/base/Base/FieldRenderers/SelectRenderer.js.map +1 -1
  7. package/features/debugger/Debugger.d.ts +8 -0
  8. package/features/debugger/Debugger.js +25 -0
  9. package/features/debugger/Debugger.js.map +1 -0
  10. package/features/debugger/DebuggerIndicator.d.ts +16 -0
  11. package/features/debugger/DebuggerIndicator.js +31 -0
  12. package/features/debugger/DebuggerIndicator.js.map +1 -0
  13. package/features/debugger/DebuggerStore.d.ts +55 -0
  14. package/features/debugger/DebuggerStore.js +65 -0
  15. package/features/debugger/DebuggerStore.js.map +1 -0
  16. package/features/debugger/DebuggerView.d.ts +4 -0
  17. package/features/debugger/DebuggerView.js +49 -0
  18. package/features/debugger/DebuggerView.js.map +1 -0
  19. package/features/debugger/GraphQLExtensionsDebugHandler.d.ts +15 -0
  20. package/features/debugger/GraphQLExtensionsDebugHandler.js +15 -0
  21. package/features/debugger/GraphQLExtensionsDebugHandler.js.map +1 -0
  22. package/features/debugger/debuggerLink.d.ts +12 -0
  23. package/features/debugger/debuggerLink.js +10 -0
  24. package/features/debugger/debuggerLink.js.map +1 -0
  25. package/features/debugger/feature.d.ts +1 -0
  26. package/features/debugger/feature.js +18 -0
  27. package/features/debugger/feature.js.map +1 -0
  28. package/features/debugger/index.d.ts +7 -0
  29. package/features/debugger/index.js +7 -0
  30. package/features/debugger/permissions.d.ts +68 -0
  31. package/features/debugger/permissions.js +27 -0
  32. package/features/debugger/permissions.js.map +1 -0
  33. package/features/debugger/report.d.ts +7 -0
  34. package/features/debugger/report.js +22 -0
  35. package/features/debugger/report.js.map +1 -0
  36. package/features/debugger/routes.d.ts +4 -0
  37. package/features/debugger/routes.js +10 -0
  38. package/features/debugger/routes.js.map +1 -0
  39. package/features/formModel/createFieldRenderer.js +3 -4
  40. package/features/formModel/createFieldRenderer.js.map +1 -1
  41. package/hooks/useHotkeys.js +3 -1
  42. package/hooks/useHotkeys.js.map +1 -1
  43. package/index.d.ts +1 -0
  44. package/index.js +3 -2
  45. package/package.json +19 -19
  46. package/presentation/listPresenter/FolderAwareDataSource.d.ts +5 -0
  47. package/presentation/listPresenter/FolderAwareDataSource.js +4 -3
  48. package/presentation/listPresenter/FolderAwareDataSource.js.map +1 -1
  49. package/presentation/listPresenter/QueryMatcher.d.ts +28 -5
  50. package/presentation/listPresenter/QueryMatcher.js +72 -2
  51. package/presentation/listPresenter/QueryMatcher.js.map +1 -1
  52. package/presentation/listPresenter/QueryMatcher.test.d.ts +1 -0
  53. package/presentation/listPresenter/QueryMatcher.test.js +345 -0
  54. package/presentation/listPresenter/QueryMatcher.test.js.map +1 -0
package/base/Admin.js CHANGED
@@ -24,6 +24,7 @@ import { SortableFeature } from "../presentation/sortable/index.js";
24
24
  import { NotificationsRenderer } from "../features/notifications/NotificationsRenderer.js";
25
25
  import { CommandPaletteFeature } from "../presentation/commandPalette/index.js";
26
26
  import { AdminCommandsFeature } from "../presentation/commandPalette/commands/feature.js";
27
+ import { DebuggerFeature } from "../features/debugger/feature.js";
27
28
  const container = createRootContainer();
28
29
  const Admin = ({ children, createApolloClient, createLegacyPlugins })=>{
29
30
  const uri = process.env.REACT_APP_GRAPHQL_API_URL;
@@ -40,6 +41,7 @@ const Admin = ({ children, createApolloClient, createLegacyPlugins })=>{
40
41
  CommandPaletteFeature.register(container);
41
42
  AdminCommandsFeature.register(container);
42
43
  SortableFeature.register(container);
44
+ DebuggerFeature.register(container);
43
45
  const ApolloProvider = createApolloProvider(apolloClient);
44
46
  const UIProviders = createUiProviders();
45
47
  const UiStateProvider = createUiStateProvider();
package/base/Admin.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"base/Admin.js","sources":["../../src/base/Admin.tsx"],"sourcesContent":["import React from \"react\";\nimport type { Container } from \"@webiny/di\";\nimport { plugins } from \"@webiny/plugins\";\nimport { App, DiContainerProvider } from \"@webiny/app\";\nimport type { ApolloClientFactory } from \"./providers/ApolloProvider.js\";\nimport { createApolloProvider } from \"./providers/ApolloProvider.js\";\nimport { Base } from \"./Base.js\";\nimport { createUiStateProvider } from \"./providers/UiStateProvider.js\";\nimport { createAdminUiStateProvider } from \"./providers/AdminUiStateProvider.js\";\nimport { createUiProviders } from \"./providers/UiProviders.js\";\nimport { createDialogsProvider } from \"~/components/Dialogs/DialogsContext.js\";\nimport { createDrawersProvider } from \"~/components/Drawers/DrawersContext.js\";\nimport { DefaultIcons, IconPickerConfigProvider } from \"~/components/IconPicker/config/index.js\";\nimport { createRootContainer } from \"~/base/createRootContainer.js\";\nimport { WcpProvider } from \"~/presentation/wcp/WcpProvider.js\";\nimport { createTenancyProvider } from \"~/presentation/tenancy/createTenancyProvider.js\";\nimport { TelemetryAdminAppStart } from \"./TelemetryAdminAppStart.js\";\nimport { ApolloClientFeature } from \"~/features/apolloClient/feature.js\";\nimport { SecurityFeature } from \"~/features/security/SecurityFeature.js\";\nimport { FormModelFeature } from \"~/features/formModel/feature.js\";\nimport type { PluginCollection } from \"@webiny/plugins/types.js\";\nimport { AdminConfigPlugin, AdminConfigProvider } from \"~/config/AdminConfig.js\";\nimport { WebinySdkFeature } from \"~/features/webinySdk/feature.js\";\nimport { DateFormatterFeature } from \"~/features/dateFormatter/feature.js\";\nimport { ListPresenterFeature } from \"~/presentation/listPresenter/index.js\";\nimport { SortableFeature } from \"~/presentation/sortable/index.js\";\nimport { NotificationsRenderer } from \"~/features/notifications/NotificationsRenderer.js\";\nimport { CommandPaletteFeature } from \"~/presentation/commandPalette/index.js\";\nimport { AdminCommandsFeature } from \"~/presentation/commandPalette/commands/feature.js\";\n\nexport interface AdminProps {\n createApolloClient: ApolloClientFactory;\n createLegacyPlugins: (container: Container) => PluginCollection;\n children?: React.ReactNode;\n}\n\nconst container = createRootContainer();\n\nexport const Admin = ({ children, createApolloClient, createLegacyPlugins }: AdminProps) => {\n const uri = process.env.REACT_APP_GRAPHQL_API_URL as string;\n const apolloClient = createApolloClient({ uri });\n\n plugins.register(...createLegacyPlugins(container));\n\n ApolloClientFeature.register(container, apolloClient);\n SecurityFeature.register(container);\n DateFormatterFeature.register(container);\n FormModelFeature.register(container);\n WebinySdkFeature.register(container);\n ListPresenterFeature.register(container);\n CommandPaletteFeature.register(container);\n AdminCommandsFeature.register(container);\n SortableFeature.register(container);\n\n const ApolloProvider = createApolloProvider(apolloClient);\n const UIProviders = createUiProviders();\n const UiStateProvider = createUiStateProvider();\n const AdminUiStateProvider = createAdminUiStateProvider();\n const DialogsProvider = createDialogsProvider();\n const DrawersProvider = createDrawersProvider();\n const TenancyProvider = createTenancyProvider();\n\n return (\n <DiContainerProvider container={container}>\n <TelemetryAdminAppStart />\n <ApolloProvider>\n <WcpProvider>\n <App\n plugins={[AdminConfigPlugin]}\n routes={[]}\n providers={[\n AdminConfigProvider,\n UIProviders,\n UiStateProvider,\n DialogsProvider,\n DrawersProvider,\n IconPickerConfigProvider,\n AdminUiStateProvider,\n TenancyProvider\n ]}\n >\n <Base />\n <DefaultIcons />\n <NotificationsRenderer />\n {children}\n </App>\n </WcpProvider>\n </ApolloProvider>\n </DiContainerProvider>\n );\n};\n"],"names":["container","createRootContainer","Admin","children","createApolloClient","createLegacyPlugins","uri","process","apolloClient","plugins","ApolloClientFeature","SecurityFeature","DateFormatterFeature","FormModelFeature","WebinySdkFeature","ListPresenterFeature","CommandPaletteFeature","AdminCommandsFeature","SortableFeature","ApolloProvider","createApolloProvider","UIProviders","createUiProviders","UiStateProvider","createUiStateProvider","AdminUiStateProvider","createAdminUiStateProvider","DialogsProvider","createDialogsProvider","DrawersProvider","createDrawersProvider","TenancyProvider","createTenancyProvider","DiContainerProvider","TelemetryAdminAppStart","WcpProvider","App","AdminConfigPlugin","AdminConfigProvider","IconPickerConfigProvider","Base","DefaultIcons","NotificationsRenderer"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAoCA,MAAMA,YAAYC;AAEX,MAAMC,QAAQ,CAAC,EAAEC,QAAQ,EAAEC,kBAAkB,EAAEC,mBAAmB,EAAc;IACnF,MAAMC,MAAMC,QAAQ,GAAG,CAAC,yBAAyB;IACjD,MAAMC,eAAeJ,mBAAmB;QAAEE;IAAI;IAE9CG,QAAQ,QAAQ,IAAIJ,oBAAoBL;IAExCU,oBAAoB,QAAQ,CAACV,WAAWQ;IACxCG,gBAAgB,QAAQ,CAACX;IACzBY,qBAAqB,QAAQ,CAACZ;IAC9Ba,iBAAiB,QAAQ,CAACb;IAC1Bc,iBAAiB,QAAQ,CAACd;IAC1Be,qBAAqB,QAAQ,CAACf;IAC9BgB,sBAAsB,QAAQ,CAAChB;IAC/BiB,qBAAqB,QAAQ,CAACjB;IAC9BkB,gBAAgB,QAAQ,CAAClB;IAEzB,MAAMmB,iBAAiBC,qBAAqBZ;IAC5C,MAAMa,cAAcC;IACpB,MAAMC,kBAAkBC;IACxB,MAAMC,uBAAuBC;IAC7B,MAAMC,kBAAkBC;IACxB,MAAMC,kBAAkBC;IACxB,MAAMC,kBAAkBC;IAExB,OAAO,WAAP,GACI,oBAACC,qBAAmBA;QAAC,WAAWjC;qBAC5B,oBAACkC,wBAAsBA,OAAAA,WAAAA,GACvB,oBAACf,gBAAAA,MAAAA,WAAAA,GACG,oBAACgB,aAAWA,MAAAA,WAAAA,GACR,oBAACC,KAAGA;QACA,SAAS;YAACC;SAAkB;QAC5B,QAAQ,EAAE;QACV,WAAW;YACPC;YACAjB;YACAE;YACAI;YACAE;YACAU;YACAd;YACAM;SACH;qBAED,oBAACS,MAAIA,OAAAA,WAAAA,GACL,oBAACC,cAAYA,OAAAA,WAAAA,GACb,oBAACC,uBAAqBA,OACrBvC;AAMzB"}
1
+ {"version":3,"file":"base/Admin.js","sources":["../../src/base/Admin.tsx"],"sourcesContent":["import React from \"react\";\nimport type { Container } from \"@webiny/di\";\nimport { plugins } from \"@webiny/plugins\";\nimport { App, DiContainerProvider } from \"@webiny/app\";\nimport type { ApolloClientFactory } from \"./providers/ApolloProvider.js\";\nimport { createApolloProvider } from \"./providers/ApolloProvider.js\";\nimport { Base } from \"./Base.js\";\nimport { createUiStateProvider } from \"./providers/UiStateProvider.js\";\nimport { createAdminUiStateProvider } from \"./providers/AdminUiStateProvider.js\";\nimport { createUiProviders } from \"./providers/UiProviders.js\";\nimport { createDialogsProvider } from \"~/components/Dialogs/DialogsContext.js\";\nimport { createDrawersProvider } from \"~/components/Drawers/DrawersContext.js\";\nimport { DefaultIcons, IconPickerConfigProvider } from \"~/components/IconPicker/config/index.js\";\nimport { createRootContainer } from \"~/base/createRootContainer.js\";\nimport { WcpProvider } from \"~/presentation/wcp/WcpProvider.js\";\nimport { createTenancyProvider } from \"~/presentation/tenancy/createTenancyProvider.js\";\nimport { TelemetryAdminAppStart } from \"./TelemetryAdminAppStart.js\";\nimport { ApolloClientFeature } from \"~/features/apolloClient/feature.js\";\nimport { SecurityFeature } from \"~/features/security/SecurityFeature.js\";\nimport { FormModelFeature } from \"~/features/formModel/feature.js\";\nimport type { PluginCollection } from \"@webiny/plugins/types.js\";\nimport { AdminConfigPlugin, AdminConfigProvider } from \"~/config/AdminConfig.js\";\nimport { WebinySdkFeature } from \"~/features/webinySdk/feature.js\";\nimport { DateFormatterFeature } from \"~/features/dateFormatter/feature.js\";\nimport { ListPresenterFeature } from \"~/presentation/listPresenter/index.js\";\nimport { SortableFeature } from \"~/presentation/sortable/index.js\";\nimport { NotificationsRenderer } from \"~/features/notifications/NotificationsRenderer.js\";\nimport { CommandPaletteFeature } from \"~/presentation/commandPalette/index.js\";\nimport { AdminCommandsFeature } from \"~/presentation/commandPalette/commands/feature.js\";\nimport { DebuggerFeature } from \"~/features/debugger/feature.js\";\n\nexport interface AdminProps {\n createApolloClient: ApolloClientFactory;\n createLegacyPlugins: (container: Container) => PluginCollection;\n children?: React.ReactNode;\n}\n\nconst container = createRootContainer();\n\nexport const Admin = ({ children, createApolloClient, createLegacyPlugins }: AdminProps) => {\n const uri = process.env.REACT_APP_GRAPHQL_API_URL as string;\n const apolloClient = createApolloClient({ uri });\n\n plugins.register(...createLegacyPlugins(container));\n\n ApolloClientFeature.register(container, apolloClient);\n SecurityFeature.register(container);\n DateFormatterFeature.register(container);\n FormModelFeature.register(container);\n WebinySdkFeature.register(container);\n ListPresenterFeature.register(container);\n CommandPaletteFeature.register(container);\n AdminCommandsFeature.register(container);\n SortableFeature.register(container);\n DebuggerFeature.register(container);\n\n const ApolloProvider = createApolloProvider(apolloClient);\n const UIProviders = createUiProviders();\n const UiStateProvider = createUiStateProvider();\n const AdminUiStateProvider = createAdminUiStateProvider();\n const DialogsProvider = createDialogsProvider();\n const DrawersProvider = createDrawersProvider();\n const TenancyProvider = createTenancyProvider();\n\n return (\n <DiContainerProvider container={container}>\n <TelemetryAdminAppStart />\n <ApolloProvider>\n <WcpProvider>\n <App\n plugins={[AdminConfigPlugin]}\n routes={[]}\n providers={[\n AdminConfigProvider,\n UIProviders,\n UiStateProvider,\n DialogsProvider,\n DrawersProvider,\n IconPickerConfigProvider,\n AdminUiStateProvider,\n TenancyProvider\n ]}\n >\n <Base />\n <DefaultIcons />\n <NotificationsRenderer />\n {children}\n </App>\n </WcpProvider>\n </ApolloProvider>\n </DiContainerProvider>\n );\n};\n"],"names":["container","createRootContainer","Admin","children","createApolloClient","createLegacyPlugins","uri","process","apolloClient","plugins","ApolloClientFeature","SecurityFeature","DateFormatterFeature","FormModelFeature","WebinySdkFeature","ListPresenterFeature","CommandPaletteFeature","AdminCommandsFeature","SortableFeature","DebuggerFeature","ApolloProvider","createApolloProvider","UIProviders","createUiProviders","UiStateProvider","createUiStateProvider","AdminUiStateProvider","createAdminUiStateProvider","DialogsProvider","createDialogsProvider","DrawersProvider","createDrawersProvider","TenancyProvider","createTenancyProvider","DiContainerProvider","TelemetryAdminAppStart","WcpProvider","App","AdminConfigPlugin","AdminConfigProvider","IconPickerConfigProvider","Base","DefaultIcons","NotificationsRenderer"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAqCA,MAAMA,YAAYC;AAEX,MAAMC,QAAQ,CAAC,EAAEC,QAAQ,EAAEC,kBAAkB,EAAEC,mBAAmB,EAAc;IACnF,MAAMC,MAAMC,QAAQ,GAAG,CAAC,yBAAyB;IACjD,MAAMC,eAAeJ,mBAAmB;QAAEE;IAAI;IAE9CG,QAAQ,QAAQ,IAAIJ,oBAAoBL;IAExCU,oBAAoB,QAAQ,CAACV,WAAWQ;IACxCG,gBAAgB,QAAQ,CAACX;IACzBY,qBAAqB,QAAQ,CAACZ;IAC9Ba,iBAAiB,QAAQ,CAACb;IAC1Bc,iBAAiB,QAAQ,CAACd;IAC1Be,qBAAqB,QAAQ,CAACf;IAC9BgB,sBAAsB,QAAQ,CAAChB;IAC/BiB,qBAAqB,QAAQ,CAACjB;IAC9BkB,gBAAgB,QAAQ,CAAClB;IACzBmB,gBAAgB,QAAQ,CAACnB;IAEzB,MAAMoB,iBAAiBC,qBAAqBb;IAC5C,MAAMc,cAAcC;IACpB,MAAMC,kBAAkBC;IACxB,MAAMC,uBAAuBC;IAC7B,MAAMC,kBAAkBC;IACxB,MAAMC,kBAAkBC;IACxB,MAAMC,kBAAkBC;IAExB,OAAO,WAAP,GACI,oBAACC,qBAAmBA;QAAC,WAAWlC;qBAC5B,oBAACmC,wBAAsBA,OAAAA,WAAAA,GACvB,oBAACf,gBAAAA,MAAAA,WAAAA,GACG,oBAACgB,aAAWA,MAAAA,WAAAA,GACR,oBAACC,KAAGA;QACA,SAAS;YAACC;SAAkB;QAC5B,QAAQ,EAAE;QACV,WAAW;YACPC;YACAjB;YACAE;YACAI;YACAE;YACAU;YACAd;YACAM;SACH;qBAED,oBAACS,MAAIA,OAAAA,WAAAA,GACL,oBAACC,cAAYA,OAAAA,WAAAA,GACb,oBAACC,uBAAqBA,OACrBxC;AAMzB"}
@@ -15,6 +15,7 @@ const AutoCompleteRenderer = createFieldRenderer(({ field })=>{
15
15
  field.onBlur();
16
16
  },
17
17
  required: field.required,
18
+ displayResetAction: !field.required,
18
19
  disabled: field.disabled,
19
20
  validation: field.validation,
20
21
  options: options.map((opt)=>({
@@ -1 +1 @@
1
- {"version":3,"file":"base/Base/FieldRenderers/AutoCompleteRenderer.js","sources":["../../../../src/base/Base/FieldRenderers/AutoCompleteRenderer.tsx"],"sourcesContent":["import React from \"react\";\nimport { createFieldRenderer } from \"~/features/formModel/createFieldRenderer.js\";\nimport { AutoComplete } from \"@webiny/admin-ui\";\nimport type { IValueOption } from \"~/features/formModel/index.js\";\n\ndeclare module \"../../../features/formModel/abstractions.js\" {\n interface IFieldRendererRegistry {\n autoComplete: { fieldType: \"text\" | \"number\"; options: true; settings: undefined };\n }\n}\n\nexport const AutoCompleteRenderer = createFieldRenderer(({ field }) => {\n const options: IValueOption[] = field.options ?? [];\n\n return (\n <AutoComplete\n label={field.label}\n hint={field.help}\n placeholder={field.placeholder}\n description={field.description}\n note={field.note}\n value={field.value != null ? String(field.value) : \"\"}\n onValueChange={value => {\n field.onChange(value);\n field.onBlur();\n }}\n required={field.required}\n disabled={field.disabled}\n validation={field.validation}\n options={options.map(opt => ({\n label: opt.label,\n value: String(opt.value),\n disabled: opt.disabled\n }))}\n />\n );\n});\n"],"names":["AutoCompleteRenderer","createFieldRenderer","field","options","AutoComplete","String","value","opt"],"mappings":";;;AAWO,MAAMA,uBAAuBC,oBAAoB,CAAC,EAAEC,KAAK,EAAE;IAC9D,MAAMC,UAA0BD,MAAM,OAAO,IAAI,EAAE;IAEnD,OAAO,WAAP,GACI,oBAACE,cAAYA;QACT,OAAOF,MAAM,KAAK;QAClB,MAAMA,MAAM,IAAI;QAChB,aAAaA,MAAM,WAAW;QAC9B,aAAaA,MAAM,WAAW;QAC9B,MAAMA,MAAM,IAAI;QAChB,OAAOA,AAAe,QAAfA,MAAM,KAAK,GAAWG,OAAOH,MAAM,KAAK,IAAI;QACnD,eAAeI,CAAAA;YACXJ,MAAM,QAAQ,CAACI;YACfJ,MAAM,MAAM;QAChB;QACA,UAAUA,MAAM,QAAQ;QACxB,UAAUA,MAAM,QAAQ;QACxB,YAAYA,MAAM,UAAU;QAC5B,SAASC,QAAQ,GAAG,CAACI,CAAAA,MAAQ;gBACzB,OAAOA,IAAI,KAAK;gBAChB,OAAOF,OAAOE,IAAI,KAAK;gBACvB,UAAUA,IAAI,QAAQ;YAC1B;;AAGZ"}
1
+ {"version":3,"file":"base/Base/FieldRenderers/AutoCompleteRenderer.js","sources":["../../../../src/base/Base/FieldRenderers/AutoCompleteRenderer.tsx"],"sourcesContent":["import React from \"react\";\nimport { createFieldRenderer } from \"~/features/formModel/createFieldRenderer.js\";\nimport { AutoComplete } from \"@webiny/admin-ui\";\nimport type { IValueOption } from \"~/features/formModel/index.js\";\n\ndeclare module \"../../../features/formModel/abstractions.js\" {\n interface IFieldRendererRegistry {\n autoComplete: { fieldType: \"text\" | \"number\"; options: true; settings: undefined };\n }\n}\n\nexport const AutoCompleteRenderer = createFieldRenderer(({ field }) => {\n const options: IValueOption[] = field.options ?? [];\n\n return (\n <AutoComplete\n label={field.label}\n hint={field.help}\n placeholder={field.placeholder}\n description={field.description}\n note={field.note}\n value={field.value != null ? String(field.value) : \"\"}\n onValueChange={value => {\n field.onChange(value);\n field.onBlur();\n }}\n required={field.required}\n // Clearing a required field can only leave it invalid, so it gets no reset action.\n displayResetAction={!field.required}\n disabled={field.disabled}\n validation={field.validation}\n options={options.map(opt => ({\n label: opt.label,\n value: String(opt.value),\n disabled: opt.disabled\n }))}\n />\n );\n});\n"],"names":["AutoCompleteRenderer","createFieldRenderer","field","options","AutoComplete","String","value","opt"],"mappings":";;;AAWO,MAAMA,uBAAuBC,oBAAoB,CAAC,EAAEC,KAAK,EAAE;IAC9D,MAAMC,UAA0BD,MAAM,OAAO,IAAI,EAAE;IAEnD,OAAO,WAAP,GACI,oBAACE,cAAYA;QACT,OAAOF,MAAM,KAAK;QAClB,MAAMA,MAAM,IAAI;QAChB,aAAaA,MAAM,WAAW;QAC9B,aAAaA,MAAM,WAAW;QAC9B,MAAMA,MAAM,IAAI;QAChB,OAAOA,AAAe,QAAfA,MAAM,KAAK,GAAWG,OAAOH,MAAM,KAAK,IAAI;QACnD,eAAeI,CAAAA;YACXJ,MAAM,QAAQ,CAACI;YACfJ,MAAM,MAAM;QAChB;QACA,UAAUA,MAAM,QAAQ;QAExB,oBAAoB,CAACA,MAAM,QAAQ;QACnC,UAAUA,MAAM,QAAQ;QACxB,YAAYA,MAAM,UAAU;QAC5B,SAASC,QAAQ,GAAG,CAACI,CAAAA,MAAQ;gBACzB,OAAOA,IAAI,KAAK;gBAChB,OAAOF,OAAOE,IAAI,KAAK;gBACvB,UAAUA,IAAI,QAAQ;YAC1B;;AAGZ"}
@@ -16,6 +16,7 @@ const SelectRenderer = createFieldRenderer(({ field })=>{
16
16
  field.onBlur();
17
17
  },
18
18
  required: field.required,
19
+ displayResetAction: !field.required,
19
20
  disabled: field.disabled,
20
21
  validation: field.validation,
21
22
  options: options.map((opt)=>({
@@ -1 +1 @@
1
- {"version":3,"file":"base/Base/FieldRenderers/SelectRenderer.js","sources":["../../../../src/base/Base/FieldRenderers/SelectRenderer.tsx"],"sourcesContent":["import React from \"react\";\nimport { createFieldRenderer } from \"~/features/formModel/createFieldRenderer.js\";\nimport { Select } from \"@webiny/admin-ui\";\nimport type { IValueOption } from \"~/features/formModel/index.js\";\n\ndeclare module \"../../../features/formModel/abstractions.js\" {\n interface IFieldRendererRegistry {\n select: { fieldType: \"text\" | \"number\"; options: true; settings: undefined };\n /** @deprecated Use \"select\" instead. */\n dropdown: { fieldType: \"text\" | \"number\"; options: true; settings: undefined };\n }\n}\n\nconst isValidValue = (value: unknown): value is string | number =>\n typeof value === \"string\" || typeof value === \"number\";\n\nexport const SelectRenderer = createFieldRenderer(({ field }) => {\n const options: IValueOption[] = field.options ?? [];\n\n return (\n <Select\n label={field.label}\n hint={field.help}\n placeholder={field.placeholder}\n description={field.description}\n note={field.note}\n value={isValidValue(field.value) ? String(field.value) : \"\"}\n onChange={value => {\n field.onChange(value);\n field.onBlur();\n }}\n required={field.required}\n disabled={field.disabled}\n validation={field.validation}\n options={options.map(opt => ({\n label: opt.label,\n value: isValidValue(opt.value) ? String(opt.value) : opt.value,\n disabled: opt.disabled\n }))}\n />\n );\n});\n"],"names":["isValidValue","value","SelectRenderer","createFieldRenderer","field","options","Select","String","opt"],"mappings":";;;AAaA,MAAMA,eAAe,CAACC,QAClB,AAAiB,YAAjB,OAAOA,SAAsB,AAAiB,YAAjB,OAAOA;AAEjC,MAAMC,iBAAiBC,oBAAoB,CAAC,EAAEC,KAAK,EAAE;IACxD,MAAMC,UAA0BD,MAAM,OAAO,IAAI,EAAE;IAEnD,OAAO,WAAP,GACI,oBAACE,QAAMA;QACH,OAAOF,MAAM,KAAK;QAClB,MAAMA,MAAM,IAAI;QAChB,aAAaA,MAAM,WAAW;QAC9B,aAAaA,MAAM,WAAW;QAC9B,MAAMA,MAAM,IAAI;QAChB,OAAOJ,aAAaI,MAAM,KAAK,IAAIG,OAAOH,MAAM,KAAK,IAAI;QACzD,UAAUH,CAAAA;YACNG,MAAM,QAAQ,CAACH;YACfG,MAAM,MAAM;QAChB;QACA,UAAUA,MAAM,QAAQ;QACxB,UAAUA,MAAM,QAAQ;QACxB,YAAYA,MAAM,UAAU;QAC5B,SAASC,QAAQ,GAAG,CAACG,CAAAA,MAAQ;gBACzB,OAAOA,IAAI,KAAK;gBAChB,OAAOR,aAAaQ,IAAI,KAAK,IAAID,OAAOC,IAAI,KAAK,IAAIA,IAAI,KAAK;gBAC9D,UAAUA,IAAI,QAAQ;YAC1B;;AAGZ"}
1
+ {"version":3,"file":"base/Base/FieldRenderers/SelectRenderer.js","sources":["../../../../src/base/Base/FieldRenderers/SelectRenderer.tsx"],"sourcesContent":["import React from \"react\";\nimport { createFieldRenderer } from \"~/features/formModel/createFieldRenderer.js\";\nimport { Select } from \"@webiny/admin-ui\";\nimport type { IValueOption } from \"~/features/formModel/index.js\";\n\ndeclare module \"../../../features/formModel/abstractions.js\" {\n interface IFieldRendererRegistry {\n select: { fieldType: \"text\" | \"number\"; options: true; settings: undefined };\n /** @deprecated Use \"select\" instead. */\n dropdown: { fieldType: \"text\" | \"number\"; options: true; settings: undefined };\n }\n}\n\nconst isValidValue = (value: unknown): value is string | number =>\n typeof value === \"string\" || typeof value === \"number\";\n\nexport const SelectRenderer = createFieldRenderer(({ field }) => {\n const options: IValueOption[] = field.options ?? [];\n\n return (\n <Select\n label={field.label}\n hint={field.help}\n placeholder={field.placeholder}\n description={field.description}\n note={field.note}\n value={isValidValue(field.value) ? String(field.value) : \"\"}\n onChange={value => {\n field.onChange(value);\n field.onBlur();\n }}\n required={field.required}\n // Clearing a required field can only leave it invalid, so it gets no reset action.\n displayResetAction={!field.required}\n disabled={field.disabled}\n validation={field.validation}\n options={options.map(opt => ({\n label: opt.label,\n value: isValidValue(opt.value) ? String(opt.value) : opt.value,\n disabled: opt.disabled\n }))}\n />\n );\n});\n"],"names":["isValidValue","value","SelectRenderer","createFieldRenderer","field","options","Select","String","opt"],"mappings":";;;AAaA,MAAMA,eAAe,CAACC,QAClB,AAAiB,YAAjB,OAAOA,SAAsB,AAAiB,YAAjB,OAAOA;AAEjC,MAAMC,iBAAiBC,oBAAoB,CAAC,EAAEC,KAAK,EAAE;IACxD,MAAMC,UAA0BD,MAAM,OAAO,IAAI,EAAE;IAEnD,OAAO,WAAP,GACI,oBAACE,QAAMA;QACH,OAAOF,MAAM,KAAK;QAClB,MAAMA,MAAM,IAAI;QAChB,aAAaA,MAAM,WAAW;QAC9B,aAAaA,MAAM,WAAW;QAC9B,MAAMA,MAAM,IAAI;QAChB,OAAOJ,aAAaI,MAAM,KAAK,IAAIG,OAAOH,MAAM,KAAK,IAAI;QACzD,UAAUH,CAAAA;YACNG,MAAM,QAAQ,CAACH;YACfG,MAAM,MAAM;QAChB;QACA,UAAUA,MAAM,QAAQ;QAExB,oBAAoB,CAACA,MAAM,QAAQ;QACnC,UAAUA,MAAM,QAAQ;QACxB,YAAYA,MAAM,UAAU;QAC5B,SAASC,QAAQ,GAAG,CAACG,CAAAA,MAAQ;gBACzB,OAAOA,IAAI,KAAK;gBAChB,OAAOR,aAAaQ,IAAI,KAAK,IAAID,OAAOC,IAAI,KAAK,IAAIA,IAAI,KAAK;gBAC9D,UAAUA,IAAI,QAAQ;YAC1B;;AAGZ"}
@@ -0,0 +1,8 @@
1
+ import React from "react";
2
+ /**
3
+ * No menu entry: the header indicator is the way in, and it downloads the report directly. The
4
+ * panel remains reachable by URL for anyone who wants the namespace filter or the session list.
5
+ */
6
+ export declare const Debugger: (() => React.JSX.Element) & {
7
+ displayName: string;
8
+ };
@@ -0,0 +1,25 @@
1
+ import react, { useEffect } from "react";
2
+ import { observer } from "mobx-react-lite";
3
+ import { AdminConfig } from "../../config/AdminConfig.js";
4
+ import { AdminLayout } from "../../components/AdminLayout.js";
5
+ import { useCanCaptureDebugData } from "./permissions.js";
6
+ import { debuggerStore } from "./DebuggerStore.js";
7
+ import { DebuggerView } from "./DebuggerView.js";
8
+ import { DebuggerRoutes } from "./routes.js";
9
+ const Debugger = observer(()=>{
10
+ const canDebug = useCanCaptureDebugData();
11
+ useEffect(()=>{
12
+ debuggerStore.applyPermission(canDebug);
13
+ }, [
14
+ canDebug
15
+ ]);
16
+ return /*#__PURE__*/ react.createElement(AdminConfig, null, /*#__PURE__*/ react.createElement(AdminConfig.Route, {
17
+ route: DebuggerRoutes.Debugger,
18
+ element: /*#__PURE__*/ react.createElement(AdminLayout, {
19
+ title: "Debugger"
20
+ }, /*#__PURE__*/ react.createElement(DebuggerView, null))
21
+ }));
22
+ });
23
+ export { Debugger };
24
+
25
+ //# sourceMappingURL=Debugger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"features/debugger/Debugger.js","sources":["../../../src/features/debugger/Debugger.tsx"],"sourcesContent":["import React, { useEffect } from \"react\";\nimport { observer } from \"mobx-react-lite\";\nimport { AdminConfig } from \"~/config/AdminConfig.js\";\nimport { AdminLayout } from \"~/components/AdminLayout.js\";\nimport { useCanCaptureDebugData } from \"./permissions.js\";\nimport { debuggerStore } from \"./DebuggerStore.js\";\nimport { DebuggerView } from \"./DebuggerView.js\";\nimport { DebuggerRoutes } from \"./routes.js\";\n\n/**\n * No menu entry: the header indicator is the way in, and it downloads the report directly. The\n * panel remains reachable by URL for anyone who wants the namespace filter or the session list.\n */\nexport const Debugger = observer(() => {\n const canDebug = useCanCaptureDebugData();\n\n /**\n * Holding the permission is the opt-in, so capture starts on. An identity that has explicitly\n * turned it off keeps it off; one that loses the permission has it turned off for them.\n */\n useEffect(() => {\n debuggerStore.applyPermission(canDebug);\n }, [canDebug]);\n\n return (\n <AdminConfig>\n <AdminConfig.Route\n route={DebuggerRoutes.Debugger}\n element={\n <AdminLayout title={\"Debugger\"}>\n <DebuggerView />\n </AdminLayout>\n }\n />\n </AdminConfig>\n );\n});\n"],"names":["Debugger","observer","canDebug","useCanCaptureDebugData","useEffect","debuggerStore","AdminConfig","DebuggerRoutes","AdminLayout","DebuggerView"],"mappings":";;;;;;;;AAaO,MAAMA,WAAWC,SAAS;IAC7B,MAAMC,WAAWC;IAMjBC,UAAU;QACNC,cAAc,eAAe,CAACH;IAClC,GAAG;QAACA;KAAS;IAEb,OAAO,WAAP,GACI,oBAACI,aAAWA,MAAAA,WAAAA,GACR,oBAACA,YAAY,KAAK;QACd,OAAOC,eAAe,QAAQ;QAC9B,uBACI,oBAACC,aAAWA;YAAC,OAAO;yBAChB,oBAACC,cAAYA;;AAMrC"}
@@ -0,0 +1,16 @@
1
+ import React from "react";
2
+ /**
3
+ * Says that capture is on, how much has been collected, and offers the two things worth doing
4
+ * about it.
5
+ *
6
+ * Renders nothing when the toggle is off, which is the normal state - the header is not the place to
7
+ * advertise a feature nobody switched on. When it is on it is deliberately hard to miss, because
8
+ * leaving capture running is the mistake it exists to prevent.
9
+ *
10
+ * Clearing matters as much as downloading: an hour of browsing collects a great deal, and everything
11
+ * held is in memory and lands in the next report whether or not it is relevant to the problem being
12
+ * reproduced.
13
+ */
14
+ export declare const DebuggerIndicator: (() => React.JSX.Element | null) & {
15
+ displayName: string;
16
+ };
@@ -0,0 +1,31 @@
1
+ import react from "react";
2
+ import { observer } from "mobx-react-lite";
3
+ import { DropdownMenu, Tag } from "@webiny/admin-ui";
4
+ import { ReactComponent } from "@webiny/icons/bug_report.svg";
5
+ import { debuggerStore } from "./DebuggerStore.js";
6
+ import { downloadReport } from "./report.js";
7
+ const DebuggerIndicator = observer(()=>{
8
+ if (!debuggerStore.enabled) return null;
9
+ const count = debuggerStore.entryCount;
10
+ const hasEntries = count > 0;
11
+ return /*#__PURE__*/ react.createElement(DropdownMenu, {
12
+ trigger: /*#__PURE__*/ react.createElement(Tag, {
13
+ variant: "warning",
14
+ icon: /*#__PURE__*/ react.createElement(ReactComponent, null),
15
+ content: hasEntries ? `Debug mode · ${count}` : "Debug mode",
16
+ title: hasEntries ? `Debug capture is on. ${count} entries collected.` : "Debug capture is on. Nothing collected yet.",
17
+ className: "cursor-pointer"
18
+ })
19
+ }, /*#__PURE__*/ react.createElement(DropdownMenu.Item, {
20
+ text: "Download report",
21
+ disabled: !hasEntries,
22
+ onClick: downloadReport
23
+ }), /*#__PURE__*/ react.createElement(DropdownMenu.Item, {
24
+ text: "Clear collected data",
25
+ disabled: !hasEntries,
26
+ onClick: debuggerStore.clear
27
+ }));
28
+ });
29
+ export { DebuggerIndicator };
30
+
31
+ //# sourceMappingURL=DebuggerIndicator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"features/debugger/DebuggerIndicator.js","sources":["../../../src/features/debugger/DebuggerIndicator.tsx"],"sourcesContent":["import React from \"react\";\nimport { observer } from \"mobx-react-lite\";\nimport { DropdownMenu, Tag } from \"@webiny/admin-ui\";\nimport { ReactComponent as DebuggerIcon } from \"@webiny/icons/bug_report.svg\";\nimport { debuggerStore } from \"./DebuggerStore.js\";\nimport { downloadReport } from \"./report.js\";\n\n/**\n * Says that capture is on, how much has been collected, and offers the two things worth doing\n * about it.\n *\n * Renders nothing when the toggle is off, which is the normal state - the header is not the place to\n * advertise a feature nobody switched on. When it is on it is deliberately hard to miss, because\n * leaving capture running is the mistake it exists to prevent.\n *\n * Clearing matters as much as downloading: an hour of browsing collects a great deal, and everything\n * held is in memory and lands in the next report whether or not it is relevant to the problem being\n * reproduced.\n */\nexport const DebuggerIndicator = observer(() => {\n if (!debuggerStore.enabled) {\n return null;\n }\n\n const count = debuggerStore.entryCount;\n const hasEntries = count > 0;\n\n return (\n <DropdownMenu\n trigger={\n <Tag\n variant={\"warning\"}\n icon={<DebuggerIcon />}\n content={hasEntries ? `Debug mode · ${count}` : \"Debug mode\"}\n title={\n hasEntries\n ? `Debug capture is on. ${count} entries collected.`\n : \"Debug capture is on. Nothing collected yet.\"\n }\n className={\"cursor-pointer\"}\n />\n }\n >\n <DropdownMenu.Item\n text={\"Download report\"}\n disabled={!hasEntries}\n onClick={downloadReport}\n />\n <DropdownMenu.Item\n text={\"Clear collected data\"}\n disabled={!hasEntries}\n onClick={debuggerStore.clear}\n />\n </DropdownMenu>\n );\n});\n"],"names":["DebuggerIndicator","observer","debuggerStore","count","hasEntries","DropdownMenu","Tag","DebuggerIcon","downloadReport"],"mappings":";;;;;;AAmBO,MAAMA,oBAAoBC,SAAS;IACtC,IAAI,CAACC,cAAc,OAAO,EACtB,OAAO;IAGX,MAAMC,QAAQD,cAAc,UAAU;IACtC,MAAME,aAAaD,QAAQ;IAE3B,OAAO,WAAP,GACI,oBAACE,cAAYA;QACT,uBACI,oBAACC,KAAGA;YACA,SAAS;YACT,oBAAM,oBAACC,gBAAYA;YACnB,SAASH,aAAa,CAAC,aAAa,EAAED,OAAO,GAAG;YAChD,OACIC,aACM,CAAC,qBAAqB,EAAED,MAAM,mBAAmB,CAAC,GAClD;YAEV,WAAW;;qBAInB,oBAACE,aAAa,IAAI;QACd,MAAM;QACN,UAAU,CAACD;QACX,SAASI;sBAEb,oBAACH,aAAa,IAAI;QACd,MAAM;QACN,UAAU,CAACD;QACX,SAASF,cAAc,KAAK;;AAI5C"}
@@ -0,0 +1,55 @@
1
+ export interface IDebugEntry {
2
+ seq: number;
3
+ namespace: string;
4
+ timestamp: number;
5
+ elapsed: number;
6
+ data: unknown;
7
+ }
8
+ export interface IDebugPayload {
9
+ enabled: boolean;
10
+ requestId?: string;
11
+ url?: string;
12
+ namespaces?: string[];
13
+ operations?: string[];
14
+ entries?: IDebugEntry[];
15
+ bytes?: number;
16
+ dropped?: number;
17
+ truncated?: boolean;
18
+ }
19
+ export interface ICollectedSession extends IDebugPayload {
20
+ collectedAt: number;
21
+ }
22
+ /**
23
+ * Holds the debug toggle and the sessions collected from responses.
24
+ *
25
+ * The toggle persists across reloads, because reproducing a bug often involves one. The collected
26
+ * sessions deliberately do not: they hold customer data, and leaving that in browser storage after
27
+ * the session is a worse exposure than the response itself, which is transient.
28
+ */
29
+ export declare class DebuggerStore {
30
+ private _enabled;
31
+ private _namespaces;
32
+ private _sessions;
33
+ constructor();
34
+ /**
35
+ * Turns capture on for an identity that holds the permission, unless they have already turned it
36
+ * off themselves.
37
+ *
38
+ * Holding `dev-tools.debug` is the opt-in: the permission is granted deliberately, for a support
39
+ * session, and nobody should then have to find a second switch before the thing they were asked
40
+ * to reproduce is captured.
41
+ */
42
+ applyPermission: (canCapture: boolean) => void;
43
+ get enabled(): boolean;
44
+ get namespaces(): string;
45
+ get sessions(): ICollectedSession[];
46
+ get entryCount(): number;
47
+ setEnabled: (enabled: boolean) => void;
48
+ setNamespaces: (namespaces: string) => void;
49
+ collect: (payload: IDebugPayload) => void;
50
+ clear: () => void;
51
+ }
52
+ /**
53
+ * A single store instance, read by the Apollo link on every request and by the panel.
54
+ */
55
+ export declare const debuggerStore: DebuggerStore;
@@ -0,0 +1,65 @@
1
+ import { makeAutoObservable } from "mobx";
2
+ const TOGGLE_STORAGE_KEY = "webiny_debugger_enabled";
3
+ const NAMESPACES_STORAGE_KEY = "webiny_debugger_namespaces";
4
+ const readStorage = (key)=>{
5
+ try {
6
+ return window.localStorage.getItem(key);
7
+ } catch {
8
+ return null;
9
+ }
10
+ };
11
+ const writeStorage = (key, value)=>{
12
+ try {
13
+ if (null === value) return void window.localStorage.removeItem(key);
14
+ window.localStorage.setItem(key, value);
15
+ } catch {}
16
+ };
17
+ class DebuggerStore {
18
+ constructor(){
19
+ this._sessions = [];
20
+ this.applyPermission = (canCapture)=>{
21
+ if (!canCapture) {
22
+ this._enabled = false;
23
+ return;
24
+ }
25
+ if (null === readStorage(TOGGLE_STORAGE_KEY)) this._enabled = true;
26
+ };
27
+ this.setEnabled = (enabled)=>{
28
+ this._enabled = enabled;
29
+ writeStorage(TOGGLE_STORAGE_KEY, enabled ? "true" : "false");
30
+ };
31
+ this.setNamespaces = (namespaces)=>{
32
+ this._namespaces = namespaces;
33
+ writeStorage(NAMESPACES_STORAGE_KEY, namespaces || null);
34
+ };
35
+ this.collect = (payload)=>{
36
+ if (!payload.entries?.length) return;
37
+ this._sessions.push({
38
+ ...payload,
39
+ collectedAt: Date.now()
40
+ });
41
+ };
42
+ this.clear = ()=>{
43
+ this._sessions = [];
44
+ };
45
+ this._enabled = "true" === readStorage(TOGGLE_STORAGE_KEY);
46
+ this._namespaces = readStorage(NAMESPACES_STORAGE_KEY) || "*";
47
+ makeAutoObservable(this);
48
+ }
49
+ get enabled() {
50
+ return this._enabled;
51
+ }
52
+ get namespaces() {
53
+ return this._namespaces;
54
+ }
55
+ get sessions() {
56
+ return this._sessions;
57
+ }
58
+ get entryCount() {
59
+ return this._sessions.reduce((total, session)=>total + (session.entries?.length || 0), 0);
60
+ }
61
+ }
62
+ const debuggerStore = new DebuggerStore();
63
+ export { DebuggerStore, debuggerStore };
64
+
65
+ //# sourceMappingURL=DebuggerStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"features/debugger/DebuggerStore.js","sources":["../../../src/features/debugger/DebuggerStore.ts"],"sourcesContent":["import { makeAutoObservable } from \"mobx\";\n\nconst TOGGLE_STORAGE_KEY = \"webiny_debugger_enabled\";\nconst NAMESPACES_STORAGE_KEY = \"webiny_debugger_namespaces\";\n\nexport interface IDebugEntry {\n seq: number;\n namespace: string;\n timestamp: number;\n elapsed: number;\n data: unknown;\n}\n\nexport interface IDebugPayload {\n enabled: boolean;\n requestId?: string;\n url?: string;\n namespaces?: string[];\n operations?: string[];\n entries?: IDebugEntry[];\n bytes?: number;\n dropped?: number;\n truncated?: boolean;\n}\n\nexport interface ICollectedSession extends IDebugPayload {\n collectedAt: number;\n}\n\nconst readStorage = (key: string): string | null => {\n try {\n return window.localStorage.getItem(key);\n } catch {\n return null;\n }\n};\n\nconst writeStorage = (key: string, value: string | null): void => {\n try {\n if (value === null) {\n window.localStorage.removeItem(key);\n return;\n }\n window.localStorage.setItem(key, value);\n } catch {\n // Private windows and blocked site data both throw. The toggle simply will not persist.\n }\n};\n\n/**\n * Holds the debug toggle and the sessions collected from responses.\n *\n * The toggle persists across reloads, because reproducing a bug often involves one. The collected\n * sessions deliberately do not: they hold customer data, and leaving that in browser storage after\n * the session is a worse exposure than the response itself, which is transient.\n */\nexport class DebuggerStore {\n private _enabled: boolean;\n private _namespaces: string;\n private _sessions: ICollectedSession[] = [];\n\n public constructor() {\n /**\n * Absent means \"no choice made yet\", which is different from an explicit \"off\" - the first\n * decides whether the permission turns capture on, the second must survive it.\n */\n this._enabled = readStorage(TOGGLE_STORAGE_KEY) === \"true\";\n this._namespaces = readStorage(NAMESPACES_STORAGE_KEY) || \"*\";\n makeAutoObservable(this);\n }\n\n /**\n * Turns capture on for an identity that holds the permission, unless they have already turned it\n * off themselves.\n *\n * Holding `dev-tools.debug` is the opt-in: the permission is granted deliberately, for a support\n * session, and nobody should then have to find a second switch before the thing they were asked\n * to reproduce is captured.\n */\n public applyPermission = (canCapture: boolean): void => {\n if (!canCapture) {\n this._enabled = false;\n return;\n }\n\n if (readStorage(TOGGLE_STORAGE_KEY) === null) {\n this._enabled = true;\n }\n };\n\n public get enabled(): boolean {\n return this._enabled;\n }\n\n public get namespaces(): string {\n return this._namespaces;\n }\n\n public get sessions(): ICollectedSession[] {\n return this._sessions;\n }\n\n public get entryCount(): number {\n return this._sessions.reduce((total, session) => {\n return total + (session.entries?.length || 0);\n }, 0);\n }\n\n public setEnabled = (enabled: boolean): void => {\n this._enabled = enabled;\n writeStorage(TOGGLE_STORAGE_KEY, enabled ? \"true\" : \"false\");\n };\n\n public setNamespaces = (namespaces: string): void => {\n this._namespaces = namespaces;\n writeStorage(NAMESPACES_STORAGE_KEY, namespaces || null);\n };\n\n public collect = (payload: IDebugPayload): void => {\n /**\n * The server already omits sessions that captured nothing. This guards the case where a\n * response carries an envelope with no entries anyway - there is nothing to read in it, and\n * it would only pad the report.\n */\n if (!payload.entries?.length) {\n return;\n }\n\n this._sessions.push({ ...payload, collectedAt: Date.now() });\n };\n\n public clear = (): void => {\n this._sessions = [];\n };\n}\n\n/**\n * A single store instance, read by the Apollo link on every request and by the panel.\n */\nexport const debuggerStore = new DebuggerStore();\n"],"names":["TOGGLE_STORAGE_KEY","NAMESPACES_STORAGE_KEY","readStorage","key","window","writeStorage","value","DebuggerStore","canCapture","enabled","namespaces","payload","Date","makeAutoObservable","total","session","debuggerStore"],"mappings":";AAEA,MAAMA,qBAAqB;AAC3B,MAAMC,yBAAyB;AA0B/B,MAAMC,cAAc,CAACC;IACjB,IAAI;QACA,OAAOC,OAAO,YAAY,CAAC,OAAO,CAACD;IACvC,EAAE,OAAM;QACJ,OAAO;IACX;AACJ;AAEA,MAAME,eAAe,CAACF,KAAaG;IAC/B,IAAI;QACA,IAAIA,AAAU,SAAVA,OAAgB,YAChBF,OAAO,YAAY,CAAC,UAAU,CAACD;QAGnCC,OAAO,YAAY,CAAC,OAAO,CAACD,KAAKG;IACrC,EAAE,OAAM,CAER;AACJ;AASO,MAAMC;IAKT,aAAqB;aAFb,SAAS,GAAwB,EAAE;QAmB1C,KACM,eAAe,GAAG,CAACC;YACtB,IAAI,CAACA,YAAY;gBACb,IAAI,CAAC,QAAQ,GAAG;gBAChB;YACJ;YAEA,IAAIN,AAAoC,SAApCA,YAAYF,qBACZ,IAAI,CAAC,QAAQ,GAAG;QAExB;aAoBO,UAAU,GAAG,CAACS;YACjB,IAAI,CAAC,QAAQ,GAAGA;YAChBJ,aAAaL,oBAAoBS,UAAU,SAAS;QACxD;aAEO,aAAa,GAAG,CAACC;YACpB,IAAI,CAAC,WAAW,GAAGA;YACnBL,aAAaJ,wBAAwBS,cAAc;QACvD;aAEO,OAAO,GAAG,CAACC;YAMd,IAAI,CAACA,QAAQ,OAAO,EAAE,QAClB;YAGJ,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;gBAAE,GAAGA,OAAO;gBAAE,aAAaC,KAAK,GAAG;YAAG;QAC9D;aAEO,KAAK,GAAG;YACX,IAAI,CAAC,SAAS,GAAG,EAAE;QACvB;QAnEI,IAAI,CAAC,QAAQ,GAAGV,AAAoC,WAApCA,YAAYF;QAC5B,IAAI,CAAC,WAAW,GAAGE,YAAYD,2BAA2B;QAC1DY,mBAAmB,IAAI;IAC3B;IAqBA,IAAW,UAAmB;QAC1B,OAAO,IAAI,CAAC,QAAQ;IACxB;IAEA,IAAW,aAAqB;QAC5B,OAAO,IAAI,CAAC,WAAW;IAC3B;IAEA,IAAW,WAAgC;QACvC,OAAO,IAAI,CAAC,SAAS;IACzB;IAEA,IAAW,aAAqB;QAC5B,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAACC,OAAOC,UAC1BD,QAASC,CAAAA,QAAQ,OAAO,EAAE,UAAU,IAC5C;IACP;AA4BJ;AAKO,MAAMC,gBAAgB,IAAIT"}
@@ -0,0 +1,4 @@
1
+ import React from "react";
2
+ export declare const DebuggerView: (() => React.JSX.Element) & {
3
+ displayName: string;
4
+ };
@@ -0,0 +1,49 @@
1
+ import react, { useCallback } from "react";
2
+ import { observer } from "mobx-react-lite";
3
+ import { Alert } from "@webiny/admin-ui/Alert/index.js";
4
+ import { Button } from "@webiny/admin-ui/Button/index.js";
5
+ import { Switch } from "@webiny/admin-ui/Switch/index.js";
6
+ import { debuggerStore } from "./DebuggerStore.js";
7
+ import { downloadReport } from "./report.js";
8
+ const DebuggerView = observer(()=>{
9
+ const onToggle = useCallback((checked)=>{
10
+ debuggerStore.setEnabled(checked);
11
+ }, []);
12
+ const onNamespacesChange = useCallback((event)=>{
13
+ debuggerStore.setNamespaces(event.target.value);
14
+ }, []);
15
+ const hasSessions = debuggerStore.sessions.length > 0;
16
+ return /*#__PURE__*/ react.createElement("div", {
17
+ className: "flex flex-col gap-lg p-lg"
18
+ }, debuggerStore.enabled ? /*#__PURE__*/ react.createElement(Alert, {
19
+ type: "warning"
20
+ }, "Debug capture is on. Responses include internal diagnostic data, which may contain content from your records. Turn it off when you are done.") : null, /*#__PURE__*/ react.createElement(Switch, {
21
+ label: "Capture debug data",
22
+ checked: debuggerStore.enabled,
23
+ onChange: onToggle,
24
+ note: "Reproduce the problem with this on, then download the report and send it to support."
25
+ }), /*#__PURE__*/ react.createElement("label", {
26
+ className: "flex flex-col gap-xs"
27
+ }, /*#__PURE__*/ react.createElement("span", null, "Namespaces"), /*#__PURE__*/ react.createElement("input", {
28
+ type: "text",
29
+ className: "border rounded-md p-sm",
30
+ value: debuggerStore.namespaces,
31
+ onChange: onNamespacesChange
32
+ }), /*#__PURE__*/ react.createElement("span", {
33
+ className: "text-sm"
34
+ }, "Leave as * to capture everything, or narrow it down - for example cms.os.*")), /*#__PURE__*/ react.createElement("div", {
35
+ className: "flex gap-sm items-center"
36
+ }, /*#__PURE__*/ react.createElement("span", null, debuggerStore.sessions.length, " responses collected, ", debuggerStore.entryCount, " ", "entries"), /*#__PURE__*/ react.createElement(Button, {
37
+ text: "Download report",
38
+ onClick: downloadReport,
39
+ disabled: !hasSessions
40
+ }), /*#__PURE__*/ react.createElement(Button, {
41
+ variant: "secondary",
42
+ text: "Clear",
43
+ onClick: debuggerStore.clear,
44
+ disabled: !hasSessions
45
+ })));
46
+ });
47
+ export { DebuggerView };
48
+
49
+ //# sourceMappingURL=DebuggerView.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"features/debugger/DebuggerView.js","sources":["../../../src/features/debugger/DebuggerView.tsx"],"sourcesContent":["import React, { useCallback } from \"react\";\nimport { observer } from \"mobx-react-lite\";\nimport { Alert } from \"@webiny/admin-ui/Alert/index.js\";\nimport { Button } from \"@webiny/admin-ui/Button/index.js\";\nimport { Switch } from \"@webiny/admin-ui/Switch/index.js\";\nimport { debuggerStore } from \"./DebuggerStore.js\";\nimport { downloadReport } from \"./report.js\";\n\nexport const DebuggerView = observer(() => {\n const onToggle = useCallback((checked: boolean) => {\n debuggerStore.setEnabled(checked);\n }, []);\n\n const onNamespacesChange = useCallback((event: React.ChangeEvent<HTMLInputElement>) => {\n debuggerStore.setNamespaces(event.target.value);\n }, []);\n\n const hasSessions = debuggerStore.sessions.length > 0;\n\n return (\n <div className={\"flex flex-col gap-lg p-lg\"}>\n {debuggerStore.enabled ? (\n <Alert type={\"warning\"}>\n Debug capture is on. Responses include internal diagnostic data, which may\n contain content from your records. Turn it off when you are done.\n </Alert>\n ) : null}\n\n <Switch\n label={\"Capture debug data\"}\n checked={debuggerStore.enabled}\n onChange={onToggle}\n note={\n \"Reproduce the problem with this on, then download the report and send it to \" +\n \"support.\"\n }\n />\n\n <label className={\"flex flex-col gap-xs\"}>\n <span>Namespaces</span>\n <input\n type={\"text\"}\n className={\"border rounded-md p-sm\"}\n value={debuggerStore.namespaces}\n onChange={onNamespacesChange}\n />\n <span className={\"text-sm\"}>\n Leave as * to capture everything, or narrow it down - for example cms.os.*\n </span>\n </label>\n\n <div className={\"flex gap-sm items-center\"}>\n <span>\n {debuggerStore.sessions.length} responses collected, {debuggerStore.entryCount}{\" \"}\n entries\n </span>\n <Button text={\"Download report\"} onClick={downloadReport} disabled={!hasSessions} />\n <Button\n variant={\"secondary\"}\n text={\"Clear\"}\n onClick={debuggerStore.clear}\n disabled={!hasSessions}\n />\n </div>\n </div>\n );\n});\n"],"names":["DebuggerView","observer","onToggle","useCallback","checked","debuggerStore","onNamespacesChange","event","hasSessions","Alert","Switch","Button","downloadReport"],"mappings":";;;;;;;AAQO,MAAMA,eAAeC,SAAS;IACjC,MAAMC,WAAWC,YAAY,CAACC;QAC1BC,cAAc,UAAU,CAACD;IAC7B,GAAG,EAAE;IAEL,MAAME,qBAAqBH,YAAY,CAACI;QACpCF,cAAc,aAAa,CAACE,MAAM,MAAM,CAAC,KAAK;IAClD,GAAG,EAAE;IAEL,MAAMC,cAAcH,cAAc,QAAQ,CAAC,MAAM,GAAG;IAEpD,OAAO,WAAP,GACI,oBAAC;QAAI,WAAW;OACXA,cAAc,OAAO,GAAG,WAAH,GAClB,oBAACI,OAAKA;QAAC,MAAM;OAAW,kJAIxB,oBAEJ,oBAACC,QAAMA;QACH,OAAO;QACP,SAASL,cAAc,OAAO;QAC9B,UAAUH;QACV,MACI;sBAKR,oBAAC;QAAM,WAAW;qBACd,oBAAC,cAAK,6BACN,oBAAC;QACG,MAAM;QACN,WAAW;QACX,OAAOG,cAAc,UAAU;QAC/B,UAAUC;sBAEd,oBAAC;QAAK,WAAW;OAAW,8FAKhC,oBAAC;QAAI,WAAW;qBACZ,oBAAC,cACID,cAAc,QAAQ,CAAC,MAAM,EAAC,0BAAuBA,cAAc,UAAU,EAAE,KAAI,0BAGxF,oBAACM,QAAMA;QAAC,MAAM;QAAmB,SAASC;QAAgB,UAAU,CAACJ;sBACrE,oBAACG,QAAMA;QACH,SAAS;QACT,MAAM;QACN,SAASN,cAAc,KAAK;QAC5B,UAAU,CAACG;;AAK/B"}
@@ -0,0 +1,15 @@
1
+ import { GraphQLExtensionsEvent, GraphQLExtensionsEventHandler } from "@webiny/app/features/graphqlClient/index.js";
2
+ /**
3
+ * Collects debug data from responses that did not go through Apollo.
4
+ *
5
+ * Newer parts of Admin - Website Builder among them - use the fetch-based `GraphQLClient` rather
6
+ * than Apollo, and that client returns only `data`. Without this the debugger would silently miss
7
+ * everything they do, which looks identical to capture being broken.
8
+ */
9
+ declare class GraphQLExtensionsDebugHandlerImpl implements GraphQLExtensionsEventHandler.Interface {
10
+ handle(event: GraphQLExtensionsEvent): Promise<void>;
11
+ }
12
+ export declare const GraphQLExtensionsDebugHandler: typeof GraphQLExtensionsDebugHandlerImpl & {
13
+ __abstraction: import("@webiny/di").Abstraction<import("@webiny/app/features/eventPublisher/abstractions.js").IEventHandler<GraphQLExtensionsEvent>>;
14
+ };
15
+ export {};
@@ -0,0 +1,15 @@
1
+ import { GraphQLExtensionsEventHandler } from "@webiny/app/features/graphqlClient/index.js";
2
+ import { debuggerStore } from "./DebuggerStore.js";
3
+ class GraphQLExtensionsDebugHandlerImpl {
4
+ async handle(event) {
5
+ const debug = event.payload.extensions.debug;
6
+ if (debug) debuggerStore.collect(debug);
7
+ }
8
+ }
9
+ const GraphQLExtensionsDebugHandler = GraphQLExtensionsEventHandler.createImplementation({
10
+ implementation: GraphQLExtensionsDebugHandlerImpl,
11
+ dependencies: []
12
+ });
13
+ export { GraphQLExtensionsDebugHandler };
14
+
15
+ //# sourceMappingURL=GraphQLExtensionsDebugHandler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"features/debugger/GraphQLExtensionsDebugHandler.js","sources":["../../../src/features/debugger/GraphQLExtensionsDebugHandler.ts"],"sourcesContent":["import {\n GraphQLExtensionsEvent,\n GraphQLExtensionsEventHandler\n} from \"@webiny/app/features/graphqlClient/index.js\";\nimport { debuggerStore, type IDebugPayload } from \"./DebuggerStore.js\";\n\n/**\n * Collects debug data from responses that did not go through Apollo.\n *\n * Newer parts of Admin - Website Builder among them - use the fetch-based `GraphQLClient` rather\n * than Apollo, and that client returns only `data`. Without this the debugger would silently miss\n * everything they do, which looks identical to capture being broken.\n */\nclass GraphQLExtensionsDebugHandlerImpl implements GraphQLExtensionsEventHandler.Interface {\n async handle(event: GraphQLExtensionsEvent): Promise<void> {\n const debug = event.payload.extensions.debug as IDebugPayload | undefined;\n\n if (debug) {\n debuggerStore.collect(debug);\n }\n }\n}\n\nexport const GraphQLExtensionsDebugHandler = GraphQLExtensionsEventHandler.createImplementation({\n implementation: GraphQLExtensionsDebugHandlerImpl,\n dependencies: []\n});\n"],"names":["GraphQLExtensionsDebugHandlerImpl","event","debug","debuggerStore","GraphQLExtensionsDebugHandler","GraphQLExtensionsEventHandler"],"mappings":";;AAaA,MAAMA;IACF,MAAM,OAAOC,KAA6B,EAAiB;QACvD,MAAMC,QAAQD,MAAM,OAAO,CAAC,UAAU,CAAC,KAAK;QAE5C,IAAIC,OACAC,cAAc,OAAO,CAACD;IAE9B;AACJ;AAEO,MAAME,gCAAgCC,8BAA8B,oBAAoB,CAAC;IAC5F,gBAAgBL;IAChB,cAAc,EAAE;AACpB"}
@@ -0,0 +1,12 @@
1
+ import { ApolloLink } from "apollo-link";
2
+ import type { DebuggerStore } from "./DebuggerStore.js";
3
+ /**
4
+ * Collects whatever debug data comes back.
5
+ *
6
+ * Deliberately sends no request header. Whether to capture is decided entirely by the API from the
7
+ * identity's permissions, which keeps this off the CORS and CloudFront header whitelists - a header
8
+ * added there is cached in preflight responses for a day, so rolling one out breaks requests
9
+ * intermittently until every cache entry expires.
10
+ */
11
+ export declare const DEBUG_HEADER = "x-webiny-debug";
12
+ export declare const createDebuggerLink: (store: DebuggerStore) => ApolloLink;
@@ -0,0 +1,10 @@
1
+ import { ApolloLink } from "apollo-link";
2
+ const DEBUG_HEADER = "x-webiny-debug";
3
+ const createDebuggerLink = (store)=>new ApolloLink((operation, forward)=>forward(operation).map((response)=>{
4
+ const debug = response.extensions?.debug;
5
+ if (debug) store.collect(debug);
6
+ return response;
7
+ }));
8
+ export { DEBUG_HEADER, createDebuggerLink };
9
+
10
+ //# sourceMappingURL=debuggerLink.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"features/debugger/debuggerLink.js","sources":["../../../src/features/debugger/debuggerLink.ts"],"sourcesContent":["import { ApolloLink } from \"apollo-link\";\nimport type { NextLink, Operation } from \"apollo-link\";\nimport type { DebuggerStore, IDebugPayload } from \"./DebuggerStore.js\";\n\n/**\n * Collects whatever debug data comes back.\n *\n * Deliberately sends no request header. Whether to capture is decided entirely by the API from the\n * identity's permissions, which keeps this off the CORS and CloudFront header whitelists - a header\n * added there is cached in preflight responses for a day, so rolling one out breaks requests\n * intermittently until every cache entry expires.\n */\nexport const DEBUG_HEADER = \"x-webiny-debug\";\n\nexport const createDebuggerLink = (store: DebuggerStore): ApolloLink => {\n return new ApolloLink((operation: Operation, forward: NextLink) => {\n /**\n * Kept for reference. Sending the header requires it on the CORS allow-list, which is\n * cached in preflight responses at CloudFront and in the browser for a day - so adding it\n * breaks requests intermittently until every cache entry expires. The API decides from the\n * identity's permissions instead, and needs nothing from the client.\n *\n * if (store.enabled) {\n * operation.setContext(({ headers = {} }: { headers?: Record<string, string> }) => {\n * return {\n * headers: {\n * ...headers,\n * [DEBUG_HEADER]: store.namespaces || \"*\"\n * }\n * };\n * });\n * }\n */\n return forward(operation).map(response => {\n /**\n * Batched requests carry the payload on one arbitrary operation's result, so every\n * response is inspected rather than only the one that was asked for.\n */\n const debug = (response.extensions as { debug?: IDebugPayload } | undefined)?.debug;\n\n if (debug) {\n store.collect(debug);\n }\n\n return response;\n });\n });\n};\n"],"names":["DEBUG_HEADER","createDebuggerLink","store","ApolloLink","operation","forward","response","debug"],"mappings":";AAYO,MAAMA,eAAe;AAErB,MAAMC,qBAAqB,CAACC,QACxB,IAAIC,WAAW,CAACC,WAAsBC,UAkBlCA,QAAQD,WAAW,GAAG,CAACE,CAAAA;YAK1B,MAAMC,QAASD,SAAS,UAAU,EAA4C;YAE9E,IAAIC,OACAL,MAAM,OAAO,CAACK;YAGlB,OAAOD;QACX"}
@@ -0,0 +1 @@
1
+ export declare const DebuggerFeature: import("@webiny/feature/admin").FeatureDefinition<any, []>;
@@ -0,0 +1,18 @@
1
+ import { ApolloLinkPlugin } from "@webiny/app";
2
+ import { plugins } from "@webiny/plugins";
3
+ import { createFeature } from "@webiny/feature/admin";
4
+ import { createDebuggerLink } from "./debuggerLink.js";
5
+ import { debuggerStore } from "./DebuggerStore.js";
6
+ import { DebuggerPermissionsFeature } from "./permissions.js";
7
+ import { GraphQLExtensionsDebugHandler } from "./GraphQLExtensionsDebugHandler.js";
8
+ const DebuggerFeature = createFeature({
9
+ name: "Debugger",
10
+ register (container) {
11
+ DebuggerPermissionsFeature.register(container);
12
+ container.register(GraphQLExtensionsDebugHandler).inSingletonScope();
13
+ plugins.register(new ApolloLinkPlugin(()=>createDebuggerLink(debuggerStore)));
14
+ }
15
+ });
16
+ export { DebuggerFeature };
17
+
18
+ //# sourceMappingURL=feature.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"features/debugger/feature.js","sources":["../../../src/features/debugger/feature.ts"],"sourcesContent":["import { ApolloLinkPlugin } from \"@webiny/app\";\nimport { plugins } from \"@webiny/plugins\";\nimport { createFeature } from \"@webiny/feature/admin\";\nimport { createDebuggerLink } from \"./debuggerLink.js\";\nimport { debuggerStore } from \"./DebuggerStore.js\";\nimport { DebuggerPermissionsFeature } from \"./permissions.js\";\nimport { GraphQLExtensionsDebugHandler } from \"./GraphQLExtensionsDebugHandler.js\";\n\nexport const DebuggerFeature = createFeature({\n name: \"Debugger\",\n register(container) {\n DebuggerPermissionsFeature.register(container);\n\n /**\n * Collects from the fetch-based client, which Apollo links never see.\n */\n container.register(GraphQLExtensionsDebugHandler).inSingletonScope();\n\n /**\n * The link is always registered; whether it does anything is decided per request from the\n * toggle. Registering conditionally would mean the link never appears for a toggle flipped\n * after start-up.\n */\n plugins.register(new ApolloLinkPlugin(() => createDebuggerLink(debuggerStore)));\n }\n});\n"],"names":["DebuggerFeature","createFeature","container","DebuggerPermissionsFeature","GraphQLExtensionsDebugHandler","plugins","ApolloLinkPlugin","createDebuggerLink","debuggerStore"],"mappings":";;;;;;;AAQO,MAAMA,kBAAkBC,cAAc;IACzC,MAAM;IACN,UAASC,SAAS;QACdC,2BAA2B,QAAQ,CAACD;QAKpCA,UAAU,QAAQ,CAACE,+BAA+B,gBAAgB;QAOlEC,QAAQ,QAAQ,CAAC,IAAIC,iBAAiB,IAAMC,mBAAmBC;IACnE;AACJ"}
@@ -0,0 +1,7 @@
1
+ export { Debugger } from "./Debugger.js";
2
+ export { DebuggerIndicator } from "./DebuggerIndicator.js";
3
+ export { DebuggerFeature } from "./feature.js";
4
+ export { debuggerStore, DebuggerStore } from "./DebuggerStore.js";
5
+ export { DebuggerRoutes } from "./routes.js";
6
+ export { DEBUGGER_PERMISSIONS_SCHEMA, DebuggerPermissions, useDebuggerPermissions } from "./permissions.js";
7
+ export { downloadReport } from "./report.js";
@@ -0,0 +1,7 @@
1
+ export { Debugger } from "./Debugger.js";
2
+ export { DebuggerIndicator } from "./DebuggerIndicator.js";
3
+ export { DebuggerFeature } from "./feature.js";
4
+ export { DebuggerStore, debuggerStore } from "./DebuggerStore.js";
5
+ export { DebuggerRoutes } from "./routes.js";
6
+ export { DEBUGGER_PERMISSIONS_SCHEMA, DebuggerPermissions, useDebuggerPermissions } from "./permissions.js";
7
+ export { downloadReport } from "./report.js";
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Registered under its own name rather than joining the `dev-tools` group declared by the
3
+ * playgrounds: `Security.Permissions` is keyed by name, so a second registration using the same name
4
+ * would replace theirs and hide their entities from the role editor.
5
+ *
6
+ * The permission itself is `dev-tools.debug`, so it still sits under the Dev Tools prefix - and note
7
+ * the consequence: `dev-tools.*` held by a Dev Tools full-access role matches it.
8
+ */
9
+ export declare const DEBUGGER_PERMISSIONS_SCHEMA: {
10
+ readonly prefix: "dev-tools";
11
+ readonly fullAccess: true;
12
+ readonly entities: [{
13
+ readonly id: "debug";
14
+ readonly title: "Debugger";
15
+ readonly permission: "dev-tools.debug";
16
+ readonly scopes: ["full"];
17
+ }];
18
+ };
19
+ export declare const DebuggerPermissions: import("@webiny/di").Abstraction<{
20
+ canAccess: (entityId: "debug") => boolean;
21
+ canAction: (action: string, entityId: "debug") => boolean;
22
+ } & {
23
+ canRead: (entityId: string) => boolean;
24
+ canCreate: (entityId: string) => boolean;
25
+ canEdit: (entityId: string, item?: import("~/permissions/index.js").OwnableItem) => boolean;
26
+ canDelete: (entityId: string, item?: import("~/permissions/index.js").OwnableItem) => boolean;
27
+ } & {
28
+ canPublish: (entityId: string) => boolean;
29
+ canUnpublish: (entityId: string) => boolean;
30
+ }>;
31
+ export declare const DebuggerPermissionsFeature: import("@webiny/feature/admin").FeatureDefinition<{
32
+ permissions: {
33
+ canAccess: (entityId: "debug") => boolean;
34
+ canAction: (action: string, entityId: "debug") => boolean;
35
+ } & {
36
+ canRead: (entityId: string) => boolean;
37
+ canCreate: (entityId: string) => boolean;
38
+ canEdit: (entityId: string, item?: import("~/permissions/index.js").OwnableItem) => boolean;
39
+ canDelete: (entityId: string, item?: import("~/permissions/index.js").OwnableItem) => boolean;
40
+ } & {
41
+ canPublish: (entityId: string) => boolean;
42
+ canUnpublish: (entityId: string) => boolean;
43
+ };
44
+ }, []>;
45
+ export declare const useDebuggerPermissions: () => {
46
+ canAccess: (entityId: "debug") => boolean;
47
+ canAction: (action: string, entityId: "debug") => boolean;
48
+ } & {
49
+ canRead: (entityId: string) => boolean;
50
+ canCreate: (entityId: string) => boolean;
51
+ canEdit: (entityId: string, item?: import("~/permissions/index.js").OwnableItem) => boolean;
52
+ canDelete: (entityId: string, item?: import("~/permissions/index.js").OwnableItem) => boolean;
53
+ } & {
54
+ canPublish: (entityId: string) => boolean;
55
+ canUnpublish: (entityId: string) => boolean;
56
+ };
57
+ export declare const DEBUG_PERMISSION_NAME = "dev-tools.debug";
58
+ /**
59
+ * Whether the current identity may capture debug data.
60
+ *
61
+ * An exact match, deliberately: `*` and `dev-tools.*` do not grant it. Capture runs automatically
62
+ * for whoever holds this, so a wildcard would leave it permanently on for every full-access
63
+ * administrator, collecting record content on every request for people who never asked for it.
64
+ *
65
+ * Full access is therefore not enough. The entity has to be granted deliberately, and that act is
66
+ * the opt-in.
67
+ */
68
+ export declare const useCanCaptureDebugData: () => boolean;