@primershop/strapi-plugin-status-manager 0.0.16 → 0.0.18

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.
@@ -1,750 +1,651 @@
1
- import { errors } from '@strapi/utils';
2
-
3
- var permissions = [
4
- {
5
- section: "plugins",
6
- displayName: "Access Status Manager",
7
- uid: "main",
8
- pluginName: "primershop-status-manager"
9
- },
10
- {
11
- section: "plugins",
12
- displayName: "Create",
13
- uid: "status.create",
14
- subCategory: "status",
15
- pluginName: "primershop-status-manager"
16
- },
17
- {
18
- section: "plugins",
19
- displayName: "Read",
20
- uid: "status.read",
21
- subCategory: "status",
22
- pluginName: "primershop-status-manager",
23
- aliases: [
24
- {
25
- actionId: "plugin::content-manager.explorer.read",
26
- subjects: [
27
- "plugin::primershop-status-manager.status"
28
- ]
29
- }
30
- ]
31
- },
32
- {
33
- section: "plugins",
34
- displayName: "Update",
35
- uid: "status.update",
36
- subCategory: "status",
37
- pluginName: "primershop-status-manager"
38
- },
39
- {
40
- section: "plugins",
41
- displayName: "Delete",
42
- uid: "status.delete",
43
- subCategory: "status",
44
- pluginName: "primershop-status-manager"
45
- }
1
+ import { errors } from "@strapi/utils";
2
+ const permissions = [
3
+ {
4
+ section: "plugins",
5
+ displayName: "Access Status Manager",
6
+ uid: "main",
7
+ pluginName: "primershop-status-manager"
8
+ },
9
+ {
10
+ section: "plugins",
11
+ displayName: "Create",
12
+ uid: "status.create",
13
+ subCategory: "status",
14
+ pluginName: "primershop-status-manager"
15
+ },
16
+ {
17
+ section: "plugins",
18
+ displayName: "Read",
19
+ uid: "status.read",
20
+ subCategory: "status",
21
+ pluginName: "primershop-status-manager",
22
+ aliases: [
23
+ {
24
+ actionId: "plugin::content-manager.explorer.read",
25
+ subjects: ["plugin::primershop-status-manager.status"]
26
+ }
27
+ ]
28
+ },
29
+ {
30
+ section: "plugins",
31
+ displayName: "Update",
32
+ uid: "status.update",
33
+ subCategory: "status",
34
+ pluginName: "primershop-status-manager"
35
+ },
36
+ {
37
+ section: "plugins",
38
+ displayName: "Delete",
39
+ uid: "status.delete",
40
+ subCategory: "status",
41
+ pluginName: "primershop-status-manager"
42
+ }
46
43
  ];
47
-
48
- const bootstrap = async ({ strapi })=>{
49
- try {
50
- strapi.admin.services.permission.actionProvider.registerMany(permissions);
51
- strapi.log.info(`[primershop-status-manager] Registered ${permissions.length} permission actions`);
52
- } catch (error) {
53
- strapi.log.error("[primershop-status-manager] Failed to register permissions:", error);
54
- throw error;
44
+ const bootstrap = async ({ strapi: strapi2 }) => {
45
+ try {
46
+ strapi2.admin.services.permission.actionProvider.registerMany(
47
+ permissions
48
+ );
49
+ strapi2.log.info(
50
+ `[primershop-status-manager] Registered ${permissions.length} permission actions`
51
+ );
52
+ } catch (error) {
53
+ strapi2.log.error(
54
+ "[primershop-status-manager] Failed to register permissions:",
55
+ error
56
+ );
57
+ throw error;
58
+ }
59
+ strapi2.db?.lifecycles?.subscribe?.({
60
+ // catch all models
61
+ models: ["*"],
62
+ async afterDelete(event) {
63
+ const modelUid = event?.model?.uid;
64
+ const deleted = event?.result;
65
+ const documentId = deleted?.documentId;
66
+ if (!modelUid || !documentId) return;
67
+ await strapi2.db.query("plugin::primershop-status-manager.status-link").deleteMany({
68
+ where: { targetUid: modelUid, targetDocumentId: documentId }
69
+ });
55
70
  }
56
- // Register lifecycle hooks for status filtering
57
- strapi.db?.lifecycles?.subscribe?.({
58
- // catch all models
59
- models: [
60
- "*"
61
- ],
62
- async afterDelete (event) {
63
- const modelUid = event?.model?.uid;
64
- const deleted = event?.result;
65
- const documentId = deleted?.documentId;
66
- if (!modelUid || !documentId) return;
67
- await strapi.db.query("plugin::primershop-status-manager.status-link").deleteMany({
68
- where: {
69
- targetUid: modelUid,
70
- targetDocumentId: documentId
71
- }
72
- });
73
- }
74
- });
71
+ });
75
72
  };
76
-
77
- var status$1 = {
78
- kind: "collectionType",
79
- collectionName: "status",
80
- info: {
81
- singularName: "status",
82
- pluralName: "statuses",
83
- displayName: "Status",
84
- description: "Status for products"
73
+ const status$1 = {
74
+ kind: "collectionType",
75
+ collectionName: "status",
76
+ info: {
77
+ singularName: "status",
78
+ pluralName: "statuses",
79
+ displayName: "Status",
80
+ description: "Status for products"
81
+ },
82
+ options: {
83
+ draftAndPublish: false
84
+ },
85
+ pluginOptions: {
86
+ "content-manager": {
87
+ visible: false
85
88
  },
86
- options: {
87
- draftAndPublish: false
89
+ "content-type-builder": {
90
+ visible: false
91
+ }
92
+ },
93
+ attributes: {
94
+ name: {
95
+ type: "string",
96
+ minLength: 1,
97
+ maxLength: 50,
98
+ required: true,
99
+ configurable: false
88
100
  },
89
- pluginOptions: {
90
- "content-manager": {
91
- visible: false
92
- },
93
- "content-type-builder": {
94
- visible: false
95
- }
101
+ published: {
102
+ type: "boolean",
103
+ default: false
96
104
  },
97
- attributes: {
98
- name: {
99
- type: "string",
100
- minLength: 1,
101
- maxLength: 50,
102
- required: true,
103
- configurable: false
104
- },
105
- published: {
106
- type: "boolean",
107
- default: false
108
- },
109
- order: {
110
- type: "integer",
111
- default: 0
112
- },
113
- links: {
114
- type: "relation",
115
- relation: "oneToMany",
116
- target: "plugin::primershop-status-manager.status-link",
117
- mappedBy: "status",
118
- configurable: false
119
- }
105
+ order: {
106
+ type: "integer",
107
+ default: 0
108
+ },
109
+ links: {
110
+ type: "relation",
111
+ relation: "oneToMany",
112
+ target: "plugin::primershop-status-manager.status-link",
113
+ mappedBy: "status",
114
+ configurable: false
120
115
  }
116
+ }
121
117
  };
122
-
123
- var statusLink = {
124
- kind: "collectionType",
125
- collectionName: "status_links",
126
- info: {
127
- singularName: "status-link",
128
- pluralName: "status-links",
129
- displayName: "Status Link",
130
- description: "Association between any content type document and a single status"
118
+ const statusLink = {
119
+ kind: "collectionType",
120
+ collectionName: "status_links",
121
+ info: {
122
+ singularName: "status-link",
123
+ pluralName: "status-links",
124
+ displayName: "Status Link",
125
+ description: "Association between any content type document and a single status"
126
+ },
127
+ options: {
128
+ draftAndPublish: false
129
+ },
130
+ pluginOptions: {
131
+ "content-manager": {
132
+ visible: false
131
133
  },
132
- options: {
133
- draftAndPublish: false
134
+ "content-type-builder": {
135
+ visible: false
136
+ }
137
+ },
138
+ attributes: {
139
+ targetUid: {
140
+ type: "string",
141
+ required: true
134
142
  },
135
- pluginOptions: {
136
- "content-manager": {
137
- visible: false
138
- },
139
- "content-type-builder": {
140
- visible: false
141
- }
143
+ targetDocumentId: {
144
+ type: "string",
145
+ required: true
142
146
  },
143
- attributes: {
144
- targetUid: {
145
- type: "string",
146
- required: true
147
- },
148
- targetDocumentId: {
149
- type: "string",
150
- required: true
151
- },
152
- status: {
153
- type: "relation",
154
- relation: "manyToOne",
155
- target: "plugin::primershop-status-manager.status",
156
- required: false,
157
- configurable: false
158
- }
159
- }
160
- };
161
-
162
- var contentTypes = {
163
147
  status: {
164
- schema: status$1
165
- },
166
- "status-link": {
167
- schema: statusLink
148
+ type: "relation",
149
+ relation: "manyToOne",
150
+ target: "plugin::primershop-status-manager.status",
151
+ required: false,
152
+ configurable: false
168
153
  }
154
+ }
169
155
  };
170
-
171
- const content = ({ strapi })=>({
172
- async getStatusForTarget (ctx) {
173
- const requestParams = ctx.request.URL.searchParams;
174
- const contentTypeUid = requestParams.get("contentTypeUid");
175
- if (!strapi.getModel(contentTypeUid)) return ctx.notFound("Unknown contentTypeUid");
176
- const contentDocumentId = requestParams.get("contentDocumentId");
177
- const exists = await strapi.documents(contentTypeUid).findOne({
178
- documentId: contentDocumentId
179
- });
180
- if (!exists) return ctx.notFound("Target document not found");
181
- const link = await strapi.plugin("primershop-status-manager").service("statusLink").getForTarget(contentTypeUid, contentDocumentId);
182
- return ctx.send({
183
- status: link?.status ?? null
184
- });
185
- },
186
- async setStatusForTarget (ctx) {
187
- const { contentTypeUid, contentDocumentId, statusId } = ctx.request.body;
188
- if (!strapi.getModel(contentTypeUid)) return ctx.notFound("Unknown contentTypeUid");
189
- const exists = await strapi.documents(contentTypeUid).findOne({
190
- documentId: contentDocumentId
191
- });
192
- if (!exists) return ctx.notFound("Target document not found");
193
- const link = await strapi.plugin("primershop-status-manager").service("statusLink").setForTarget(contentTypeUid, contentDocumentId, statusId);
194
- return ctx.send({
195
- status: link.status
196
- });
197
- }
156
+ const contentTypes = {
157
+ status: {
158
+ schema: status$1
159
+ },
160
+ "status-link": {
161
+ schema: statusLink
162
+ }
163
+ };
164
+ const content = ({ strapi: strapi2 }) => ({
165
+ async getStatusForTarget(ctx) {
166
+ const requestParams = ctx.request.URL.searchParams;
167
+ const contentTypeUid = requestParams.get("contentTypeUid");
168
+ if (!strapi2.getModel(contentTypeUid))
169
+ return ctx.notFound("Unknown contentTypeUid");
170
+ const contentDocumentId = requestParams.get("contentDocumentId");
171
+ const exists = await strapi2.documents(contentTypeUid).findOne({
172
+ documentId: contentDocumentId
198
173
  });
199
-
200
- const status = ({ strapi })=>({
201
- async listStatuses (ctx) {
202
- try {
203
- const statuses = await strapi.documents("plugin::primershop-status-manager.status").findMany({
204
- sort: {
205
- order: "asc"
206
- }
207
- });
208
- return ctx.send(statuses);
209
- } catch (err) {
210
- console.error("❌ Status controller: find error:", err);
211
- ctx.throw(500, err);
212
- }
213
- },
214
- async create (ctx) {
215
- try {
216
- const { name, published = false } = ctx.request.body;
217
- // Validate name (only Latin characters)
218
- if (!/^[a-zA-Z\s]+$/.test(name)) {
219
- return ctx.badRequest("Status name must contain only Latin characters.");
220
- }
221
- // Get the highest order value
222
- const existingStatuses = await strapi.documents("plugin::primershop-status-manager.status").findMany({
223
- orderBy: {
224
- order: "desc"
225
- },
226
- limit: 1
227
- });
228
- const newOrder = existingStatuses.length > 0 ? existingStatuses[0].order + 1 : 0;
229
- // Create status
230
- const newStatus = await strapi.documents("plugin::primershop-status-manager.status").create({
231
- data: {
232
- name,
233
- published,
234
- order: newOrder
235
- }
236
- });
237
- return ctx.send(newStatus);
238
- } catch (error) {
239
- console.error("Status controller: create error:", error);
240
- ctx.internalServerError(`Error adding status: ${error}`);
241
- }
242
- },
243
- async reorder (ctx) {
244
- try {
245
- const { statuses } = ctx.request.body;
246
- if (!Array.isArray(statuses)) {
247
- return ctx.badRequest("Invalid data format");
248
- }
249
- // Update each status with new order
250
- await Promise.all(statuses.map(({ documentId, order })=>strapi.documents("plugin::primershop-status-manager.status").update({
251
- documentId,
252
- data: {
253
- order
254
- }
255
- })));
256
- ctx.send({
257
- message: "Order updated successfully"
258
- });
259
- } catch (error) {
260
- console.error("Status controller: reorder error:", error);
261
- ctx.internalServerError(`Error updating order: ${error}`);
262
- }
263
- },
264
- async publish (ctx) {
265
- try {
266
- const { id } = ctx.params;
267
- const { published } = ctx.request.body;
268
- await strapi.documents("plugin::primershop-status-manager.status").update({
269
- documentId: id,
270
- data: {
271
- published
272
- }
273
- });
274
- ctx.send({
275
- message: "Status updated successfully"
276
- });
277
- } catch (error) {
278
- console.error("Status controller: publish error:", error);
279
- ctx.internalServerError(`Error updating status: ${error}`);
280
- }
281
- },
282
- async delete (ctx) {
283
- try {
284
- const { statusId } = ctx.request.body;
285
- if (!statusId) {
286
- return ctx.badRequest("Status ID is required.");
287
- }
288
- // Delete the status
289
- await strapi.documents("plugin::primershop-status-manager.status").delete({
290
- documentId: statusId
291
- });
292
- return ctx.send({
293
- message: "Status deleted successfully"
294
- });
295
- } catch (error) {
296
- console.error("Status controller: delete error:", error);
297
- ctx.internalServerError(`Error deleting status: ${error}`);
298
- }
299
- }
174
+ if (!exists) return ctx.notFound("Target document not found");
175
+ const link = await strapi2.plugin("primershop-status-manager").service("statusLink").getForTarget(contentTypeUid, contentDocumentId);
176
+ return ctx.send({ status: link?.status ?? null });
177
+ },
178
+ async setStatusForTarget(ctx) {
179
+ const { contentTypeUid, contentDocumentId, statusId } = ctx.request.body;
180
+ if (!strapi2.getModel(contentTypeUid))
181
+ return ctx.notFound("Unknown contentTypeUid");
182
+ const exists = await strapi2.documents(contentTypeUid).findOne({
183
+ documentId: contentDocumentId
300
184
  });
301
-
302
- var controllers = {
303
- status_controller: status,
304
- content_controller: content
305
- };
306
-
307
- const PLUGIN_ID = "primershop-status-manager";
308
-
309
- var addStatusField = (async (context, next)=>{
310
- const uid = context.uid;
311
- if (!uid.includes("api::")) {
312
- return next();
313
- }
314
- const result = await next();
315
- let documentIds = [];
316
- if (Array.isArray(result)) {
317
- documentIds = result.map((doc)=>doc.documentId).filter(Boolean);
318
- } else if (result && typeof result === "object" && "documentId" in result) {
319
- documentIds = [
320
- result.documentId
321
- ].filter(Boolean);
322
- }
323
- if (documentIds.length === 0) {
324
- return result;
185
+ if (!exists) return ctx.notFound("Target document not found");
186
+ const link = await strapi2.plugin("primershop-status-manager").service("statusLink").setForTarget(contentTypeUid, contentDocumentId, statusId);
187
+ return ctx.send({ status: link.status });
188
+ }
189
+ });
190
+ const status = ({ strapi: strapi2 }) => ({
191
+ async listStatuses(ctx) {
192
+ try {
193
+ const statuses = await strapi2.documents("plugin::primershop-status-manager.status").findMany({
194
+ sort: { order: "asc" }
195
+ });
196
+ return ctx.send(statuses);
197
+ } catch (err) {
198
+ console.error("❌ Status controller: find error:", err);
199
+ ctx.throw(500, err);
325
200
  }
201
+ },
202
+ async create(ctx) {
326
203
  try {
327
- const statusLinks = await strapi.db.query("plugin::primershop-status-manager.status-link").findMany({
328
- populate: {
329
- status: true
330
- },
331
- where: {
332
- targetUid: uid,
333
- targetDocumentId: {
334
- $in: documentIds
335
- }
336
- }
337
- });
338
- if (Array.isArray(result)) {
339
- result.forEach((doc)=>{
340
- doc.statusField = statusLinks.find((link)=>link.targetDocumentId === doc.documentId)?.status || undefined;
341
- });
342
- }
343
- if (result && typeof result === "object") {
344
- result.statusField = statusLinks.find((link)=>link.targetDocumentId === result.documentId)?.status || undefined;
204
+ const { name, published = false } = ctx.request.body;
205
+ if (!/^[a-zA-Z\s]+$/.test(name)) {
206
+ return ctx.badRequest(
207
+ "Status name must contain only Latin characters."
208
+ );
209
+ }
210
+ const existingStatuses = await strapi2.documents("plugin::primershop-status-manager.status").findMany({
211
+ orderBy: { order: "desc" },
212
+ limit: 1
213
+ });
214
+ const newOrder = existingStatuses.length > 0 ? existingStatuses[0].order + 1 : 0;
215
+ const newStatus = await strapi2.documents("plugin::primershop-status-manager.status").create({
216
+ data: {
217
+ name,
218
+ published,
219
+ order: newOrder
345
220
  }
221
+ });
222
+ return ctx.send(newStatus);
346
223
  } catch (error) {
347
- // If status enrichment fails, just return original result
348
- console.error("primershop-status-manager: status enrichment error", error);
224
+ console.error("Status controller: create error:", error);
225
+ ctx.internalServerError(`Error adding status: ${error}`);
349
226
  }
350
- return result;
351
- });
352
-
353
- var filterByStatus = (async (context, next)=>{
354
- const uid = context.uid;
355
- if (!uid.includes("api::")) {
356
- return next();
227
+ },
228
+ async reorder(ctx) {
229
+ try {
230
+ const { statuses } = ctx.request.body;
231
+ if (!Array.isArray(statuses)) {
232
+ return ctx.badRequest("Invalid data format");
233
+ }
234
+ await Promise.all(
235
+ statuses.map(
236
+ ({ documentId, order }) => strapi2.documents("plugin::primershop-status-manager.status").update({
237
+ documentId,
238
+ data: { order }
239
+ })
240
+ )
241
+ );
242
+ ctx.send({ message: "Order updated successfully" });
243
+ } catch (error) {
244
+ console.error("Status controller: reorder error:", error);
245
+ ctx.internalServerError(`Error updating order: ${error}`);
357
246
  }
358
- const paramKeys = Object.keys(context.params || {});
359
- if (!paramKeys.includes("statusName")) {
360
- return next();
247
+ },
248
+ async publish(ctx) {
249
+ try {
250
+ const { id } = ctx.params;
251
+ const { published } = ctx.request.body;
252
+ await strapi2.documents("plugin::primershop-status-manager.status").update({
253
+ documentId: id,
254
+ data: { published }
255
+ });
256
+ ctx.send({ message: "Status updated successfully" });
257
+ } catch (error) {
258
+ console.error("Status controller: publish error:", error);
259
+ ctx.internalServerError(`Error updating status: ${error}`);
361
260
  }
362
- const desiredStatus = context.params["statusName"];
363
- if (!desiredStatus || desiredStatus === "all") return next();
364
- const isValid = await strapi.plugin("primershop-status-manager").service("status").isValidStatus(desiredStatus);
365
- if (!isValid) throw new errors.ValidationError(`Invalid status: ${desiredStatus}`);
366
- const status = await strapi.plugin("primershop-status-manager").service("status").getStatusByName(desiredStatus);
367
- if (!status) {
368
- throw new errors.ValidationError(`Status not found: ${desiredStatus}`);
261
+ },
262
+ async delete(ctx) {
263
+ try {
264
+ const { statusId } = ctx.request.body;
265
+ if (!statusId) {
266
+ return ctx.badRequest("Status ID is required.");
267
+ }
268
+ await strapi2.documents("plugin::primershop-status-manager.status").delete({
269
+ documentId: statusId
270
+ });
271
+ return ctx.send({ message: "Status deleted successfully" });
272
+ } catch (error) {
273
+ console.error("Status controller: delete error:", error);
274
+ ctx.internalServerError(`Error deleting status: ${error}`);
369
275
  }
276
+ }
277
+ });
278
+ const controllers = {
279
+ status_controller: status,
280
+ content_controller: content
281
+ };
282
+ const PLUGIN_ID = "primershop-status-manager";
283
+ const addStatusField = async (context, next) => {
284
+ const uid = context.uid;
285
+ if (!uid.includes("api::")) {
286
+ return next();
287
+ }
288
+ const result = await next();
289
+ let documentIds = [];
290
+ if (Array.isArray(result)) {
291
+ documentIds = result.map((doc) => doc.documentId).filter(Boolean);
292
+ } else if (result && typeof result === "object" && "documentId" in result) {
293
+ documentIds = [result.documentId].filter(Boolean);
294
+ }
295
+ if (documentIds.length === 0) {
296
+ return result;
297
+ }
298
+ try {
370
299
  const statusLinks = await strapi.db.query("plugin::primershop-status-manager.status-link").findMany({
371
- where: {
372
- targetUid: uid,
373
- status: status.id
374
- },
375
- select: [
376
- "targetDocumentId"
377
- ]
300
+ populate: {
301
+ status: true
302
+ },
303
+ where: {
304
+ targetUid: uid,
305
+ targetDocumentId: { $in: documentIds }
306
+ }
378
307
  });
379
- const allowedDocumentIds = statusLinks.map((link)=>link.targetDocumentId);
380
- context.params["filters"] = {
381
- ...context.params["filters"],
382
- documentId: {
383
- $in: allowedDocumentIds
384
- }
385
- };
386
- return next();
387
- });
388
-
389
- var filterPublished = (async (context, next)=>{
390
- const uid = context.uid;
391
- if (!uid.includes("api::")) {
392
- return next();
308
+ if (Array.isArray(result)) {
309
+ result.forEach((doc) => {
310
+ doc.statusField = statusLinks.find((link) => link.targetDocumentId === doc.documentId)?.status || void 0;
311
+ });
393
312
  }
394
- const params = context.params;
395
- if (!params && !params["status"] || params["statusName"]) return next();
396
- const unpublishedStatusLinks = await strapi.db.query("plugin::primershop-status-manager.status-link").findMany({
397
- populate: {
398
- status: true
399
- },
400
- where: {
401
- targetUid: uid,
402
- status: {
403
- published: false
404
- }
405
- },
406
- select: [
407
- "targetDocumentId"
408
- ]
409
- });
410
- const unpublishedDocumentIds = unpublishedStatusLinks.map((link)=>link.targetDocumentId);
411
- context.params["filters"] = {
412
- ...context.params["filters"],
413
- documentId: {
414
- $notIn: unpublishedDocumentIds
415
- }
416
- };
313
+ if (result && typeof result === "object") {
314
+ result.statusField = statusLinks.find(
315
+ (link) => link.targetDocumentId === result.documentId
316
+ )?.status || void 0;
317
+ }
318
+ } catch (error) {
319
+ console.error("primershop-status-manager: status enrichment error", error);
320
+ }
321
+ return result;
322
+ };
323
+ const filterByStatus = async (context, next) => {
324
+ const uid = context.uid;
325
+ if (!uid.includes("api::")) {
417
326
  return next();
418
- });
419
-
420
- const register = ({ strapi })=>{
421
- strapi.customFields.register({
422
- name: "statusName",
423
- plugin: PLUGIN_ID,
424
- type: "string"
425
- });
426
- strapi.documents.use(filterByStatus);
427
- strapi.documents.use(addStatusField);
428
- strapi.documents.use(filterPublished);
327
+ }
328
+ const paramKeys = Object.keys(context.params || {});
329
+ if (!paramKeys.includes("statusName")) {
330
+ return next();
331
+ }
332
+ const desiredStatus = context.params["statusName"];
333
+ if (!desiredStatus || desiredStatus === "all") return next();
334
+ const isValid = await strapi.plugin("primershop-status-manager").service("status").isValidStatus(desiredStatus);
335
+ if (!isValid)
336
+ throw new errors.ValidationError(`Invalid status: ${desiredStatus}`);
337
+ const status2 = await strapi.plugin("primershop-status-manager").service("status").getStatusByName(desiredStatus);
338
+ if (!status2) {
339
+ throw new errors.ValidationError(`Status not found: ${desiredStatus}`);
340
+ }
341
+ const statusLinks = await strapi.db.query("plugin::primershop-status-manager.status-link").findMany({
342
+ where: {
343
+ targetUid: uid,
344
+ status: status2.id
345
+ },
346
+ select: ["targetDocumentId"]
347
+ });
348
+ const allowedDocumentIds = statusLinks.map((link) => link.targetDocumentId);
349
+ context.params["filters"] = {
350
+ ...context.params["filters"],
351
+ documentId: { $in: allowedDocumentIds }
352
+ };
353
+ return next();
429
354
  };
430
-
431
- var statusManagement = [
432
- {
433
- method: "GET",
434
- path: "/statuses",
435
- handler: "status_controller.listStatuses",
436
- config: {
437
- policies: [
438
- {
439
- name: "admin::hasPermissions",
440
- config: {
441
- actions: [
442
- "plugin::primershop-status-manager.status.read"
443
- ]
444
- }
445
- }
446
- ]
447
- },
448
- description: "Get all statuses",
449
- tag: {
450
- plugin: "primershop-status-manager",
451
- name: "statuses",
452
- actionType: "findMany"
453
- }
355
+ const filterPublished = async (context, next) => {
356
+ const uid = context.uid;
357
+ if (!uid.includes("api::")) {
358
+ return next();
359
+ }
360
+ const params = context.params;
361
+ if (!params && !params["status"] || params["statusName"]) return next();
362
+ const unpublishedStatusLinks = await strapi.db.query("plugin::primershop-status-manager.status-link").findMany({
363
+ populate: {
364
+ status: true
454
365
  },
455
- {
456
- method: "POST",
457
- path: "/status",
458
- handler: "status_controller.create",
459
- config: {
460
- policies: [
461
- {
462
- name: "admin::hasPermissions",
463
- config: {
464
- actions: [
465
- "plugin::primershop-status-manager.status.create"
466
- ]
467
- }
468
- }
469
- ]
470
- },
471
- description: "Create a new status",
472
- tag: {
473
- plugin: "primershop-status-manager",
474
- name: "Status",
475
- actionType: "create"
476
- }
366
+ where: {
367
+ targetUid: uid,
368
+ status: {
369
+ published: false
370
+ }
477
371
  },
478
- {
479
- method: "PUT",
480
- path: "/statuses/reorder",
481
- handler: "status_controller.reorder",
482
- config: {
483
- policies: [
484
- {
485
- name: "admin::hasPermissions",
486
- config: {
487
- actions: [
488
- "plugin::primershop-status-manager.status.update"
489
- ]
490
- }
491
- }
492
- ],
493
- description: "Reorder statuses",
494
- tag: {
495
- plugin: "primershop-status-manager",
496
- name: "Status",
497
- actionType: "update"
498
- }
372
+ select: ["targetDocumentId"]
373
+ });
374
+ const unpublishedDocumentIds = unpublishedStatusLinks.map(
375
+ (link) => link.targetDocumentId
376
+ );
377
+ context.params["filters"] = {
378
+ ...context.params["filters"],
379
+ documentId: { $notIn: unpublishedDocumentIds }
380
+ };
381
+ return next();
382
+ };
383
+ const register = ({ strapi: strapi2 }) => {
384
+ strapi2.customFields.register({
385
+ name: "statusName",
386
+ plugin: PLUGIN_ID,
387
+ type: "string"
388
+ });
389
+ strapi2.documents.use(filterByStatus);
390
+ strapi2.documents.use(addStatusField);
391
+ strapi2.documents.use(filterPublished);
392
+ };
393
+ const statusManagement = [
394
+ {
395
+ method: "GET",
396
+ path: "/statuses",
397
+ handler: "status_controller.listStatuses",
398
+ config: {
399
+ policies: [
400
+ {
401
+ name: "admin::hasPermissions",
402
+ config: {
403
+ actions: ["plugin::primershop-status-manager.status.read"]
404
+ }
499
405
  }
406
+ ]
500
407
  },
501
- {
502
- method: "PUT",
503
- path: "/statuses/delete",
504
- handler: "status_controller.delete",
505
- config: {
506
- policies: [
507
- {
508
- name: "admin::hasPermissions",
509
- config: {
510
- actions: [
511
- "plugin::primershop-status-manager.status.delete"
512
- ]
513
- }
514
- }
515
- ],
516
- description: "Delete a status",
517
- tag: {
518
- plugin: "primershop-status-manager",
519
- name: "Status",
520
- actionType: "delete"
521
- }
408
+ description: "Get all statuses",
409
+ tag: {
410
+ plugin: "primershop-status-manager",
411
+ name: "statuses",
412
+ actionType: "findMany"
413
+ }
414
+ },
415
+ {
416
+ method: "POST",
417
+ path: "/status",
418
+ handler: "status_controller.create",
419
+ config: {
420
+ policies: [
421
+ {
422
+ name: "admin::hasPermissions",
423
+ config: {
424
+ actions: ["plugin::primershop-status-manager.status.create"]
425
+ }
522
426
  }
427
+ ]
523
428
  },
524
- {
525
- method: "PUT",
526
- path: "/statuses/:id",
527
- handler: "status_controller.publish",
528
- config: {
529
- policies: [
530
- {
531
- name: "admin::hasPermissions",
532
- config: {
533
- actions: [
534
- "plugin::primershop-status-manager.status.update"
535
- ]
536
- }
537
- }
538
- ],
539
- description: "Update status publish state",
540
- tag: {
541
- plugin: "primershop-status-manager",
542
- name: "Status",
543
- actionType: "update"
544
- }
429
+ description: "Create a new status",
430
+ tag: {
431
+ plugin: "primershop-status-manager",
432
+ name: "Status",
433
+ actionType: "create"
434
+ }
435
+ },
436
+ {
437
+ method: "PUT",
438
+ path: "/statuses/reorder",
439
+ handler: "status_controller.reorder",
440
+ config: {
441
+ policies: [
442
+ {
443
+ name: "admin::hasPermissions",
444
+ config: {
445
+ actions: ["plugin::primershop-status-manager.status.update"]
446
+ }
545
447
  }
448
+ ],
449
+ description: "Reorder statuses",
450
+ tag: {
451
+ plugin: "primershop-status-manager",
452
+ name: "Status",
453
+ actionType: "update"
454
+ }
546
455
  }
547
- ];
548
-
549
- var contentManagement = [
550
- {
551
- method: "GET",
552
- path: "/content-status",
553
- handler: "content_controller.getStatusForTarget",
554
- config: {
555
- policies: [
556
- {
557
- name: "admin::hasPermissions",
558
- config: {
559
- actions: [
560
- "plugin::primershop-status-manager.status.read"
561
- ]
562
- }
563
- }
564
- ]
456
+ },
457
+ {
458
+ method: "PUT",
459
+ path: "/statuses/delete",
460
+ handler: "status_controller.delete",
461
+ config: {
462
+ policies: [
463
+ {
464
+ name: "admin::hasPermissions",
465
+ config: {
466
+ actions: ["plugin::primershop-status-manager.status.delete"]
467
+ }
565
468
  }
566
- },
567
- {
568
- method: "PUT",
569
- path: "/content-status",
570
- handler: "content_controller.setStatusForTarget",
571
- config: {
572
- policies: [
573
- {
574
- name: "admin::hasPermissions",
575
- config: {
576
- actions: [
577
- "plugin::primershop-status-manager.status.update"
578
- ]
579
- }
580
- }
581
- ]
469
+ ],
470
+ description: "Delete a status",
471
+ tag: {
472
+ plugin: "primershop-status-manager",
473
+ name: "Status",
474
+ actionType: "delete"
475
+ }
476
+ }
477
+ },
478
+ {
479
+ method: "PUT",
480
+ path: "/statuses/:id",
481
+ handler: "status_controller.publish",
482
+ config: {
483
+ policies: [
484
+ {
485
+ name: "admin::hasPermissions",
486
+ config: {
487
+ actions: ["plugin::primershop-status-manager.status.update"]
488
+ }
582
489
  }
490
+ ],
491
+ description: "Update status publish state",
492
+ tag: {
493
+ plugin: "primershop-status-manager",
494
+ name: "Status",
495
+ actionType: "update"
496
+ }
583
497
  }
498
+ }
584
499
  ];
585
-
586
- var routes = {
587
- admin: {
588
- type: "admin",
589
- routes: [
590
- ...statusManagement,
591
- ...contentManagement
592
- ]
500
+ const contentManagement = [
501
+ {
502
+ method: "GET",
503
+ path: "/content-status",
504
+ handler: "content_controller.getStatusForTarget",
505
+ config: {
506
+ policies: [
507
+ {
508
+ name: "admin::hasPermissions",
509
+ config: {
510
+ actions: ["plugin::primershop-status-manager.status.read"]
511
+ }
512
+ }
513
+ ]
593
514
  }
594
- };
595
-
596
- const statusService = ({ strapi })=>({
597
- async isValidStatus (code) {
598
- try {
599
- const row = await strapi.db.query("plugin::primershop-status-manager.status").findOne({
600
- where: {
601
- name: code
602
- },
603
- select: [
604
- "id"
605
- ]
606
- });
607
- return !!row;
608
- } catch {
609
- return false;
610
- }
611
- },
612
- async getStatusByName (name) {
613
- return strapi.db.query("plugin::primershop-status-manager.status").findOne({
614
- where: {
615
- name
616
- }
617
- });
618
- },
619
- isStatusEnabledFor (uid) {
620
- return !!strapi.getModel(uid);
621
- },
622
- async find () {
623
- const result = await strapi.db.query("plugin::primershop-status-manager.status").findMany({
624
- orderBy: {
625
- order: "asc"
626
- }
627
- });
628
- return result;
629
- },
630
- async findOne (id) {
631
- const result = await strapi.db.query("plugin::primershop-status-manager.status").findOne({
632
- where: {
633
- id
634
- }
635
- });
636
- return result;
637
- },
638
- async createStatus (data) {
639
- const result = await strapi.db.query("plugin::primershop-status-manager.status").create({
640
- data: {
641
- name: data.name,
642
- published: data.published ?? false,
643
- order: data.order ?? 0
644
- }
645
- });
646
- return result;
647
- },
648
- async findProductsByStatus (statusId) {
649
- return strapi.db.query("api::product.product").findMany({
650
- where: {
651
- status: statusId
652
- }
653
- });
654
- },
655
- async updateProductStatus (productId, statusId) {
656
- return strapi.db.query("api::product.product").update({
657
- where: {
658
- id: productId
659
- },
660
- data: {
661
- status: statusId
662
- }
663
- });
664
- },
665
- async delete (id) {
666
- return strapi.db.query("plugin::primershop-status-manager.status").delete({
667
- where: {
668
- id
669
- }
670
- });
671
- },
672
- async deleteStatus (statusId, replacementId) {
673
- // Find status by documentId
674
- const status = await strapi.db.query("plugin::primershop-status-manager.status").findOne({
675
- where: {
676
- documentId: statusId
677
- }
678
- });
679
- if (!status) {
680
- throw new Error("Status not found");
681
- }
682
- if (replacementId) {
683
- const replacementStatus = await strapi.db.query("plugin::primershop-status-manager.status").findOne({
684
- where: {
685
- documentId: replacementId
686
- }
687
- });
688
- if (!replacementStatus) {
689
- throw new Error("Replacement status not found");
690
- }
691
- }
692
- // Delete the status
693
- await strapi.db.query("plugin::primershop-status-manager.status").delete({
694
- where: {
695
- documentId: statusId
696
- }
697
- });
698
- return true;
515
+ },
516
+ {
517
+ method: "PUT",
518
+ path: "/content-status",
519
+ handler: "content_controller.setStatusForTarget",
520
+ config: {
521
+ policies: [
522
+ {
523
+ name: "admin::hasPermissions",
524
+ config: {
525
+ actions: ["plugin::primershop-status-manager.status.update"]
526
+ }
699
527
  }
528
+ ]
529
+ }
530
+ }
531
+ ];
532
+ const routes = {
533
+ admin: {
534
+ type: "admin",
535
+ routes: [...statusManagement, ...contentManagement]
536
+ }
537
+ };
538
+ const statusService = ({ strapi: strapi2 }) => ({
539
+ async isValidStatus(code) {
540
+ try {
541
+ const row = await strapi2.db.query("plugin::primershop-status-manager.status").findOne({ where: { name: code }, select: ["id"] });
542
+ return !!row;
543
+ } catch {
544
+ return false;
545
+ }
546
+ },
547
+ async getStatusByName(name) {
548
+ return strapi2.db.query("plugin::primershop-status-manager.status").findOne({ where: { name } });
549
+ },
550
+ isStatusEnabledFor(uid) {
551
+ return !!strapi2.getModel(uid);
552
+ },
553
+ async find() {
554
+ const result = await strapi2.db.query("plugin::primershop-status-manager.status").findMany({
555
+ orderBy: { order: "asc" }
556
+ });
557
+ return result;
558
+ },
559
+ async findOne(id) {
560
+ const result = await strapi2.db.query("plugin::primershop-status-manager.status").findOne({
561
+ where: { id }
562
+ });
563
+ return result;
564
+ },
565
+ async createStatus(data) {
566
+ const result = await strapi2.db.query("plugin::primershop-status-manager.status").create({
567
+ data: {
568
+ name: data.name,
569
+ published: data.published ?? false,
570
+ order: data.order ?? 0
571
+ }
572
+ });
573
+ return result;
574
+ },
575
+ async findProductsByStatus(statusId) {
576
+ return strapi2.db.query("api::product.product").findMany({
577
+ where: { status: statusId }
578
+ });
579
+ },
580
+ async updateProductStatus(productId, statusId) {
581
+ return strapi2.db.query("api::product.product").update({
582
+ where: { id: productId },
583
+ data: { status: statusId }
700
584
  });
701
-
702
- const statusLinkService = ({ strapi })=>({
703
- async getForTarget (targetUid, targetDocumentId) {
704
- const link = await strapi.db.query("plugin::primershop-status-manager.status-link").findOne({
705
- where: {
706
- targetUid,
707
- targetDocumentId
708
- },
709
- populate: {
710
- status: true
711
- }
712
- });
713
- return link ?? null;
714
- },
715
- async setForTarget (targetUid, targetDocumentId, statusDocumentId) {
716
- // Create status link
717
- await strapi.db.query("plugin::primershop-status-manager.status-link").deleteMany({
718
- where: {
719
- targetUid,
720
- targetDocumentId
721
- }
722
- });
723
- const created = await strapi.documents("plugin::primershop-status-manager.status-link").create({
724
- data: {
725
- targetUid,
726
- targetDocumentId,
727
- status: {
728
- set: statusDocumentId
729
- }
730
- }
731
- });
732
- return created;
585
+ },
586
+ async delete(id) {
587
+ return strapi2.db.query("plugin::primershop-status-manager.status").delete({
588
+ where: { id }
589
+ });
590
+ },
591
+ async deleteStatus(statusId, replacementId) {
592
+ const status2 = await strapi2.db.query("plugin::primershop-status-manager.status").findOne({
593
+ where: { documentId: statusId }
594
+ });
595
+ if (!status2) {
596
+ throw new Error("Status not found");
597
+ }
598
+ if (replacementId) {
599
+ const replacementStatus = await strapi2.db.query("plugin::primershop-status-manager.status").findOne({
600
+ where: { documentId: replacementId }
601
+ });
602
+ if (!replacementStatus) {
603
+ throw new Error("Replacement status not found");
604
+ }
605
+ }
606
+ await strapi2.db.query("plugin::primershop-status-manager.status").delete({
607
+ where: { documentId: statusId }
608
+ });
609
+ return true;
610
+ }
611
+ });
612
+ const statusLinkService = ({ strapi: strapi2 }) => ({
613
+ async getForTarget(targetUid, targetDocumentId) {
614
+ const link = await strapi2.db.query("plugin::primershop-status-manager.status-link").findOne({
615
+ where: { targetUid, targetDocumentId },
616
+ populate: { status: true }
617
+ });
618
+ return link ?? null;
619
+ },
620
+ async setForTarget(targetUid, targetDocumentId, statusDocumentId) {
621
+ await strapi2.db.query("plugin::primershop-status-manager.status-link").deleteMany({ where: { targetUid, targetDocumentId } });
622
+ const created = await strapi2.documents("plugin::primershop-status-manager.status-link").create({
623
+ data: {
624
+ targetUid,
625
+ targetDocumentId,
626
+ status: {
627
+ set: statusDocumentId
733
628
  }
629
+ }
734
630
  });
735
-
736
- var services = {
737
- status: statusService,
738
- statusLink: statusLinkService
631
+ return created;
632
+ }
633
+ });
634
+ const services = {
635
+ status: statusService,
636
+ statusLink: statusLinkService
637
+ };
638
+ const destroy = ({ strapi: strapi2 }) => {
639
+ };
640
+ const index = {
641
+ register,
642
+ bootstrap,
643
+ destroy,
644
+ controllers,
645
+ contentTypes,
646
+ routes,
647
+ services
739
648
  };
740
-
741
- var index = {
742
- register,
743
- controllers,
744
- contentTypes,
745
- routes,
746
- services,
747
- bootstrap
649
+ export {
650
+ index as default
748
651
  };
749
-
750
- export { index as default };