buro26-strapi-graphql 0.0.24 → 0.0.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -6,6 +6,8 @@ as co-location of GraphQL schema and resolvers, field overriding, and field auth
6
6
  This let's you define your GraphQL schema and resolvers in the content-type directory, making it easier to manage and
7
7
  maintain your GraphQL API.
8
8
 
9
+ This plugin is compatible with both Strapi v4 and Strapi v5.
10
+
9
11
  ## Getting started
10
12
 
11
13
  ```bash
@@ -21,7 +23,7 @@ the [Strapi GraphQL plugin](https://docs.strapi.io/dev-docs/plugins/graphql).
21
23
 
22
24
  ### Enable plugin
23
25
 
24
- Add plugin in `./config/plugins.js/ts` in your Strapi project.
26
+ Add plugin in `./config/plugins.[js/ts]` in your Strapi project.
25
27
 
26
28
  ```typescript
27
29
  export default () => ({
@@ -156,6 +158,54 @@ export default createGraphQLExtension(strapi => ({
156
158
  }));
157
159
  ```
158
160
 
161
+ ### Fluent Builder Pattern
162
+ The plugin also supports a builder pattern so that you can configure your extension using a fluent API. This is achieved by calling createGraphQLExtension() with no arguments. For example, you can write:
163
+
164
+ ```typescript
165
+ export default createGraphQLExtension()
166
+ .init(() => {
167
+ // Initialization logic here...
168
+ })
169
+ .typeDefs(`
170
+ extend type Query {
171
+ hello: String
172
+ }
173
+ `)
174
+ .resolvers({
175
+ Query: {
176
+ hello: () => 'Hello from builder!'
177
+ }
178
+ });
179
+ ```
180
+
181
+ In this pattern, `createGraphQLExtension()` detects that no argument was passed and returns a builder. The builder exposes methods like `.init()`, `.typeDefs()`, `.types()`, `.plugins()`, `.resolvers()`, and `.resolversConfig()` so you can chain calls and define your extension inline.
182
+
183
+ ### Shorter way to define a new field
184
+
185
+ The `createGraphQLFieldBuilder()` function provides a fluent builder API to create a single GraphQL field extension using Nexus. It simplifies the process of extending the GraphQL schema by letting you define the field's name, arguments, output type, resolver, and resolver configuration in a chainable way.
186
+
187
+ The builder pattern ensures that you only need to specify the necessary parts, and the extension is automatically registered using the provided settings. This approach minimizes boilerplate code while ensuring consistency across your GraphQL extensions.
188
+
189
+ Below is an example of how to define a new field using the builder pattern. This example creates a new query field called `helloWorld` that takes a non-null `name` argument and returns a non-null `String`.
190
+
191
+ ```typescript
192
+ import { createGraphQLFieldBuilder } from "buro26-strapi-graphql";
193
+ import { nonNull, stringArg } from 'nexus';
194
+
195
+ export default createGraphQLFieldBuilder('Query')
196
+ .fieldName('helloWorld')
197
+ .args({
198
+ name: nonNull(stringArg()),
199
+ })
200
+ .outputType(nonNull('String'))
201
+ .resolver(async (parent, args, ctx) => {
202
+ return `Hello World ${args.name}`;
203
+ })
204
+ .resolverConfig({
205
+ auth: false,
206
+ });
207
+ ```
208
+
159
209
  ### Overriding a field
160
210
 
161
211
  Sometimes you will need to override a field in an existing type. You can do this by extending the type and adding the
@@ -487,6 +537,27 @@ args into args that can be passed to the entityManager.
487
537
 
488
538
  This function is re-exported from the Strapi GraphQL plugin.
489
539
 
540
+ #### shadowCRUD
541
+
542
+ This function is a typesafe utility function to create shadow CRUD operations for a content type. It will create the CRUD operations for the content type and return the shadow CRUD object.
543
+
544
+ ```typescript
545
+ import { createGraphQLExtension, shadowCRUD } from 'buro26-strapi-graphql';
546
+
547
+ export default createGraphQLExtension((strapi) => ({
548
+
549
+ init() {
550
+ shadowCRUD('api::article.article')
551
+ .disableActions(['create', 'update', 'delete']);
552
+
553
+ shadowCRUD('api::category.category')
554
+ .field('title')
555
+ .disable();
556
+ }
557
+
558
+ }));
559
+ ```
560
+
490
561
  ## Test and Deploy
491
562
 
492
563
  ### Running tests
@@ -1,4 +1,4 @@
1
- import { type Strapi } from '@strapi/strapi';
1
+ import { type Strapi } from './types';
2
2
  declare const _default: ({ strapi }: {
3
3
  strapi: Strapi;
4
4
  }) => void;
@@ -1,6 +1,6 @@
1
1
  declare const _default: {
2
2
  myController: ({ strapi }: {
3
- strapi: import("@strapi/types").Strapi;
3
+ strapi: Required<import("@strapi/types").Strapi>;
4
4
  }) => {};
5
5
  };
6
6
  export default _default;
@@ -1,4 +1,4 @@
1
- import { Strapi } from '@strapi/strapi';
1
+ import type { Strapi } from '../types';
2
2
  declare const _default: ({ strapi }: {
3
3
  strapi: Strapi;
4
4
  }) => {};
@@ -1,4 +1,4 @@
1
- import { type Strapi } from '@strapi/strapi';
1
+ import { type Strapi } from './types';
2
2
  declare const _default: ({ strapi }: {
3
3
  strapi: Strapi;
4
4
  }) => void;
@@ -1,17 +1,16 @@
1
- import type { Strapi } from '@strapi/strapi';
2
1
  import type { GraphQLExtension } from './types';
3
2
  import type { Middleware, ResolveContext } from './utils';
4
3
  import type { GraphQLResolveInfo } from 'graphql';
5
4
  import type { GraphQLFieldConfig } from 'graphql/type';
6
5
  declare const _default: {
7
6
  register: ({ strapi }: {
8
- strapi: Strapi;
7
+ strapi: import("@strapi/types").Strapi;
9
8
  }) => Promise<void>;
10
9
  bootstrap: ({ strapi }: {
11
- strapi: Strapi;
10
+ strapi: Required<import("@strapi/types").Strapi>;
12
11
  }) => void;
13
12
  destroy: ({ strapi }: {
14
- strapi: Strapi;
13
+ strapi: Required<import("@strapi/types").Strapi>;
15
14
  }) => void;
16
15
  config: {
17
16
  default: {};
@@ -19,18 +18,18 @@ declare const _default: {
19
18
  };
20
19
  controllers: {
21
20
  myController: ({ strapi }: {
22
- strapi: Strapi;
21
+ strapi: Required<import("@strapi/types").Strapi>;
23
22
  }) => {};
24
23
  };
25
24
  routes: any[];
26
25
  services: {
27
26
  fileService: ({ strapi }: {
28
- strapi: Strapi;
27
+ strapi: Required<import("@strapi/types").Strapi>;
29
28
  }) => {
30
29
  getAllFilesInGraphQlDirectory(directoryPath: string, collectedExtensions?: GraphQLExtension[]): Promise<GraphQLExtension[]>;
31
30
  };
32
31
  graphQlService: ({ strapi }: {
33
- strapi: Strapi;
32
+ strapi: Required<import("@strapi/types").Strapi>;
34
33
  }) => {};
35
34
  };
36
35
  contentTypes: {};
@@ -40,12 +39,16 @@ declare const _default: {
40
39
  export default _default;
41
40
  export * from './types';
42
41
  export * from './utils';
43
- export declare const createGraphQLExtension: (factory: (strapi: Strapi) => GraphQLExtension) => GraphQLExtension;
44
42
  declare module '@strapi/strapi' {
45
43
  interface Strapi {
46
44
  createGraphQLExtension: (factory: (strapi: Strapi) => GraphQLExtension) => GraphQLExtension;
47
45
  }
48
46
  }
47
+ declare module '@strapi/types' {
48
+ interface Strapi {
49
+ createGraphQLExtension: (factory: (strapi: Strapi) => GraphQLExtension) => GraphQLExtension;
50
+ }
51
+ }
49
52
  /**
50
53
  * Extend Nexus's field definition to include a middleware array.
51
54
  */
@@ -17,7 +17,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
17
17
  return (mod && mod.__esModule) ? mod : { "default": mod };
18
18
  };
19
19
  Object.defineProperty(exports, "__esModule", { value: true });
20
- exports.createGraphQLExtension = void 0;
21
20
  const register_1 = __importDefault(require("./register"));
22
21
  const bootstrap_1 = __importDefault(require("./bootstrap"));
23
22
  const destroy_1 = __importDefault(require("./destroy"));
@@ -42,5 +41,3 @@ exports.default = {
42
41
  };
43
42
  __exportStar(require("./types"), exports);
44
43
  __exportStar(require("./utils"), exports);
45
- const createGraphQLExtension = (factory) => factory(strapi);
46
- exports.createGraphQLExtension = createGraphQLExtension;
@@ -1,5 +1,4 @@
1
- import type { Strapi } from '@strapi/strapi';
2
- import type { GraphQLExtension } from '../types';
1
+ import type { GraphQLExtension, Strapi } from '../types';
3
2
  declare const _default: ({ strapi }: {
4
3
  strapi: Strapi;
5
4
  }) => {
@@ -53,10 +53,13 @@ exports.default = ({ strapi }) => ({
53
53
  if (!graphqlModule) {
54
54
  return;
55
55
  }
56
- collectedExtensions.push({
57
- ...graphqlModule,
58
- ...(graphqlModule.default || {})
59
- });
56
+ // Support both ES module default export and CommonJS exports
57
+ let extension = graphqlModule.default || graphqlModule;
58
+ // If the extension is a builder (has a build function), call build() automatically
59
+ if (extension && typeof extension.build === 'function') {
60
+ extension = extension.build();
61
+ }
62
+ collectedExtensions.push(extension);
60
63
  });
61
64
  // Wait for all the promises to resolve
62
65
  await Promise.all(filePromises);
@@ -1,4 +1,4 @@
1
- import { type Strapi } from '@strapi/strapi';
1
+ import { type Strapi } from '../types';
2
2
  declare const _default: ({ strapi }: {
3
3
  strapi: Strapi;
4
4
  }) => {};
@@ -1,11 +1,11 @@
1
1
  declare const _default: {
2
2
  fileService: ({ strapi }: {
3
- strapi: import("@strapi/types").Strapi;
3
+ strapi: Required<import("@strapi/types").Strapi>;
4
4
  }) => {
5
5
  getAllFilesInGraphQlDirectory(directoryPath: string, collectedExtensions?: import("..").GraphQLExtension[]): Promise<import("..").GraphQLExtension[]>;
6
6
  };
7
7
  graphQlService: ({ strapi }: {
8
- strapi: import("@strapi/types").Strapi;
8
+ strapi: Required<import("@strapi/types").Strapi>;
9
9
  }) => {};
10
10
  };
11
11
  export default _default;
@@ -1,6 +1,6 @@
1
1
  import type { ResolveContext } from './utils';
2
2
  import type { GraphQLResolveInfo } from 'graphql';
3
- import type { Strapi } from '@strapi/strapi';
3
+ export type Strapi = typeof strapi;
4
4
  export interface GraphQLExtension {
5
5
  /**
6
6
  * Called when the extension is initialized, use this to perform any initialization logic
@@ -53,12 +53,12 @@ export interface GraphQLExtension {
53
53
  */
54
54
  resolversConfig?: () => Record<string, ResolverConfigOption>;
55
55
  }
56
- type ResolverConfigOption = {
56
+ export type ResolverConfigOption = {
57
57
  auth?: boolean | undefined;
58
58
  policies?: (string | PolicyFunction)[];
59
59
  middlewares?: MiddlewareFunction[];
60
60
  };
61
- type PolicyFunctionContext = {
61
+ export type PolicyFunctionContext = {
62
62
  parent: any;
63
63
  args: any;
64
64
  context: ResolveContext;
@@ -66,11 +66,10 @@ type PolicyFunctionContext = {
66
66
  state: ResolveContext['state'];
67
67
  http: any;
68
68
  };
69
- type PolicyFunctionOptions = {
69
+ export type PolicyFunctionOptions = {
70
70
  strapi: Strapi;
71
71
  };
72
- type PolicyFunction = (context: PolicyFunctionContext, config: any, opts: PolicyFunctionOptions) => boolean | Promise<boolean>;
73
- type MiddlewareFunction = (next: MiddlewareNextFunction, parent: any, args: any, context: ResolveContext, info: GraphQLResolveInfo) => any | Promise<any>;
74
- type MiddlewareNextFunction = (parent: any, args: any, context: ResolveContext, info: GraphQLResolveInfo) => Promise<any>;
75
- type ResolverFunction = (parent: any, args: any, context: ResolveContext, info: GraphQLResolveInfo) => any | Promise<any>;
76
- export {};
72
+ export type PolicyFunction = (context: PolicyFunctionContext, config: any, opts: PolicyFunctionOptions) => boolean | Promise<boolean>;
73
+ export type MiddlewareFunction = (next: MiddlewareNextFunction, parent: any, args: any, context: ResolveContext, info: GraphQLResolveInfo) => any | Promise<any>;
74
+ export type MiddlewareNextFunction = (parent: any, args: any, context: ResolveContext, info: GraphQLResolveInfo) => Promise<any>;
75
+ export type ResolverFunction = (parent: any, args: any, context: ResolveContext, info: GraphQLResolveInfo) => any | Promise<any>;
@@ -0,0 +1,31 @@
1
+ import type { GraphQLExtension, ResolverConfigOption, ResolverFunction } from '../types';
2
+ export type FieldExtensionOptions = {
3
+ rootType: string;
4
+ fieldName?: string;
5
+ resolver: ResolverFunction;
6
+ resolverConfig?: ResolverConfigOption;
7
+ typeDefs?: string;
8
+ types?: () => any[];
9
+ plugins?: () => any[];
10
+ args?: Record<string, string | any>;
11
+ outputType?: string | any;
12
+ };
13
+ export interface FieldExtensionBuilder {
14
+ fieldName(name: string): FieldExtensionBuilder;
15
+ resolver(fn: ResolverFunction): FieldExtensionBuilder;
16
+ resolverConfig(config: ResolverConfigOption): FieldExtensionBuilder;
17
+ typeDefs(sdl: string): FieldExtensionBuilder;
18
+ types(typesFn: () => any[]): FieldExtensionBuilder;
19
+ plugins(pluginsFn: () => any[]): FieldExtensionBuilder;
20
+ args(a: Record<string, string | any>): FieldExtensionBuilder;
21
+ outputType(type: string | any): FieldExtensionBuilder;
22
+ build(): GraphQLExtension;
23
+ }
24
+ /**
25
+ * Creates a fluent builder to extend a root field in the GraphQL schema.
26
+ * The field is automatically registered using Nexus. The output type must be defined
27
+ * using the outputType callback.
28
+ *
29
+ * @param rootType - Either 'Query' or 'Mutation'
30
+ */
31
+ export declare const createGraphQLFieldBuilder: (rootType: string) => FieldExtensionBuilder;
@@ -0,0 +1,113 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createGraphQLFieldBuilder = void 0;
4
+ const nexus_1 = require("nexus");
5
+ const graphql_extension_1 = require("./graphql-extension");
6
+ /**
7
+ * Creates a fluent builder to extend a root field in the GraphQL schema.
8
+ * The field is automatically registered using Nexus. The output type must be defined
9
+ * using the outputType callback.
10
+ *
11
+ * @param rootType - Either 'Query' or 'Mutation'
12
+ */
13
+ const createGraphQLFieldBuilder = (rootType) => {
14
+ const options = {
15
+ rootType,
16
+ fieldName: undefined,
17
+ resolver: () => {
18
+ throw new Error('Resolver function must be provided via .resolver()');
19
+ },
20
+ resolverConfig: {},
21
+ typeDefs: '',
22
+ types: () => [],
23
+ plugins: () => [],
24
+ args: {},
25
+ outputType: undefined
26
+ };
27
+ return {
28
+ fieldName(name) {
29
+ options.fieldName = name;
30
+ return this;
31
+ },
32
+ resolver(fn) {
33
+ options.resolver = fn;
34
+ return this;
35
+ },
36
+ resolverConfig(config) {
37
+ options.resolverConfig = config;
38
+ return this;
39
+ },
40
+ typeDefs(sdl) {
41
+ options.typeDefs = sdl;
42
+ return this;
43
+ },
44
+ types(typesFn) {
45
+ options.types = typesFn;
46
+ return this;
47
+ },
48
+ plugins(pluginsFn) {
49
+ options.plugins = pluginsFn;
50
+ return this;
51
+ },
52
+ args(a) {
53
+ options.args = a;
54
+ return this;
55
+ },
56
+ outputType(type) {
57
+ options.outputType = type;
58
+ return this;
59
+ },
60
+ build() {
61
+ if (!options.fieldName) {
62
+ throw new Error('Field name must be provided via fieldName()');
63
+ }
64
+ if (!options.outputType) {
65
+ throw new Error(`Output type must be provided for field "${options.fieldName}" via outputType()`);
66
+ }
67
+ const nexusExtension = (0, nexus_1.extendType)({
68
+ type: options.rootType,
69
+ definition(t) {
70
+ // Build Nexus arguments if provided
71
+ let nexusArgs = {};
72
+ if (options.args) {
73
+ for (const [argName, argType] of Object.entries(options.args)) {
74
+ if (typeof argType !== 'string') {
75
+ nexusArgs[argName] = argType;
76
+ continue;
77
+ }
78
+ const isNonNull = argType.endsWith('!');
79
+ const baseType = isNonNull ? argType.slice(0, -1) : argType;
80
+ nexusArgs[argName] = isNonNull
81
+ ? (0, nexus_1.nonNull)((0, nexus_1.arg)({ type: baseType }))
82
+ : (0, nexus_1.arg)({ type: baseType });
83
+ }
84
+ }
85
+ t.field(options.fieldName, {
86
+ type: options.outputType,
87
+ args: nexusArgs,
88
+ resolve: options.resolver
89
+ });
90
+ }
91
+ });
92
+ // Merge the auto-generated Nexus extension with any additional Nexus types
93
+ const autoTypes = [nexusExtension, ...(options.types ? options.types() : [])];
94
+ return (0, graphql_extension_1.createGraphQLExtension)((strapi) => ({
95
+ // Provided typeDefs are optional; Nexus types take precedence.
96
+ typeDefs: () => options.typeDefs || '',
97
+ types: () => autoTypes,
98
+ plugins: () => (options.plugins ? options.plugins() : []),
99
+ resolvers: () => ({
100
+ [options.rootType]: {
101
+ [options.fieldName]: options.resolver
102
+ }
103
+ }),
104
+ resolversConfig: () => ({
105
+ [options.rootType]: {
106
+ [options.fieldName]: options.resolverConfig || {}
107
+ }
108
+ })
109
+ }));
110
+ }
111
+ };
112
+ };
113
+ exports.createGraphQLFieldBuilder = createGraphQLFieldBuilder;
@@ -0,0 +1,25 @@
1
+ import type { GraphQLExtension, ResolverConfigOption, ResolverFunction, Strapi } from '../types';
2
+ type ResolversObject = {
3
+ Query?: Record<string, ResolverFunction>;
4
+ Mutation?: Record<string, ResolverFunction>;
5
+ };
6
+ /**
7
+ * Builder interface for configuring a GraphQLExtension.
8
+ */
9
+ interface GraphQLExtensionBuilder {
10
+ init(fn: () => void): GraphQLExtensionBuilder;
11
+ typeDefs(sdl: string | (() => string)): GraphQLExtensionBuilder;
12
+ types(typesFn: (() => any[]) | any[]): GraphQLExtensionBuilder;
13
+ plugins(pluginsFn: (() => any[]) | any[]): GraphQLExtensionBuilder;
14
+ resolvers(resolversObj: (() => ResolversObject) | ResolversObject): GraphQLExtensionBuilder;
15
+ resolversConfig(config: (() => Record<string, ResolverConfigOption>) | Record<string, ResolverConfigOption>): GraphQLExtensionBuilder;
16
+ build(): GraphQLExtension;
17
+ }
18
+ /**
19
+ * Overloaded createGraphQLExtension:
20
+ * - When called with no arguments, returns a new builder.
21
+ * - When called with a factory function returns a GraphQLExtension.
22
+ */
23
+ export declare function createGraphQLExtension(): GraphQLExtensionBuilder;
24
+ export declare function createGraphQLExtension(extension: ((strapi: Strapi) => GraphQLExtension)): GraphQLExtension;
25
+ export {};
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createGraphQLExtension = void 0;
4
+ /**
5
+ * Internal function that creates a new builder instance.
6
+ */
7
+ function graphQLExtensionBuilder() {
8
+ // Options to store configuration.
9
+ const options = {};
10
+ return {
11
+ init(fn) {
12
+ options.init = fn;
13
+ return this;
14
+ },
15
+ typeDefs(sdl) {
16
+ options.typeDefs = typeof sdl === 'string' ? () => sdl : sdl;
17
+ return this;
18
+ },
19
+ types(typesFn) {
20
+ options.types = typeof typesFn === 'function' ? typesFn : () => typesFn;
21
+ return this;
22
+ },
23
+ plugins(pluginsFn) {
24
+ options.plugins = typeof pluginsFn === 'function' ? pluginsFn : () => pluginsFn;
25
+ return this;
26
+ },
27
+ resolvers(resolversObj) {
28
+ options.resolvers = typeof resolversObj === 'function' ? resolversObj : () => resolversObj;
29
+ return this;
30
+ },
31
+ resolversConfig(configObj) {
32
+ options.resolversConfig = typeof configObj === 'function' ? configObj : () => configObj;
33
+ return this;
34
+ },
35
+ build() {
36
+ // Create the extension using the options collected.
37
+ return {
38
+ init: options.init,
39
+ typeDefs: options.typeDefs,
40
+ types: options.types,
41
+ plugins: options.plugins,
42
+ resolvers: options.resolvers,
43
+ resolversConfig: options.resolversConfig,
44
+ };
45
+ },
46
+ };
47
+ }
48
+ function createGraphQLExtension(extension) {
49
+ if (!extension) {
50
+ // No argument passed: return a new builder.
51
+ return graphQLExtensionBuilder();
52
+ }
53
+ return extension(strapi);
54
+ }
55
+ exports.createGraphQLExtension = createGraphQLExtension;
@@ -1,6 +1,9 @@
1
1
  export * from './types';
2
2
  export * from './single-type';
3
3
  export * from './collection-type';
4
+ export * from './field-builder';
5
+ export * from './graphql-extension';
4
6
  export * from './middleware';
5
7
  export * from './misc';
6
8
  export * from './override';
9
+ export * from './shadow-crud';
@@ -17,6 +17,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./types"), exports);
18
18
  __exportStar(require("./single-type"), exports);
19
19
  __exportStar(require("./collection-type"), exports);
20
+ __exportStar(require("./field-builder"), exports);
21
+ __exportStar(require("./graphql-extension"), exports);
20
22
  __exportStar(require("./middleware"), exports);
21
23
  __exportStar(require("./misc"), exports);
22
24
  __exportStar(require("./override"), exports);
25
+ __exportStar(require("./shadow-crud"), exports);
@@ -0,0 +1,30 @@
1
+ type Action = 'create' | 'update' | 'delete' | 'findOne' | 'find';
2
+ interface FieldOperations<T> {
3
+ disable(): this;
4
+ disableInput(): this;
5
+ disableOutput(): this;
6
+ disableFilters(): this;
7
+ isEnabled(): boolean;
8
+ isDisabled(): boolean;
9
+ hasInputEnabled(): boolean;
10
+ hasOutputEnabled(): boolean;
11
+ hasFiltersEnabled(): boolean;
12
+ }
13
+ interface ShadowCRUD<T> {
14
+ disable(): this;
15
+ disableActions(actions: Action[]): this;
16
+ disableAction(action: Action): this;
17
+ disableQueries(): this;
18
+ disableMutations(): this;
19
+ field<K extends keyof T>(name: K): FieldOperations<T[K]>;
20
+ isEnabled(): boolean;
21
+ isDisabled(): boolean;
22
+ areQueriesEnabled(): boolean;
23
+ areQueriesDisabled(): boolean;
24
+ areMutationsEnabled(): boolean;
25
+ areMutationsDisabled(): boolean;
26
+ isActionEnabled(action: Action): boolean;
27
+ isActionDisabled(action: Action): boolean;
28
+ }
29
+ export declare const shadowCRUD: <Type extends unknown = null>(contentTypeUID: string) => ShadowCRUD<Type>;
30
+ export {};
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.shadowCRUD = void 0;
4
+ const shadowCRUD = (contentTypeUID) => {
5
+ const extensionService = strapi.plugin('graphql').service('extension');
6
+ return extensionService.shadowCRUD(contentTypeUID);
7
+ };
8
+ exports.shadowCRUD = shadowCRUD;