@pinelab/vendure-plugin-customer-managed-groups 0.0.3

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 ADDED
@@ -0,0 +1,123 @@
1
+ # Vendure Customer Group Extensions
2
+
3
+ This plugin allows customers to manage their own groups, called Customer Managed Groups. Customer Managed Groups can have Group Admins and Group members.
4
+
5
+ - Group admins and members are stored as Vendure's built-in customers, and the groups are the built-in Customer Group entities.
6
+ - Customers can only be in one group, and they are either group participant or group admin. (Customers can still be in multiple)
7
+ - Customers can create groups and add other non-admin customers to their group. Adding others to your group automatically makes you administrator of the group.
8
+ - Group Admins can fetch placed orders for everyone in the group.
9
+ - Group Admins can update profile details of members of their group.
10
+
11
+ ## Getting started
12
+
13
+ Add the plugin to your config:
14
+
15
+ ```ts
16
+ import { CustomerManagedGroupsPlugin } from 'vendure-plugin-customer-managed-group';
17
+ plugins: [CustomerManagedGroupsPlugin];
18
+ ```
19
+
20
+ You can create your own group via the Shop API, if you are logged in as a customer, by inviting another customer by email:
21
+
22
+ ```graphql
23
+ mutation {
24
+ addCustomerToMyCustomerManagedGroup('invitee@gmail.com') {
25
+ id
26
+ createdAt
27
+ updatedAt
28
+ name
29
+ administrators {
30
+ id
31
+ title
32
+ firstName
33
+ lastName
34
+ emailAddress
35
+ }
36
+ participants {
37
+ id
38
+ title
39
+ firstName
40
+ lastName
41
+ emailAddress
42
+ }
43
+ }
44
+ }
45
+ ```
46
+
47
+ You can also remove participants again, by passing in the customer id that should be removed:
48
+
49
+ ```graphql
50
+ mutation {
51
+ removeCustomerToMyCustomerManagedGroup('2') {
52
+ id
53
+ createdAt
54
+ updatedAt
55
+ name
56
+ administrators {
57
+ id
58
+ title
59
+ firstName
60
+ lastName
61
+ emailAddress
62
+ }
63
+ participants {
64
+ id
65
+ title
66
+ firstName
67
+ lastName
68
+ emailAddress
69
+ }
70
+ }
71
+ }
72
+ ```
73
+
74
+ Admins are allowed to fetch orders of all customers in a group. You can do this with the following query:
75
+
76
+ ```graphql
77
+ query {
78
+ ordersForMyCustomerManagedGroup {
79
+ items {
80
+ id
81
+ code
82
+ customer {
83
+ emailAddress
84
+ }
85
+ }
86
+ totalItems
87
+ }
88
+ }
89
+ ```
90
+
91
+ These are all the GraphQL queries and mutations exposed by this plugin:
92
+
93
+ ```graphql
94
+ extend type Mutation {
95
+ """
96
+ Creates a group with the current logged in user as administrator of the group
97
+ """
98
+ addCustomerToMyCustomerManagedGroup(
99
+ input: AddCustomerToMyCustomerManagedGroupInput
100
+ ): CustomerManagedGroup!
101
+ """
102
+ Create an empty group with the current user as Administrator
103
+ """
104
+ createCustomerManagedGroup: CustomerManagedGroup!
105
+
106
+ removeCustomerFromMyCustomerManagedGroup(
107
+ customerId: ID!
108
+ ): CustomerManagedGroup!
109
+ }
110
+
111
+ extend type Query {
112
+ """
113
+ Fetch placed orders for each member of the group
114
+ """
115
+ ordersForMyCustomerManagedGroup: OrderList!
116
+ """
117
+ Fetch the current logged in group member
118
+ """
119
+ activeCustomerManagedGroupMember: CustomerManagedGroupMember
120
+
121
+ myCustomerManagedGroup: CustomerManagedGroup
122
+ }
123
+ ```
@@ -0,0 +1,16 @@
1
+ import { ID, Order, PaginatedList, RequestContext } from '@vendure/core';
2
+ import { CustomerManagedGroupsService } from './customer-managed-groups.service';
3
+ import { AddCustomerToMyCustomerManagedGroupInput, CustomerManagedGroup, CustomerManagedGroupMember, UpdateCustomerManagedGroupMemberInput } from './generated/graphql';
4
+ export declare const shopSchema: import("graphql").DocumentNode;
5
+ export declare class CustomerManagedGroupsResolver {
6
+ private service;
7
+ constructor(service: CustomerManagedGroupsService);
8
+ ordersForMyCustomerManagedGroup(ctx: RequestContext): Promise<PaginatedList<Order>>;
9
+ activeCustomerManagedGroupMember(ctx: RequestContext): Promise<CustomerManagedGroupMember | undefined>;
10
+ myCustomerManagedGroup(ctx: RequestContext): Promise<CustomerManagedGroup | undefined>;
11
+ createCustomerManagedGroup(ctx: RequestContext): Promise<CustomerManagedGroup | undefined>;
12
+ makeCustomerAdminOfCustomerManagedGroup(ctx: RequestContext, groupId: ID, customerId: ID): Promise<CustomerManagedGroup>;
13
+ addCustomerToMyCustomerManagedGroup(ctx: RequestContext, input: AddCustomerToMyCustomerManagedGroupInput): Promise<CustomerManagedGroup>;
14
+ updateCustomerManagedGroupMember(ctx: RequestContext, input: UpdateCustomerManagedGroupMemberInput): Promise<CustomerManagedGroup>;
15
+ removeCustomerFromMyCustomerManagedGroup(ctx: RequestContext, customerId: ID): Promise<CustomerManagedGroup>;
16
+ }
@@ -0,0 +1,256 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.CustomerManagedGroupsResolver = exports.shopSchema = void 0;
16
+ const graphql_1 = require("@nestjs/graphql");
17
+ const core_1 = require("@vendure/core");
18
+ const graphql_tag_1 = require("graphql-tag");
19
+ const customer_managed_groups_service_1 = require("./customer-managed-groups.service");
20
+ // This is just to enable static codegen, without starting a server
21
+ const scalars = (0, graphql_tag_1.gql) `
22
+ scalar DateTime
23
+ scalar OrderList
24
+ scalar LanguageCode
25
+ scalar JSON
26
+ `;
27
+ exports.shopSchema = (0, graphql_tag_1.gql) `
28
+ input AddCustomerToMyCustomerManagedGroupInput {
29
+ emailAddress: String!
30
+ isGroupAdmin: Boolean
31
+ }
32
+
33
+ input UpdateCustomerManagedGroupMemberInput {
34
+ title: String
35
+ firstName: String
36
+ lastName: String
37
+ emailAddress: String
38
+ addresses: [CustomerManagedGroupAddressInput!]
39
+ customerId: ID!
40
+ customFields: JSON
41
+ }
42
+
43
+ """
44
+ When no ID is given, a new address will be created
45
+ """
46
+ input CustomerManagedGroupAddressInput {
47
+ id: ID
48
+ fullName: String
49
+ company: String
50
+ streetLine1: String
51
+ streetLine2: String
52
+ city: String
53
+ province: String
54
+ postalCode: String
55
+ countryCode: String
56
+ phoneNumber: String
57
+ defaultShippingAddress: Boolean
58
+ defaultBillingAddress: Boolean
59
+ }
60
+
61
+ type CustomerManagedGroupMember {
62
+ customerId: ID!
63
+ title: String
64
+ addresses: [CustomerManagedGroupAddress!]
65
+ firstName: String!
66
+ lastName: String!
67
+ emailAddress: String!
68
+ isGroupAdministrator: Boolean!
69
+ customFields: JSON
70
+ }
71
+
72
+ type CustomerManagedGroupAddress {
73
+ id: ID!
74
+ createdAt: DateTime!
75
+ updatedAt: DateTime!
76
+ fullName: String
77
+ company: String
78
+ streetLine1: String!
79
+ streetLine2: String
80
+ city: String
81
+ province: String
82
+ postalCode: String
83
+ country: CustomerManagedGroupCountry!
84
+ phoneNumber: String
85
+ defaultShippingAddress: Boolean
86
+ defaultBillingAddress: Boolean
87
+ }
88
+
89
+ type CustomerManagedGroupCountry {
90
+ id: ID!
91
+ createdAt: DateTime!
92
+ updatedAt: DateTime!
93
+ code: String!
94
+ name: String!
95
+ enabled: Boolean!
96
+ translations: [CustomerManagedGroupCountryTranslation!]!
97
+ }
98
+
99
+ type CustomerManagedGroupCountryTranslation {
100
+ id: ID!
101
+ languageCode: LanguageCode!
102
+ name: String!
103
+ }
104
+
105
+ type CustomerManagedGroup {
106
+ id: ID!
107
+ createdAt: DateTime!
108
+ updatedAt: DateTime!
109
+ name: String!
110
+ customers: [CustomerManagedGroupMember!]!
111
+ }
112
+
113
+ extend type Mutation {
114
+ """
115
+ Creates a group with the current logged in user as administrator of the group
116
+ """
117
+ addCustomerToMyCustomerManagedGroup(
118
+ input: AddCustomerToMyCustomerManagedGroupInput
119
+ ): CustomerManagedGroup!
120
+ """
121
+ Create an empty group with the current user as Administrator
122
+ """
123
+ createCustomerManagedGroup: CustomerManagedGroup!
124
+
125
+ removeCustomerFromMyCustomerManagedGroup(
126
+ customerId: ID!
127
+ ): CustomerManagedGroup!
128
+
129
+ """
130
+ Update a member of one's group
131
+ """
132
+ updateCustomerManagedGroupMember(
133
+ input: UpdateCustomerManagedGroupMemberInput!
134
+ ): CustomerManagedGroup!
135
+ makeCustomerAdminOfCustomerManagedGroup(
136
+ groupId: ID!
137
+ customerId: ID!
138
+ ): CustomerManagedGroup!
139
+ }
140
+
141
+ extend type Query {
142
+ """
143
+ Fetch placed orders for each member of the group
144
+ """
145
+ ordersForMyCustomerManagedGroup: OrderList!
146
+ """
147
+ Fetch the current logged in group member
148
+ """
149
+ activeCustomerManagedGroupMember: CustomerManagedGroupMember
150
+
151
+ myCustomerManagedGroup: CustomerManagedGroup
152
+ }
153
+ `;
154
+ let CustomerManagedGroupsResolver = class CustomerManagedGroupsResolver {
155
+ constructor(service) {
156
+ this.service = service;
157
+ }
158
+ async ordersForMyCustomerManagedGroup(ctx) {
159
+ return this.service.getOrdersForCustomer(ctx);
160
+ }
161
+ async activeCustomerManagedGroupMember(ctx) {
162
+ return this.service.getActiveMember(ctx);
163
+ }
164
+ async myCustomerManagedGroup(ctx) {
165
+ return this.service.myCustomerManagedGroup(ctx);
166
+ }
167
+ async createCustomerManagedGroup(ctx) {
168
+ return this.service.createCustomerManagedGroup(ctx);
169
+ }
170
+ async makeCustomerAdminOfCustomerManagedGroup(ctx, groupId, customerId) {
171
+ return this.service.makeAdminOfGroup(ctx, groupId, customerId);
172
+ }
173
+ async addCustomerToMyCustomerManagedGroup(ctx, input) {
174
+ return this.service.addToGroup(ctx, input);
175
+ }
176
+ async updateCustomerManagedGroupMember(ctx, input) {
177
+ return this.service.updateGroupMember(ctx, input);
178
+ }
179
+ async removeCustomerFromMyCustomerManagedGroup(ctx, customerId) {
180
+ return this.service.removeFromGroup(ctx, customerId);
181
+ }
182
+ };
183
+ __decorate([
184
+ (0, graphql_1.Query)(),
185
+ (0, core_1.Allow)(core_1.Permission.Authenticated),
186
+ __param(0, (0, core_1.Ctx)()),
187
+ __metadata("design:type", Function),
188
+ __metadata("design:paramtypes", [core_1.RequestContext]),
189
+ __metadata("design:returntype", Promise)
190
+ ], CustomerManagedGroupsResolver.prototype, "ordersForMyCustomerManagedGroup", null);
191
+ __decorate([
192
+ (0, graphql_1.Query)(),
193
+ (0, core_1.Allow)(core_1.Permission.Authenticated),
194
+ __param(0, (0, core_1.Ctx)()),
195
+ __metadata("design:type", Function),
196
+ __metadata("design:paramtypes", [core_1.RequestContext]),
197
+ __metadata("design:returntype", Promise)
198
+ ], CustomerManagedGroupsResolver.prototype, "activeCustomerManagedGroupMember", null);
199
+ __decorate([
200
+ (0, graphql_1.Query)(),
201
+ (0, core_1.Allow)(core_1.Permission.Authenticated),
202
+ __param(0, (0, core_1.Ctx)()),
203
+ __metadata("design:type", Function),
204
+ __metadata("design:paramtypes", [core_1.RequestContext]),
205
+ __metadata("design:returntype", Promise)
206
+ ], CustomerManagedGroupsResolver.prototype, "myCustomerManagedGroup", null);
207
+ __decorate([
208
+ (0, graphql_1.Mutation)(),
209
+ (0, core_1.Allow)(core_1.Permission.Authenticated),
210
+ __param(0, (0, core_1.Ctx)()),
211
+ __metadata("design:type", Function),
212
+ __metadata("design:paramtypes", [core_1.RequestContext]),
213
+ __metadata("design:returntype", Promise)
214
+ ], CustomerManagedGroupsResolver.prototype, "createCustomerManagedGroup", null);
215
+ __decorate([
216
+ (0, graphql_1.Mutation)(),
217
+ (0, core_1.Allow)(core_1.Permission.Authenticated),
218
+ __param(0, (0, core_1.Ctx)()),
219
+ __param(1, (0, graphql_1.Args)('groupId')),
220
+ __param(2, (0, graphql_1.Args)('customerId')),
221
+ __metadata("design:type", Function),
222
+ __metadata("design:paramtypes", [core_1.RequestContext, Object, Object]),
223
+ __metadata("design:returntype", Promise)
224
+ ], CustomerManagedGroupsResolver.prototype, "makeCustomerAdminOfCustomerManagedGroup", null);
225
+ __decorate([
226
+ (0, graphql_1.Mutation)(),
227
+ (0, core_1.Allow)(core_1.Permission.Authenticated),
228
+ __param(0, (0, core_1.Ctx)()),
229
+ __param(1, (0, graphql_1.Args)('input')),
230
+ __metadata("design:type", Function),
231
+ __metadata("design:paramtypes", [core_1.RequestContext, Object]),
232
+ __metadata("design:returntype", Promise)
233
+ ], CustomerManagedGroupsResolver.prototype, "addCustomerToMyCustomerManagedGroup", null);
234
+ __decorate([
235
+ (0, graphql_1.Mutation)(),
236
+ (0, core_1.Allow)(core_1.Permission.Authenticated),
237
+ __param(0, (0, core_1.Ctx)()),
238
+ __param(1, (0, graphql_1.Args)('input')),
239
+ __metadata("design:type", Function),
240
+ __metadata("design:paramtypes", [core_1.RequestContext, Object]),
241
+ __metadata("design:returntype", Promise)
242
+ ], CustomerManagedGroupsResolver.prototype, "updateCustomerManagedGroupMember", null);
243
+ __decorate([
244
+ (0, graphql_1.Mutation)(),
245
+ (0, core_1.Allow)(core_1.Permission.Authenticated),
246
+ __param(0, (0, core_1.Ctx)()),
247
+ __param(1, (0, graphql_1.Args)('customerId')),
248
+ __metadata("design:type", Function),
249
+ __metadata("design:paramtypes", [core_1.RequestContext, Object]),
250
+ __metadata("design:returntype", Promise)
251
+ ], CustomerManagedGroupsResolver.prototype, "removeCustomerFromMyCustomerManagedGroup", null);
252
+ CustomerManagedGroupsResolver = __decorate([
253
+ (0, graphql_1.Resolver)(),
254
+ __metadata("design:paramtypes", [customer_managed_groups_service_1.CustomerManagedGroupsService])
255
+ ], CustomerManagedGroupsResolver);
256
+ exports.CustomerManagedGroupsResolver = CustomerManagedGroupsResolver;
@@ -0,0 +1,2 @@
1
+ export declare const loggerCtx = "CustomerManagedGroupsPlugin";
2
+ export declare const PLUGIN_INIT_OPTIONS: unique symbol;
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PLUGIN_INIT_OPTIONS = exports.loggerCtx = void 0;
4
+ exports.loggerCtx = 'CustomerManagedGroupsPlugin';
5
+ exports.PLUGIN_INIT_OPTIONS = Symbol('PLUGIN_INIT_OPTIONS');
@@ -0,0 +1,11 @@
1
+ import { CustomerGroup, Customer, CustomFields } from '@vendure/core';
2
+ export interface CustomerGroupWithCustomFields extends CustomerGroup {
3
+ customFields: {
4
+ isCustomerManaged?: boolean;
5
+ groupAdmins?: Customer[];
6
+ };
7
+ }
8
+ export interface CustomerWithCustomFields extends Customer {
9
+ groups: CustomerGroupWithCustomFields[];
10
+ }
11
+ export declare const customFields: CustomFields;
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.customFields = void 0;
4
+ const core_1 = require("@vendure/core");
5
+ exports.customFields = {
6
+ CustomerGroup: [
7
+ {
8
+ name: 'groupAdmins',
9
+ list: true,
10
+ type: 'relation',
11
+ entity: core_1.Customer,
12
+ graphQLType: 'Customer',
13
+ public: true,
14
+ nullable: true,
15
+ eager: true,
16
+ readonly: false,
17
+ label: [
18
+ {
19
+ languageCode: core_1.LanguageCode.en,
20
+ value: 'Administrators of this group',
21
+ },
22
+ ],
23
+ // ui: { component: 'customer-group-admin-selector' },
24
+ },
25
+ {
26
+ name: 'isCustomerManaged',
27
+ type: 'boolean',
28
+ public: false,
29
+ nullable: true,
30
+ readonly: true,
31
+ label: [
32
+ {
33
+ languageCode: core_1.LanguageCode.en,
34
+ value: 'Is customer managed',
35
+ },
36
+ ],
37
+ },
38
+ ],
39
+ };
@@ -0,0 +1,7 @@
1
+ import { AdminUiExtension } from '@vendure/ui-devkit/compiler';
2
+ export interface ExampleOptions {
3
+ enabled: boolean;
4
+ }
5
+ export declare class CustomerManagedGroupsPlugin {
6
+ static ui: AdminUiExtension;
7
+ }
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __importDefault = (this && this.__importDefault) || function (mod) {
9
+ return (mod && mod.__esModule) ? mod : { "default": mod };
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.CustomerManagedGroupsPlugin = void 0;
13
+ const core_1 = require("@vendure/core");
14
+ const path_1 = __importDefault(require("path"));
15
+ const api_extensions_1 = require("./api-extensions");
16
+ const custom_fields_1 = require("./custom-fields");
17
+ const customer_managed_groups_service_1 = require("./customer-managed-groups.service");
18
+ let CustomerManagedGroupsPlugin = class CustomerManagedGroupsPlugin {
19
+ };
20
+ CustomerManagedGroupsPlugin.ui = {
21
+ extensionPath: path_1.default.join(__dirname, 'ui'),
22
+ ngModules: [
23
+ {
24
+ type: 'shared',
25
+ ngModuleFileName: 'customer-group-extension.shared-module.ts',
26
+ ngModuleName: 'CustomerGroupExtensionSharedModule',
27
+ },
28
+ ],
29
+ };
30
+ CustomerManagedGroupsPlugin = __decorate([
31
+ (0, core_1.VendurePlugin)({
32
+ imports: [core_1.PluginCommonModule],
33
+ providers: [customer_managed_groups_service_1.CustomerManagedGroupsService],
34
+ shopApiExtensions: {
35
+ resolvers: [api_extensions_1.CustomerManagedGroupsResolver],
36
+ schema: api_extensions_1.shopSchema,
37
+ },
38
+ configuration: (config) => {
39
+ config.customFields = {
40
+ ...config.customFields,
41
+ ...custom_fields_1.customFields,
42
+ };
43
+ return config;
44
+ },
45
+ compatibility: '^2.0.0',
46
+ })
47
+ ], CustomerManagedGroupsPlugin);
48
+ exports.CustomerManagedGroupsPlugin = CustomerManagedGroupsPlugin;
@@ -0,0 +1,41 @@
1
+ import { Customer, CustomerGroupService, CustomerService, EntityHydrator, ID, Order, OrderService, PaginatedList, RequestContext, TransactionalConnection } from '@vendure/core';
2
+ import { CustomerGroupWithCustomFields, CustomerWithCustomFields } from './custom-fields';
3
+ import { AddCustomerToMyCustomerManagedGroupInput, CustomerManagedGroup, CustomerManagedGroupMember, UpdateCustomerManagedGroupMemberInput } from './generated/graphql';
4
+ export declare class CustomerManagedGroupsService {
5
+ private orderService;
6
+ private customerService;
7
+ private customerGroupService;
8
+ private hydrator;
9
+ private transactionalConnection;
10
+ constructor(orderService: OrderService, customerService: CustomerService, customerGroupService: CustomerGroupService, hydrator: EntityHydrator, transactionalConnection: TransactionalConnection);
11
+ getOrdersForCustomer(ctx: RequestContext): Promise<PaginatedList<Order>>;
12
+ addToGroup(ctx: RequestContext, { emailAddress: inviteeEmailAddress, isGroupAdmin: inviteeIsAdmin, }: AddCustomerToMyCustomerManagedGroupInput): Promise<CustomerManagedGroup>;
13
+ removeFromGroup(ctx: RequestContext, customerIdToRemove: ID): Promise<CustomerManagedGroup>;
14
+ getOrThrowCustomerByUserId(ctx: RequestContext, userId: ID): Promise<CustomerWithCustomFields>;
15
+ getOrThrowCustomerByEmail(ctx: RequestContext, emailAddress: string): Promise<Customer>;
16
+ /**
17
+ * Get userId from RequestContext or throw a ForbiddenError if not logged in
18
+ */
19
+ getOrThrowUserId(ctx: RequestContext): ID;
20
+ throwIfNotAdministratorOfGroup(userId: ID, group: CustomerGroupWithCustomFields): void;
21
+ isAdministratorOfGroup(userId: ID, group: CustomerGroupWithCustomFields): boolean;
22
+ getCustomerManagedGroup(customer: CustomerWithCustomFields): CustomerGroupWithCustomFields | undefined;
23
+ /**
24
+ * Get current logged in member, or undefined if not in a group
25
+ */
26
+ getActiveMember(ctx: RequestContext): Promise<CustomerManagedGroupMember | undefined>;
27
+ myCustomerManagedGroup(ctx: RequestContext): Promise<CustomerManagedGroup | undefined>;
28
+ myCustomerManagedGroupWithCustomFields(ctx: RequestContext): Promise<CustomerGroupWithCustomFields | undefined>;
29
+ createCustomerManagedGroup(ctx: RequestContext): Promise<CustomerManagedGroup>;
30
+ /**
31
+ *
32
+ * @param ctx Internal function to create a customer managed group based
33
+ * @param groupAdmin
34
+ * @param additionalMembers add addtional members to the group. Group admin is already added as member
35
+ */
36
+ private createGroup;
37
+ mapToCustomerManagedGroup(group: CustomerGroupWithCustomFields): CustomerManagedGroup;
38
+ mapToCustomerManagedGroupMember(customer: Customer, isGroupAdministrator: boolean): CustomerManagedGroupMember;
39
+ updateGroupMember(ctx: RequestContext, input: UpdateCustomerManagedGroupMemberInput): Promise<CustomerManagedGroup>;
40
+ makeAdminOfGroup(ctx: RequestContext, groupId: ID, customerId: ID): Promise<CustomerManagedGroup>;
41
+ }
@@ -0,0 +1,380 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.CustomerManagedGroupsService = void 0;
13
+ const common_1 = require("@nestjs/common");
14
+ const core_1 = require("@vendure/core");
15
+ const constants_1 = require("./constants");
16
+ let CustomerManagedGroupsService = class CustomerManagedGroupsService {
17
+ constructor(orderService, customerService, customerGroupService, hydrator, transactionalConnection) {
18
+ this.orderService = orderService;
19
+ this.customerService = customerService;
20
+ this.customerGroupService = customerGroupService;
21
+ this.hydrator = hydrator;
22
+ this.transactionalConnection = transactionalConnection;
23
+ }
24
+ async getOrdersForCustomer(ctx) {
25
+ const userId = this.getOrThrowUserId(ctx);
26
+ const customer = await this.getOrThrowCustomerByUserId(ctx, userId);
27
+ const customerManagedGroup = this.getCustomerManagedGroup(customer);
28
+ if (!customerManagedGroup) {
29
+ throw new core_1.UserInputError(`You are not in a customer managed group`);
30
+ }
31
+ const isAdmin = this.isAdministratorOfGroup(userId, customerManagedGroup);
32
+ const orders = [];
33
+ // If not admin, only fetch orders for the current user
34
+ const customers = isAdmin ? customerManagedGroup.customers : [customer];
35
+ for (const customer of customers) {
36
+ const ordersForCustomer = await this.orderService.findByCustomerId(ctx, customer.id);
37
+ core_1.Logger.info(`Found ${ordersForCustomer.items.length} orders for customer ${customer.emailAddress}`, constants_1.loggerCtx);
38
+ orders.push(...ordersForCustomer.items);
39
+ if (ordersForCustomer.totalItems > ordersForCustomer.items.length) {
40
+ throw Error(`Too many orders for customer ${customer.emailAddress}, pagination is not implemented yet.`);
41
+ }
42
+ }
43
+ return {
44
+ items: orders,
45
+ totalItems: orders.length,
46
+ };
47
+ }
48
+ async addToGroup(ctx, { emailAddress: inviteeEmailAddress, isGroupAdmin: inviteeIsAdmin, }) {
49
+ const userId = this.getOrThrowUserId(ctx);
50
+ let [currentCustomer, invitee] = await Promise.all([
51
+ this.getOrThrowCustomerByUserId(ctx, userId),
52
+ this.getOrThrowCustomerByEmail(ctx, inviteeEmailAddress),
53
+ ]);
54
+ let customerManagedGroup = this.getCustomerManagedGroup(currentCustomer);
55
+ if (customerManagedGroup) {
56
+ this.throwIfNotAdministratorOfGroup(userId, customerManagedGroup);
57
+ }
58
+ if (!customerManagedGroup) {
59
+ customerManagedGroup = await this.createGroup(ctx, currentCustomer, [
60
+ invitee.id,
61
+ ]);
62
+ }
63
+ const existingAdminIds = (customerManagedGroup.customFields.groupAdmins || []).map((admin) => admin.id);
64
+ // Add current customer as admin
65
+ const adminIds = [currentCustomer.id, ...existingAdminIds];
66
+ core_1.Logger.info(`Adding ${currentCustomer.emailAddress} as administrator of group`, constants_1.loggerCtx);
67
+ if (inviteeIsAdmin) {
68
+ // Add invitee as admin
69
+ adminIds.push(invitee.id);
70
+ core_1.Logger.info(`Adding ${invitee.emailAddress} as administrator of group`, constants_1.loggerCtx);
71
+ }
72
+ // Set group admins
73
+ customerManagedGroup = await this.customerGroupService.update(ctx, {
74
+ id: customerManagedGroup.id,
75
+ customFields: {
76
+ groupAdmins: adminIds.map((id) => ({ id })),
77
+ },
78
+ });
79
+ await this.hydrator.hydrate(ctx, customerManagedGroup, {
80
+ relations: ['customers'],
81
+ });
82
+ const existingCustomersIds = customerManagedGroup.customers.map((customer) => customer.id);
83
+ if (!existingCustomersIds.includes(invitee.id)) {
84
+ // Add invitee to group
85
+ customerManagedGroup =
86
+ await this.customerGroupService.addCustomersToGroup(ctx, {
87
+ customerGroupId: customerManagedGroup.id,
88
+ customerIds: [invitee.id, ...existingCustomersIds],
89
+ });
90
+ core_1.Logger.info(`Added ${invitee.emailAddress} as participants of group`, constants_1.loggerCtx);
91
+ }
92
+ // Refetch customer and group
93
+ currentCustomer = await this.getOrThrowCustomerByUserId(ctx, userId);
94
+ customerManagedGroup = this.getCustomerManagedGroup(currentCustomer);
95
+ return this.mapToCustomerManagedGroup(customerManagedGroup);
96
+ }
97
+ async removeFromGroup(ctx, customerIdToRemove) {
98
+ const userId = this.getOrThrowUserId(ctx);
99
+ let customer = await this.getOrThrowCustomerByUserId(ctx, userId);
100
+ let customerManagedGroup = this.getCustomerManagedGroup(customer);
101
+ if (!customerManagedGroup) {
102
+ throw new core_1.UserInputError(`You are not in a customer managed group`);
103
+ }
104
+ this.throwIfNotAdministratorOfGroup(userId, customerManagedGroup);
105
+ const customerToRemove = customerManagedGroup.customers.find((c) => c.id == customerIdToRemove);
106
+ if (!customerToRemove) {
107
+ throw new core_1.UserInputError(`Customer '${customerIdToRemove}' is not in your group`);
108
+ }
109
+ if (customer.id === customerIdToRemove) {
110
+ throw new core_1.UserInputError(`You cannot remove yourself from your group`);
111
+ }
112
+ customerManagedGroup =
113
+ await this.customerGroupService.removeCustomersFromGroup(ctx, {
114
+ customerGroupId: customerManagedGroup.id,
115
+ customerIds: [customerIdToRemove],
116
+ });
117
+ core_1.Logger.info(`Removed customer ${customerToRemove.emailAddress} from group`, constants_1.loggerCtx);
118
+ const existingAdminIds = customerManagedGroup.customFields.groupAdmins?.map((a) => a.id) || [];
119
+ if (existingAdminIds.includes(customerToRemove.id)) {
120
+ const newAdminIds = existingAdminIds.filter((id) => id != customerToRemove.id);
121
+ customerManagedGroup = await this.customerGroupService.update(ctx, {
122
+ id: customerManagedGroup.id,
123
+ customFields: {
124
+ groupAdmins: newAdminIds.map((id) => ({ id })),
125
+ },
126
+ });
127
+ core_1.Logger.info(`Removed ${customerToRemove.emailAddress} as group administrator`, constants_1.loggerCtx);
128
+ }
129
+ // Refetch customer and group
130
+ customer = await this.getOrThrowCustomerByUserId(ctx, userId);
131
+ customerManagedGroup = this.getCustomerManagedGroup(customer);
132
+ return this.mapToCustomerManagedGroup(customerManagedGroup);
133
+ }
134
+ async getOrThrowCustomerByUserId(ctx, userId) {
135
+ const customerRepo = this.transactionalConnection.getRepository(ctx, core_1.Customer);
136
+ const customerWithGroupsData = await customerRepo
137
+ .createQueryBuilder('customer')
138
+ .leftJoin('customer.channels', 'customer_channel')
139
+ .leftJoin('customer.user', 'user')
140
+ .leftJoinAndSelect('customer.addresses', 'customerAddress')
141
+ .leftJoinAndSelect('customerAddress.country', 'customerCountry')
142
+ .leftJoinAndSelect('customer.groups', 'groups')
143
+ .leftJoinAndSelect('groups.customers', 'customers')
144
+ .leftJoinAndSelect('groups.customFields.groupAdmins', 'groupAdmins')
145
+ .leftJoinAndSelect('groupAdmins.user', 'groupAdminsUser')
146
+ .leftJoinAndSelect('groupAdmins.addresses', 'groupAdminAddresses')
147
+ .leftJoinAndSelect('groupAdminAddresses.country', 'groupAdminCountries')
148
+ .leftJoinAndSelect('customers.addresses', 'addresses')
149
+ .leftJoinAndSelect('addresses.country', 'country')
150
+ .where('user.id = :userId', { userId: userId })
151
+ .andWhere('customer_channel.id = :customerChannelId', {
152
+ customerChannelId: ctx.channelId,
153
+ })
154
+ .getOne();
155
+ if (!customerWithGroupsData) {
156
+ throw new core_1.UserInputError(`No customer found for user with id ${userId}`);
157
+ }
158
+ return customerWithGroupsData;
159
+ }
160
+ async getOrThrowCustomerByEmail(ctx, emailAddress) {
161
+ const customers = await this.customerService.findAll(ctx, {
162
+ filter: {
163
+ emailAddress: {
164
+ eq: emailAddress,
165
+ },
166
+ },
167
+ });
168
+ if (!customers.items[0]) {
169
+ throw new core_1.UserInputError(`No customer found for email adress ${emailAddress}`);
170
+ }
171
+ return customers.items[0];
172
+ }
173
+ /**
174
+ * Get userId from RequestContext or throw a ForbiddenError if not logged in
175
+ */
176
+ getOrThrowUserId(ctx) {
177
+ if (!ctx.activeUserId) {
178
+ throw new core_1.ForbiddenError();
179
+ }
180
+ return ctx.activeUserId;
181
+ }
182
+ throwIfNotAdministratorOfGroup(userId, group) {
183
+ if (!this.isAdministratorOfGroup(userId, group)) {
184
+ throw new core_1.UserInputError('You are not administrator of your group');
185
+ }
186
+ }
187
+ isAdministratorOfGroup(userId, group) {
188
+ return !!group.customFields.groupAdmins?.find((admin) => admin.user.id == userId);
189
+ }
190
+ getCustomerManagedGroup(customer) {
191
+ if (!customer.groups) {
192
+ throw Error(`Make sure to include groups in the customer query. Can not find customer managed group for customer ${customer.emailAddress}`);
193
+ }
194
+ return customer.groups.find((group) => group.customFields.isCustomerManaged);
195
+ }
196
+ /**
197
+ * Get current logged in member, or undefined if not in a group
198
+ */
199
+ async getActiveMember(ctx) {
200
+ const userId = this.getOrThrowUserId(ctx);
201
+ const customer = await this.getOrThrowCustomerByUserId(ctx, userId);
202
+ const customerManagedGroup = this.getCustomerManagedGroup(customer);
203
+ if (!customerManagedGroup) {
204
+ return;
205
+ }
206
+ const isAdministrator = this.isAdministratorOfGroup(userId, customerManagedGroup);
207
+ return this.mapToCustomerManagedGroupMember(customer, isAdministrator);
208
+ }
209
+ async myCustomerManagedGroup(ctx) {
210
+ let customerManagedGroup = await this.myCustomerManagedGroupWithCustomFields(ctx);
211
+ if (!customerManagedGroup) {
212
+ return undefined;
213
+ }
214
+ return this.mapToCustomerManagedGroup(customerManagedGroup);
215
+ }
216
+ async myCustomerManagedGroupWithCustomFields(ctx) {
217
+ const userId = this.getOrThrowUserId(ctx);
218
+ const customer = await this.getOrThrowCustomerByUserId(ctx, userId);
219
+ let customerManagedGroup = this.getCustomerManagedGroup(customer);
220
+ if (!customerManagedGroup) {
221
+ return undefined;
222
+ }
223
+ return customerManagedGroup;
224
+ }
225
+ async createCustomerManagedGroup(ctx) {
226
+ const userId = this.getOrThrowUserId(ctx);
227
+ const currentCustomer = await this.getOrThrowCustomerByUserId(ctx, userId);
228
+ let customerManagedGroup = this.getCustomerManagedGroup(currentCustomer);
229
+ if (customerManagedGroup) {
230
+ throw new core_1.UserInputError(`You are already in a customer managed group`);
231
+ }
232
+ customerManagedGroup = await this.createGroup(ctx, currentCustomer);
233
+ await this.hydrator.hydrate(ctx, customerManagedGroup, {
234
+ relations: ['customers'],
235
+ });
236
+ return this.mapToCustomerManagedGroup(customerManagedGroup);
237
+ }
238
+ /**
239
+ *
240
+ * @param ctx Internal function to create a customer managed group based
241
+ * @param groupAdmin
242
+ * @param additionalMembers add addtional members to the group. Group admin is already added as member
243
+ */
244
+ createGroup(ctx, groupAdmin, additionalMembers) {
245
+ const members = [groupAdmin.id];
246
+ if (additionalMembers) {
247
+ members.push(...additionalMembers);
248
+ }
249
+ return this.customerGroupService.create(ctx, {
250
+ name: `${groupAdmin.lastName}'s Group`,
251
+ customerIds: members,
252
+ customFields: {
253
+ isCustomerManaged: true,
254
+ groupAdmins: [groupAdmin],
255
+ },
256
+ });
257
+ }
258
+ mapToCustomerManagedGroup(group) {
259
+ const adminIds = group.customFields.groupAdmins?.map((admin) => admin.id) || [];
260
+ // Filter out group administrators
261
+ const participants = group.customers
262
+ .filter((customer) => !adminIds.includes(customer.id))
263
+ .map((c) => this.mapToCustomerManagedGroupMember(c, false));
264
+ const administrators = (group.customFields.groupAdmins || []).map((a) => this.mapToCustomerManagedGroupMember(a, true));
265
+ return {
266
+ ...group,
267
+ customers: [...administrators, ...participants],
268
+ };
269
+ }
270
+ mapToCustomerManagedGroupMember(customer, isGroupAdministrator) {
271
+ return {
272
+ ...customer,
273
+ addresses: customer.addresses,
274
+ customFields: customer.customFields,
275
+ customerId: customer.id,
276
+ isGroupAdministrator,
277
+ };
278
+ }
279
+ async updateGroupMember(ctx, input) {
280
+ if (!input.title &&
281
+ !input.firstName &&
282
+ !input.lastName &&
283
+ !input.emailAddress &&
284
+ !input.addresses?.length &&
285
+ !input.customFields) {
286
+ throw new core_1.UserInputError(`Make sure to include fields to be updated`);
287
+ }
288
+ if (!ctx.activeUserId) {
289
+ throw new core_1.ForbiddenError();
290
+ }
291
+ const myGroup = await this.myCustomerManagedGroupWithCustomFields(ctx);
292
+ if (!myGroup) {
293
+ throw new core_1.UserInputError(`No customer managed group exists for the authenticated customer`);
294
+ }
295
+ const member = myGroup.customers.find((customer) => customer.id === input.customerId);
296
+ if (!member) {
297
+ throw new core_1.UserInputError(`No customer with id ${input.customerId} exists in '${myGroup.name}' customer managed group`);
298
+ }
299
+ const customer = await this.customerService.findOne(ctx, member.id, [
300
+ 'user',
301
+ ]);
302
+ if (!customer || !customer.user) {
303
+ throw new core_1.UserInputError(`No customer with id ${input.customerId} exists`);
304
+ }
305
+ if (!this.isAdministratorOfGroup(ctx.activeUserId, myGroup) &&
306
+ customer.user.id !== ctx.activeUserId) {
307
+ throw new core_1.UserInputError(`You are not allowed to update other member's details`);
308
+ }
309
+ const userRepo = this.transactionalConnection.getRepository(ctx, core_1.User);
310
+ if (input.emailAddress &&
311
+ (await userRepo.count({
312
+ where: { identifier: input.emailAddress },
313
+ }))) {
314
+ throw new core_1.UserInputError('User with this email already exists');
315
+ }
316
+ const updateCustomerData = {
317
+ id: customer.id,
318
+ ...(input.title ? { title: input.title } : []),
319
+ ...(input.firstName ? { firstName: input.firstName } : []),
320
+ ...(input.lastName ? { lastName: input.lastName } : []),
321
+ ...(input.emailAddress ? { emailAddress: input.emailAddress } : []),
322
+ ...(input.customFields ? { customFields: input.customFields } : []),
323
+ };
324
+ await this.customerService.update(ctx, updateCustomerData);
325
+ if (input.addresses?.length) {
326
+ for (let addressInput of input.addresses) {
327
+ if (addressInput?.id) {
328
+ await this.customerService.updateAddress(ctx, addressInput);
329
+ }
330
+ else {
331
+ await this.customerService.createAddress(ctx, customer.id, addressInput);
332
+ }
333
+ }
334
+ }
335
+ const newGroupData = await this.myCustomerManagedGroup(ctx);
336
+ if (!newGroupData) {
337
+ throw Error(`Group with id ${myGroup.id} not found`); // Should never happen
338
+ }
339
+ return newGroupData;
340
+ }
341
+ async makeAdminOfGroup(ctx, groupId, customerId) {
342
+ const customerGroup = await this.customerGroupService.findOne(ctx, groupId, ['customers', 'customers.user']);
343
+ if (!customerGroup ||
344
+ !customerGroup.customFields ||
345
+ !customerGroup.customFields.isCustomerManaged) {
346
+ throw new core_1.UserInputError(`No customer managed group with id ${groupId} exists`);
347
+ }
348
+ if (!customerGroup.customFields.groupAdmins.find((admin) => admin.user?.id === ctx.activeUserId)) {
349
+ throw new core_1.UserInputError(`You are not admin of this customer managed group`);
350
+ }
351
+ const customerInQuestion = await customerGroup.customers.find((c) => c.id === customerId);
352
+ if (!customerInQuestion) {
353
+ throw new core_1.UserInputError(`Customer with id ${customerId} is not part of this customer managed group`);
354
+ }
355
+ if (customerGroup.customFields.groupAdmins.find((admin) => admin.id === customerId)) {
356
+ throw new core_1.UserInputError('Customer is already admin of this customer managed group');
357
+ }
358
+ const customerGroupRepo = this.transactionalConnection.getRepository(ctx, core_1.CustomerGroup);
359
+ const partialValue = {
360
+ id: customerGroup.id,
361
+ customFields: {
362
+ groupAdmins: [
363
+ ...customerGroup.customFields.groupAdmins,
364
+ customerInQuestion,
365
+ ],
366
+ },
367
+ };
368
+ await customerGroupRepo.save(partialValue);
369
+ return this.mapToCustomerManagedGroup((await this.customerGroupService.findOne(ctx, groupId, ['customers'])));
370
+ }
371
+ };
372
+ CustomerManagedGroupsService = __decorate([
373
+ (0, common_1.Injectable)(),
374
+ __metadata("design:paramtypes", [core_1.OrderService,
375
+ core_1.CustomerService,
376
+ core_1.CustomerGroupService,
377
+ core_1.EntityHydrator,
378
+ core_1.TransactionalConnection])
379
+ ], CustomerManagedGroupsService);
380
+ exports.CustomerManagedGroupsService = CustomerManagedGroupsService;
@@ -0,0 +1,137 @@
1
+ export type Maybe<T> = T | null;
2
+ export type InputMaybe<T> = Maybe<T>;
3
+ export type Exact<T extends {
4
+ [key: string]: unknown;
5
+ }> = {
6
+ [K in keyof T]: T[K];
7
+ };
8
+ export type MakeOptional<T, K extends keyof T> = Omit<T, K> & {
9
+ [SubKey in K]?: Maybe<T[SubKey]>;
10
+ };
11
+ export type MakeMaybe<T, K extends keyof T> = Omit<T, K> & {
12
+ [SubKey in K]: Maybe<T[SubKey]>;
13
+ };
14
+ /** All built-in and custom scalars, mapped to their actual values */
15
+ export type Scalars = {
16
+ ID: number | string;
17
+ String: string;
18
+ Boolean: boolean;
19
+ Int: number;
20
+ Float: number;
21
+ DateTime: any;
22
+ JSON: any;
23
+ LanguageCode: any;
24
+ OrderList: any;
25
+ };
26
+ export type AddCustomerToMyCustomerManagedGroupInput = {
27
+ emailAddress: Scalars['String'];
28
+ isGroupAdmin?: InputMaybe<Scalars['Boolean']>;
29
+ };
30
+ export type CustomerManagedGroup = {
31
+ __typename?: 'CustomerManagedGroup';
32
+ createdAt: Scalars['DateTime'];
33
+ customers: Array<CustomerManagedGroupMember>;
34
+ id: Scalars['ID'];
35
+ name: Scalars['String'];
36
+ updatedAt: Scalars['DateTime'];
37
+ };
38
+ export type CustomerManagedGroupAddress = {
39
+ __typename?: 'CustomerManagedGroupAddress';
40
+ city?: Maybe<Scalars['String']>;
41
+ company?: Maybe<Scalars['String']>;
42
+ country: CustomerManagedGroupCountry;
43
+ createdAt: Scalars['DateTime'];
44
+ defaultBillingAddress?: Maybe<Scalars['Boolean']>;
45
+ defaultShippingAddress?: Maybe<Scalars['Boolean']>;
46
+ fullName?: Maybe<Scalars['String']>;
47
+ id: Scalars['ID'];
48
+ phoneNumber?: Maybe<Scalars['String']>;
49
+ postalCode?: Maybe<Scalars['String']>;
50
+ province?: Maybe<Scalars['String']>;
51
+ streetLine1: Scalars['String'];
52
+ streetLine2?: Maybe<Scalars['String']>;
53
+ updatedAt: Scalars['DateTime'];
54
+ };
55
+ /** When no ID is given, a new address will be created */
56
+ export type CustomerManagedGroupAddressInput = {
57
+ city?: InputMaybe<Scalars['String']>;
58
+ company?: InputMaybe<Scalars['String']>;
59
+ countryCode?: InputMaybe<Scalars['String']>;
60
+ defaultBillingAddress?: InputMaybe<Scalars['Boolean']>;
61
+ defaultShippingAddress?: InputMaybe<Scalars['Boolean']>;
62
+ fullName?: InputMaybe<Scalars['String']>;
63
+ id?: InputMaybe<Scalars['ID']>;
64
+ phoneNumber?: InputMaybe<Scalars['String']>;
65
+ postalCode?: InputMaybe<Scalars['String']>;
66
+ province?: InputMaybe<Scalars['String']>;
67
+ streetLine1?: InputMaybe<Scalars['String']>;
68
+ streetLine2?: InputMaybe<Scalars['String']>;
69
+ };
70
+ export type CustomerManagedGroupCountry = {
71
+ __typename?: 'CustomerManagedGroupCountry';
72
+ code: Scalars['String'];
73
+ createdAt: Scalars['DateTime'];
74
+ enabled: Scalars['Boolean'];
75
+ id: Scalars['ID'];
76
+ name: Scalars['String'];
77
+ translations: Array<CustomerManagedGroupCountryTranslation>;
78
+ updatedAt: Scalars['DateTime'];
79
+ };
80
+ export type CustomerManagedGroupCountryTranslation = {
81
+ __typename?: 'CustomerManagedGroupCountryTranslation';
82
+ id: Scalars['ID'];
83
+ languageCode: Scalars['LanguageCode'];
84
+ name: Scalars['String'];
85
+ };
86
+ export type CustomerManagedGroupMember = {
87
+ __typename?: 'CustomerManagedGroupMember';
88
+ addresses?: Maybe<Array<CustomerManagedGroupAddress>>;
89
+ customFields?: Maybe<Scalars['JSON']>;
90
+ customerId: Scalars['ID'];
91
+ emailAddress: Scalars['String'];
92
+ firstName: Scalars['String'];
93
+ isGroupAdministrator: Scalars['Boolean'];
94
+ lastName: Scalars['String'];
95
+ title?: Maybe<Scalars['String']>;
96
+ };
97
+ export type Mutation = {
98
+ __typename?: 'Mutation';
99
+ /** Creates a group with the current logged in user as administrator of the group */
100
+ addCustomerToMyCustomerManagedGroup: CustomerManagedGroup;
101
+ /** Create an empty group with the current user as Administrator */
102
+ createCustomerManagedGroup: CustomerManagedGroup;
103
+ makeCustomerAdminOfCustomerManagedGroup: CustomerManagedGroup;
104
+ removeCustomerFromMyCustomerManagedGroup: CustomerManagedGroup;
105
+ /** Update a member of one's group */
106
+ updateCustomerManagedGroupMember: CustomerManagedGroup;
107
+ };
108
+ export type MutationAddCustomerToMyCustomerManagedGroupArgs = {
109
+ input?: InputMaybe<AddCustomerToMyCustomerManagedGroupInput>;
110
+ };
111
+ export type MutationMakeCustomerAdminOfCustomerManagedGroupArgs = {
112
+ customerId: Scalars['ID'];
113
+ groupId: Scalars['ID'];
114
+ };
115
+ export type MutationRemoveCustomerFromMyCustomerManagedGroupArgs = {
116
+ customerId: Scalars['ID'];
117
+ };
118
+ export type MutationUpdateCustomerManagedGroupMemberArgs = {
119
+ input: UpdateCustomerManagedGroupMemberInput;
120
+ };
121
+ export type Query = {
122
+ __typename?: 'Query';
123
+ /** Fetch the current logged in group member */
124
+ activeCustomerManagedGroupMember?: Maybe<CustomerManagedGroupMember>;
125
+ myCustomerManagedGroup?: Maybe<CustomerManagedGroup>;
126
+ /** Fetch placed orders for each member of the group */
127
+ ordersForMyCustomerManagedGroup: Scalars['OrderList'];
128
+ };
129
+ export type UpdateCustomerManagedGroupMemberInput = {
130
+ addresses?: InputMaybe<Array<CustomerManagedGroupAddressInput>>;
131
+ customFields?: InputMaybe<Scalars['JSON']>;
132
+ customerId: Scalars['ID'];
133
+ emailAddress?: InputMaybe<Scalars['String']>;
134
+ firstName?: InputMaybe<Scalars['String']>;
135
+ lastName?: InputMaybe<Scalars['String']>;
136
+ title?: InputMaybe<Scalars['String']>;
137
+ };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,4 @@
1
+ export * from './customer-managed-groups.plugin';
2
+ export * from './customer-managed-groups.service';
3
+ export * from './api-extensions';
4
+ export * from './custom-fields';
package/dist/index.js ADDED
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./customer-managed-groups.plugin"), exports);
18
+ __exportStar(require("./customer-managed-groups.service"), exports);
19
+ __exportStar(require("./api-extensions"), exports);
20
+ __exportStar(require("./custom-fields"), exports);
package/package.json ADDED
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "@pinelab/vendure-plugin-customer-managed-groups",
3
+ "version": "0.0.3",
4
+ "description": "This plugin allows customer groups to have 'Group admins', that are allowed to fetch placed orders for everyone in the group.",
5
+ "author": "Martijn van de Brug <martijn@pinelab.studio>",
6
+ "homepage": "https://pinelab-plugins.com/",
7
+ "repository": "https://github.com/Pinelab-studio/pinelab-vendure-plugins",
8
+ "license": "MIT",
9
+ "private": false,
10
+ "publishConfig": {
11
+ "access": "public"
12
+ },
13
+ "engines": {
14
+ "node": ">=16.0.0"
15
+ },
16
+ "main": "dist/index.js",
17
+ "types": "dist/index.d.ts",
18
+ "files": [
19
+ "dist",
20
+ "README.md"
21
+ ],
22
+ "scripts": {
23
+ "start": "yarn ts-node test/dev-server.ts",
24
+ "build": "rimraf dist && yarn graphql-codegen && tsc",
25
+ "test": "vitest run"
26
+ },
27
+ "devDependencies": {
28
+ "@graphql-codegen/cli": "^2.4.0",
29
+ "@graphql-codegen/typescript": "^2.4.8",
30
+ "@graphql-codegen/typescript-operations": "^2.3.5",
31
+ "@swc/core": "^1.3.59",
32
+ "@vendure/admin-ui-plugin": "2.0.4",
33
+ "@vendure/asset-server-plugin": "2.0.4",
34
+ "@vendure/core": "2.0.4",
35
+ "@vendure/testing": "2.0.4",
36
+ "@vendure/ui-devkit": "2.0.4",
37
+ "rimraf": "^4.1.2",
38
+ "ts-node": "10.9.1",
39
+ "typescript": "5.0.4",
40
+ "unplugin-swc": "^1.3.2",
41
+ "vitest": "^0.32.0"
42
+ },
43
+ "gitHead": "5673faf91c029dc4716226965ce3531931b434b6"
44
+ }