@strapi/core 5.53.0 → 5.54.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/dist/domain/content-type/index.d.ts.map +1 -1
  2. package/dist/domain/content-type/index.js +3 -1
  3. package/dist/domain/content-type/index.js.map +1 -1
  4. package/dist/domain/content-type/index.mjs +3 -1
  5. package/dist/domain/content-type/index.mjs.map +1 -1
  6. package/dist/package.json.js +14 -15
  7. package/dist/package.json.js.map +1 -1
  8. package/dist/package.json.mjs +14 -15
  9. package/dist/package.json.mjs.map +1 -1
  10. package/dist/services/content-source-maps.d.ts +14 -2
  11. package/dist/services/content-source-maps.d.ts.map +1 -1
  12. package/dist/services/content-source-maps.js +134 -1
  13. package/dist/services/content-source-maps.js.map +1 -1
  14. package/dist/services/content-source-maps.mjs +134 -2
  15. package/dist/services/content-source-maps.mjs.map +1 -1
  16. package/dist/services/cron.d.ts +3 -18
  17. package/dist/services/cron.d.ts.map +1 -1
  18. package/dist/services/cron.js +241 -33
  19. package/dist/services/cron.js.map +1 -1
  20. package/dist/services/cron.mjs +241 -33
  21. package/dist/services/cron.mjs.map +1 -1
  22. package/dist/services/document-service/transform/relations/extract/data-ids.d.ts +1 -1
  23. package/dist/services/document-service/transform/relations/extract/data-ids.d.ts.map +1 -1
  24. package/dist/services/document-service/transform/relations/extract/data-ids.js +12 -3
  25. package/dist/services/document-service/transform/relations/extract/data-ids.js.map +1 -1
  26. package/dist/services/document-service/transform/relations/extract/data-ids.mjs +12 -3
  27. package/dist/services/document-service/transform/relations/extract/data-ids.mjs.map +1 -1
  28. package/dist/services/document-service/transform/relations/transform/data-ids.d.ts +1 -1
  29. package/dist/services/document-service/transform/relations/transform/data-ids.d.ts.map +1 -1
  30. package/dist/services/document-service/transform/relations/transform/data-ids.js +12 -3
  31. package/dist/services/document-service/transform/relations/transform/data-ids.js.map +1 -1
  32. package/dist/services/document-service/transform/relations/transform/data-ids.mjs +12 -3
  33. package/dist/services/document-service/transform/relations/transform/data-ids.mjs.map +1 -1
  34. package/dist/services/document-service/transform/relations/utils/map-relation.d.ts +6 -1
  35. package/dist/services/document-service/transform/relations/utils/map-relation.d.ts.map +1 -1
  36. package/dist/services/document-service/transform/relations/utils/map-relation.js +13 -10
  37. package/dist/services/document-service/transform/relations/utils/map-relation.js.map +1 -1
  38. package/dist/services/document-service/transform/relations/utils/map-relation.mjs +13 -10
  39. package/dist/services/document-service/transform/relations/utils/map-relation.mjs.map +1 -1
  40. package/dist/services/features.d.ts.map +1 -1
  41. package/dist/services/features.js +3 -0
  42. package/dist/services/features.js.map +1 -1
  43. package/dist/services/features.mjs +3 -0
  44. package/dist/services/features.mjs.map +1 -1
  45. package/package.json +14 -15
@@ -1,17 +1,227 @@
1
1
  import { isFunction } from 'lodash/fp';
2
2
 
3
- // Lazy: only required when a cron task is actually scheduled
4
- let lazyNs;
5
- const ns = ()=>{
6
- if (!lazyNs) {
3
+ let lazyCroner;
4
+ const getCroner = ()=>{
5
+ if (!lazyCroner) {
7
6
  // eslint-disable-next-line @typescript-eslint/no-var-requires
8
- lazyNs = require('node-schedule');
7
+ lazyCroner = require('croner');
9
8
  }
10
- return lazyNs;
9
+ return lazyCroner;
10
+ };
11
+ const RECURRENCE_KEYS = [
12
+ 'date',
13
+ 'dayOfWeek',
14
+ 'hour',
15
+ 'minute',
16
+ 'month',
17
+ 'second',
18
+ 'year',
19
+ 'recurs'
20
+ ];
21
+ const isPlainObject = (value)=>typeof value === 'object' && value !== null && !(value instanceof Date);
22
+ const isRuleOptions = (value)=>isPlainObject(value) && 'rule' in value;
23
+ const isRecurrenceSpec = (value)=>isPlainObject(value) && !('rule' in value) && RECURRENCE_KEYS.some((key)=>key in value);
24
+ const toDate = (value)=>value instanceof Date ? value : new Date(value);
25
+ const toSegmentPart = (value, offset = 0)=>{
26
+ if (typeof value === 'number') {
27
+ return String(value + offset);
28
+ }
29
+ return typeof value === 'string' ? value : null;
30
+ };
31
+ const segmentToField = (segment, fallback = '*', offset = 0)=>{
32
+ if (segment == null) {
33
+ return fallback;
34
+ }
35
+ const part = toSegmentPart(segment, offset);
36
+ if (part !== null) {
37
+ return part;
38
+ }
39
+ if (Array.isArray(segment)) {
40
+ return segment.map((item)=>segmentToField(item, fallback, offset)).join(',');
41
+ }
42
+ if (isPlainObject(segment)) {
43
+ const start = toSegmentPart(segment.start ?? segment.from, offset);
44
+ const end = toSegmentPart(segment.end ?? segment.to, offset);
45
+ if (start !== null && end !== null) {
46
+ const range = `${start}-${end}`;
47
+ const step = toSegmentPart(segment.step);
48
+ return step === null ? range : `${range}/${step}`;
49
+ }
50
+ }
51
+ return fallback;
52
+ };
53
+ const recurrenceToCron = (spec)=>{
54
+ const second = segmentToField(spec.second, '0');
55
+ const minute = segmentToField(spec.minute);
56
+ const hour = segmentToField(spec.hour);
57
+ const date = segmentToField(spec.date);
58
+ const month = segmentToField(spec.month, '*', 1);
59
+ const dayOfWeek = segmentToField(spec.dayOfWeek);
60
+ const fields = `${second} ${minute} ${hour} ${date} ${month} ${dayOfWeek}`;
61
+ return spec.year == null ? fields : `${fields} ${segmentToField(spec.year)}`;
62
+ };
63
+ const toCronerOptions = ({ tz, start, end })=>{
64
+ const cronerOptions = {};
65
+ if (tz) {
66
+ cronerOptions.timezone = tz;
67
+ }
68
+ if (start != null) {
69
+ cronerOptions.startAt = toDate(start);
70
+ }
71
+ if (end != null) {
72
+ cronerOptions.stopAt = toDate(end);
73
+ }
74
+ return cronerOptions;
75
+ };
76
+ const ruleToPattern = (rule)=>{
77
+ if (typeof rule === 'number') {
78
+ return {
79
+ pattern: new Date(rule),
80
+ oneShot: true
81
+ };
82
+ }
83
+ if (rule instanceof Date) {
84
+ return {
85
+ pattern: rule,
86
+ oneShot: true
87
+ };
88
+ }
89
+ if (typeof rule === 'string') {
90
+ return {
91
+ pattern: rule,
92
+ oneShot: false
93
+ };
94
+ }
95
+ if (isRecurrenceSpec(rule)) {
96
+ return {
97
+ pattern: recurrenceToCron(rule),
98
+ oneShot: false
99
+ };
100
+ }
101
+ throw new Error('Unsupported cron rule');
102
+ };
103
+ const toCronerArgs = (options)=>{
104
+ if (typeof options === 'number') {
105
+ return {
106
+ pattern: new Date(options),
107
+ cronerOptions: {
108
+ maxRuns: 1
109
+ }
110
+ };
111
+ }
112
+ if (options instanceof Date) {
113
+ return {
114
+ pattern: options,
115
+ cronerOptions: {
116
+ maxRuns: 1
117
+ }
118
+ };
119
+ }
120
+ if (typeof options === 'string') {
121
+ return {
122
+ pattern: options,
123
+ cronerOptions: {}
124
+ };
125
+ }
126
+ if (isRecurrenceSpec(options)) {
127
+ return {
128
+ pattern: recurrenceToCron(options),
129
+ cronerOptions: toCronerOptions(options)
130
+ };
131
+ }
132
+ if (isRuleOptions(options)) {
133
+ const cronerOptions = toCronerOptions(options);
134
+ const { pattern, oneShot } = ruleToPattern(options.rule);
135
+ if (oneShot) {
136
+ cronerOptions.maxRuns = 1;
137
+ }
138
+ return {
139
+ pattern,
140
+ cronerOptions
141
+ };
142
+ }
143
+ throw new Error('Unsupported cron schedule');
11
144
  };
12
145
  const createCronService = ()=>{
13
146
  let jobsSpecs = [];
14
147
  let running = false;
148
+ const createRunner = (fn)=>{
149
+ let nextFireDate = null;
150
+ return {
151
+ async run (self) {
152
+ const fireDate = nextFireDate ?? self?.currentRun() ?? new Date();
153
+ nextFireDate = self?.nextRun(fireDate) ?? null;
154
+ await fn({
155
+ strapi
156
+ }, fireDate);
157
+ },
158
+ setNextRun (date) {
159
+ nextFireDate = date;
160
+ }
161
+ };
162
+ };
163
+ const createCronJob = (pattern, cronerOptions, fn, jobLabel)=>{
164
+ const { Cron: CronCtor } = getCroner();
165
+ const runner = createRunner(fn);
166
+ const job = new CronCtor(pattern, {
167
+ paused: !running,
168
+ // cron-parser (via node-schedule) accepted numeric-prefix stepping
169
+ // like `5/15` as `5-59/15`. Croner 10 rejects it unless this is set.
170
+ sloppyRanges: true,
171
+ ...cronerOptions,
172
+ catch (error) {
173
+ strapi.log.error(`Cron job "${jobLabel}" failed`, error);
174
+ }
175
+ }, runner.run);
176
+ runner.setNextRun(job.nextRun());
177
+ return job;
178
+ };
179
+ const attachHandle = (job, fn, jobLabel)=>{
180
+ let current = job;
181
+ let handle;
182
+ const invoke = async ()=>{
183
+ const fireDate = current.currentRun() ?? new Date();
184
+ return fn({
185
+ strapi
186
+ }, fireDate);
187
+ };
188
+ const cancel = ()=>{
189
+ current.stop();
190
+ return true;
191
+ };
192
+ const nextInvocation = ()=>current.nextRun();
193
+ const reschedule = (spec)=>{
194
+ try {
195
+ const idx = jobsSpecs.findIndex((jobSpec)=>jobSpec.job === handle);
196
+ if (idx === -1) {
197
+ return false;
198
+ }
199
+ const { pattern, cronerOptions } = toCronerArgs(spec);
200
+ const next = createCronJob(pattern, cronerOptions, fn, jobLabel);
201
+ current.stop();
202
+ current = next;
203
+ jobsSpecs[idx] = {
204
+ ...jobsSpecs[idx],
205
+ options: spec
206
+ };
207
+ return true;
208
+ } catch (error) {
209
+ strapi.log.error(`Could not reschedule cron job "${jobLabel}"`, error);
210
+ return false;
211
+ }
212
+ };
213
+ handle = new Proxy(job, {
214
+ get (_target, property) {
215
+ if (property === 'invoke') return invoke;
216
+ if (property === 'cancel') return cancel;
217
+ if (property === 'nextInvocation') return nextInvocation;
218
+ if (property === 'reschedule') return reschedule;
219
+ const value = Reflect.get(current, property, current);
220
+ return typeof value === 'function' ? value.bind(current) : value;
221
+ }
222
+ });
223
+ return handle;
224
+ };
15
225
  return {
16
226
  add (tasks = {}) {
17
227
  for (const taskExpression of Object.keys(tasks)){
@@ -20,65 +230,63 @@ const createCronService = ()=>{
20
230
  let options;
21
231
  let taskName;
22
232
  if (isFunction(taskValue)) {
23
- // don't use task name if key is the rule
24
233
  taskName = null;
25
234
  fn = taskValue.bind(tasks);
26
235
  options = taskExpression;
27
236
  } else if (isFunction(taskValue.task)) {
28
- // set task name if key is not the rule
29
237
  taskName = taskExpression;
30
238
  fn = taskValue.task.bind(taskValue);
31
239
  options = taskValue.options;
32
240
  } else {
33
241
  throw new Error(`Could not schedule a cron job for "${taskExpression}": no function found.`);
34
242
  }
35
- const fnWithStrapi = (...args)=>fn({
36
- strapi
37
- }, ...args);
38
- // const job = new Job(null, fnWithStrapi);
39
- const job = new (ns()).Job(fnWithStrapi);
40
- job.on('error', (error)=>{
41
- strapi.log.error(`Cron job "${taskName ?? taskExpression}" failed`, error);
42
- });
43
- jobsSpecs.push({
44
- job,
45
- options,
46
- name: taskName
47
- });
48
- if (running) {
49
- job.schedule(options);
243
+ const jobLabel = taskName ?? taskExpression;
244
+ try {
245
+ const { pattern, cronerOptions } = toCronerArgs(options);
246
+ const job = createCronJob(pattern, cronerOptions, fn, jobLabel);
247
+ jobsSpecs.push({
248
+ job: attachHandle(job, fn, jobLabel),
249
+ options,
250
+ name: taskName
251
+ });
252
+ } catch (error) {
253
+ strapi.log.error(`Could not schedule cron job "${jobLabel}": invalid schedule`, error);
50
254
  }
51
255
  }
52
256
  return this;
53
257
  },
54
258
  remove (name) {
55
259
  if (!name) throw new Error('You must provide a name to remove a cron job.');
56
- const matchingJobsSpecs = jobsSpecs.filter(({ name: jobSpecName }, index)=>{
57
- if (jobSpecName === name) {
58
- jobsSpecs.splice(index, 1);
59
- return true;
260
+ const remaining = [];
261
+ for (const jobSpec of jobsSpecs){
262
+ if (jobSpec.name === name) {
263
+ jobSpec.job.stop();
264
+ } else {
265
+ remaining.push(jobSpec);
60
266
  }
61
- return false;
62
- });
63
- matchingJobsSpecs.forEach(({ job })=>job.cancel());
267
+ }
268
+ jobsSpecs = remaining;
64
269
  return this;
65
270
  },
66
271
  start () {
67
- jobsSpecs.forEach(({ job, options })=>job.schedule(options));
272
+ jobsSpecs.forEach(({ job })=>job.resume());
68
273
  running = true;
69
274
  return this;
70
275
  },
71
276
  stop () {
72
- jobsSpecs.forEach(({ job })=>job.cancel());
277
+ jobsSpecs.forEach(({ job })=>job.pause());
73
278
  running = false;
74
279
  return this;
75
280
  },
76
281
  destroy () {
77
282
  this.stop();
283
+ jobsSpecs.forEach(({ job })=>job.stop());
78
284
  jobsSpecs = [];
79
285
  return this;
80
286
  },
81
- jobs: jobsSpecs
287
+ get jobs () {
288
+ return jobsSpecs;
289
+ }
82
290
  };
83
291
  };
84
292
 
@@ -1 +1 @@
1
- {"version":3,"file":"cron.mjs","sources":["../../src/services/cron.ts"],"sourcesContent":["import type { Job, Spec } from 'node-schedule';\nimport { isFunction } from 'lodash/fp';\nimport type { Core } from '@strapi/types';\n\n// Lazy: only required when a cron task is actually scheduled\nlet lazyNs: typeof import('node-schedule') | undefined;\nconst ns = (): typeof import('node-schedule') => {\n if (!lazyNs) {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n lazyNs = require('node-schedule');\n }\n return lazyNs as typeof import('node-schedule');\n};\n\ninterface JobSpec {\n job: Job;\n options: Spec;\n name: string | null;\n}\n\ntype TaskFn = ({ strapi }: { strapi: Core.Strapi }, ...args: unknown[]) => Promise<unknown>;\n\ntype Task =\n | TaskFn\n | {\n task: TaskFn;\n options: Spec;\n };\n\ninterface Tasks {\n [key: string]: Task;\n}\n\nconst createCronService = () => {\n let jobsSpecs: JobSpec[] = [];\n let running = false;\n\n return {\n add(tasks: Tasks = {}) {\n for (const taskExpression of Object.keys(tasks)) {\n const taskValue = tasks[taskExpression];\n\n let fn: TaskFn;\n let options: Spec;\n let taskName: string | null;\n if (isFunction(taskValue)) {\n // don't use task name if key is the rule\n taskName = null;\n fn = taskValue.bind(tasks);\n options = taskExpression;\n } else if (isFunction(taskValue.task)) {\n // set task name if key is not the rule\n taskName = taskExpression;\n fn = taskValue.task.bind(taskValue);\n options = taskValue.options;\n } else {\n throw new Error(\n `Could not schedule a cron job for \"${taskExpression}\": no function found.`\n );\n }\n\n const fnWithStrapi = (...args: unknown[]) => fn({ strapi }, ...args);\n\n // const job = new Job(null, fnWithStrapi);\n const job: Job = new (ns().Job)(fnWithStrapi);\n job.on('error', (error) => {\n strapi.log.error(`Cron job \"${taskName ?? taskExpression}\" failed`, error);\n });\n jobsSpecs.push({ job, options, name: taskName });\n\n if (running) {\n job.schedule(options);\n }\n }\n return this;\n },\n\n remove(name: string) {\n if (!name) throw new Error('You must provide a name to remove a cron job.');\n const matchingJobsSpecs = jobsSpecs.filter(({ name: jobSpecName }, index) => {\n if (jobSpecName === name) {\n jobsSpecs.splice(index, 1);\n return true;\n }\n return false;\n });\n matchingJobsSpecs.forEach(({ job }) => job.cancel());\n return this;\n },\n\n start() {\n jobsSpecs.forEach(({ job, options }) => job.schedule(options));\n running = true;\n return this;\n },\n\n stop() {\n jobsSpecs.forEach(({ job }) => job.cancel());\n running = false;\n return this;\n },\n\n destroy() {\n this.stop();\n jobsSpecs = [];\n return this;\n },\n jobs: jobsSpecs,\n };\n};\n\nexport default createCronService;\n"],"names":["lazyNs","ns","require","createCronService","jobsSpecs","running","add","tasks","taskExpression","Object","keys","taskValue","fn","options","taskName","isFunction","bind","task","Error","fnWithStrapi","args","strapi","job","Job","on","error","log","push","name","schedule","remove","matchingJobsSpecs","filter","jobSpecName","index","splice","forEach","cancel","start","stop","destroy","jobs"],"mappings":"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"}
1
+ {"version":3,"file":"cron.mjs","sources":["../../src/services/cron.ts"],"sourcesContent":["import { isFunction } from 'lodash/fp';\nimport type { Modules } from '@strapi/types';\nimport type { Cron } from 'croner';\n\ntype RecurrenceSpecObjLit = Modules.Cron.RecurrenceSpecObjLit;\ntype CronRuleOptions = Modules.Cron.CronRuleOptions;\ntype CronSchedule = Modules.Cron.CronSchedule;\ntype CronJob = Modules.Cron.CronJob;\ntype JobSpec = Modules.Cron.JobSpec;\ntype TaskFn = Modules.Cron.CronTaskFn;\ntype Tasks = Modules.Cron.CronTasks;\n\nlet lazyCroner: typeof import('croner') | undefined;\nconst getCroner = (): typeof import('croner') => {\n if (!lazyCroner) {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n lazyCroner = require('croner');\n }\n return lazyCroner as typeof import('croner');\n};\n\nconst RECURRENCE_KEYS = [\n 'date',\n 'dayOfWeek',\n 'hour',\n 'minute',\n 'month',\n 'second',\n 'year',\n 'recurs',\n] as const;\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !(value instanceof Date);\n\nconst isRuleOptions = (value: unknown): value is CronRuleOptions =>\n isPlainObject(value) && 'rule' in value;\n\nconst isRecurrenceSpec = (value: unknown): value is RecurrenceSpecObjLit =>\n isPlainObject(value) && !('rule' in value) && RECURRENCE_KEYS.some((key) => key in value);\n\nconst toDate = (value: Date | number | string): Date =>\n value instanceof Date ? value : new Date(value);\n\nconst toSegmentPart = (value: unknown, offset = 0): string | null => {\n if (typeof value === 'number') {\n return String(value + offset);\n }\n return typeof value === 'string' ? value : null;\n};\n\nconst segmentToField = (segment: unknown, fallback = '*', offset = 0): string => {\n if (segment == null) {\n return fallback;\n }\n\n const part = toSegmentPart(segment, offset);\n if (part !== null) {\n return part;\n }\n\n if (Array.isArray(segment)) {\n return segment.map((item) => segmentToField(item, fallback, offset)).join(',');\n }\n\n if (isPlainObject(segment)) {\n const start = toSegmentPart(segment.start ?? segment.from, offset);\n const end = toSegmentPart(segment.end ?? segment.to, offset);\n if (start !== null && end !== null) {\n const range = `${start}-${end}`;\n const step = toSegmentPart(segment.step);\n return step === null ? range : `${range}/${step}`;\n }\n }\n\n return fallback;\n};\n\nconst recurrenceToCron = (spec: RecurrenceSpecObjLit): string => {\n const second = segmentToField(spec.second, '0');\n const minute = segmentToField(spec.minute);\n const hour = segmentToField(spec.hour);\n const date = segmentToField(spec.date);\n const month = segmentToField(spec.month, '*', 1);\n const dayOfWeek = segmentToField(spec.dayOfWeek);\n const fields = `${second} ${minute} ${hour} ${date} ${month} ${dayOfWeek}`;\n\n return spec.year == null ? fields : `${fields} ${segmentToField(spec.year)}`;\n};\n\ntype ScheduleWindow = {\n tz?: string;\n start?: Date | number | string;\n end?: Date | number | string;\n};\n\nconst toCronerOptions = ({ tz, start, end }: ScheduleWindow): Record<string, unknown> => {\n const cronerOptions: Record<string, unknown> = {};\n\n if (tz) {\n cronerOptions.timezone = tz;\n }\n if (start != null) {\n cronerOptions.startAt = toDate(start);\n }\n if (end != null) {\n cronerOptions.stopAt = toDate(end);\n }\n\n return cronerOptions;\n};\n\nconst ruleToPattern = (\n rule: CronRuleOptions['rule']\n): { pattern: string | Date; oneShot: boolean } => {\n if (typeof rule === 'number') {\n return { pattern: new Date(rule), oneShot: true };\n }\n if (rule instanceof Date) {\n return { pattern: rule, oneShot: true };\n }\n if (typeof rule === 'string') {\n return { pattern: rule, oneShot: false };\n }\n if (isRecurrenceSpec(rule)) {\n return { pattern: recurrenceToCron(rule), oneShot: false };\n }\n throw new Error('Unsupported cron rule');\n};\n\nconst toCronerArgs = (\n options: CronSchedule\n): { pattern: string | Date; cronerOptions: Record<string, unknown> } => {\n if (typeof options === 'number') {\n return { pattern: new Date(options), cronerOptions: { maxRuns: 1 } };\n }\n\n if (options instanceof Date) {\n return { pattern: options, cronerOptions: { maxRuns: 1 } };\n }\n\n if (typeof options === 'string') {\n return { pattern: options, cronerOptions: {} };\n }\n\n if (isRecurrenceSpec(options)) {\n return {\n pattern: recurrenceToCron(options),\n cronerOptions: toCronerOptions(options),\n };\n }\n\n if (isRuleOptions(options)) {\n const cronerOptions = toCronerOptions(options);\n const { pattern, oneShot } = ruleToPattern(options.rule);\n if (oneShot) {\n cronerOptions.maxRuns = 1;\n }\n\n return { pattern, cronerOptions };\n }\n\n throw new Error('Unsupported cron schedule');\n};\n\nconst createCronService = () => {\n let jobsSpecs: JobSpec[] = [];\n let running = false;\n\n const createRunner = (fn: TaskFn) => {\n let nextFireDate: Date | null = null;\n\n return {\n async run(self?: Cron): Promise<void> {\n const fireDate = nextFireDate ?? self?.currentRun() ?? new Date();\n nextFireDate = self?.nextRun(fireDate) ?? null;\n await fn({ strapi }, fireDate);\n },\n setNextRun(date: Date | null) {\n nextFireDate = date;\n },\n };\n };\n\n const createCronJob = (\n pattern: string | Date,\n cronerOptions: Record<string, unknown>,\n fn: TaskFn,\n jobLabel: string\n ) => {\n const { Cron: CronCtor } = getCroner();\n const runner = createRunner(fn);\n const job = new CronCtor(\n pattern,\n {\n paused: !running,\n // cron-parser (via node-schedule) accepted numeric-prefix stepping\n // like `5/15` as `5-59/15`. Croner 10 rejects it unless this is set.\n sloppyRanges: true,\n ...cronerOptions,\n catch(error: unknown) {\n strapi.log.error(`Cron job \"${jobLabel}\" failed`, error);\n },\n },\n runner.run\n );\n runner.setNextRun(job.nextRun());\n return job;\n };\n\n const attachHandle = (job: Cron, fn: TaskFn, jobLabel: string): CronJob => {\n let current = job;\n let handle: CronJob;\n\n const invoke = async () => {\n const fireDate = current.currentRun() ?? new Date();\n return fn({ strapi }, fireDate);\n };\n\n const cancel = () => {\n current.stop();\n return true;\n };\n\n const nextInvocation = () => current.nextRun();\n\n const reschedule = (spec: CronSchedule) => {\n try {\n const idx = jobsSpecs.findIndex((jobSpec) => jobSpec.job === handle);\n if (idx === -1) {\n return false;\n }\n\n const { pattern, cronerOptions } = toCronerArgs(spec);\n const next = createCronJob(pattern, cronerOptions, fn, jobLabel);\n\n current.stop();\n current = next;\n jobsSpecs[idx] = {\n ...jobsSpecs[idx],\n options: spec,\n };\n return true;\n } catch (error) {\n strapi.log.error(`Could not reschedule cron job \"${jobLabel}\"`, error);\n return false;\n }\n };\n\n handle = new Proxy(job as CronJob, {\n get(_target, property) {\n if (property === 'invoke') return invoke;\n if (property === 'cancel') return cancel;\n if (property === 'nextInvocation') return nextInvocation;\n if (property === 'reschedule') return reschedule;\n\n const value = Reflect.get(current, property, current);\n return typeof value === 'function' ? value.bind(current) : value;\n },\n });\n\n return handle;\n };\n\n return {\n add(tasks: Tasks = {}) {\n for (const taskExpression of Object.keys(tasks)) {\n const taskValue = tasks[taskExpression];\n\n let fn: TaskFn;\n let options: CronSchedule;\n let taskName: string | null;\n if (isFunction(taskValue)) {\n taskName = null;\n fn = taskValue.bind(tasks);\n options = taskExpression;\n } else if (isFunction(taskValue.task)) {\n taskName = taskExpression;\n fn = taskValue.task.bind(taskValue);\n options = taskValue.options;\n } else {\n throw new Error(\n `Could not schedule a cron job for \"${taskExpression}\": no function found.`\n );\n }\n\n const jobLabel = taskName ?? taskExpression;\n\n try {\n const { pattern, cronerOptions } = toCronerArgs(options);\n const job = createCronJob(pattern, cronerOptions, fn, jobLabel);\n\n jobsSpecs.push({\n job: attachHandle(job, fn, jobLabel),\n options,\n name: taskName,\n });\n } catch (error) {\n strapi.log.error(`Could not schedule cron job \"${jobLabel}\": invalid schedule`, error);\n }\n }\n return this;\n },\n\n remove(name: string) {\n if (!name) throw new Error('You must provide a name to remove a cron job.');\n const remaining: JobSpec[] = [];\n for (const jobSpec of jobsSpecs) {\n if (jobSpec.name === name) {\n jobSpec.job.stop();\n } else {\n remaining.push(jobSpec);\n }\n }\n jobsSpecs = remaining;\n return this;\n },\n\n start() {\n jobsSpecs.forEach(({ job }) => job.resume());\n running = true;\n return this;\n },\n\n stop() {\n jobsSpecs.forEach(({ job }) => job.pause());\n running = false;\n return this;\n },\n\n destroy() {\n this.stop();\n jobsSpecs.forEach(({ job }) => job.stop());\n jobsSpecs = [];\n return this;\n },\n\n get jobs() {\n return jobsSpecs;\n },\n };\n};\n\nexport default createCronService;\n"],"names":["lazyCroner","getCroner","require","RECURRENCE_KEYS","isPlainObject","value","Date","isRuleOptions","isRecurrenceSpec","some","key","toDate","toSegmentPart","offset","String","segmentToField","segment","fallback","part","Array","isArray","map","item","join","start","from","end","to","range","step","recurrenceToCron","spec","second","minute","hour","date","month","dayOfWeek","fields","year","toCronerOptions","tz","cronerOptions","timezone","startAt","stopAt","ruleToPattern","rule","pattern","oneShot","Error","toCronerArgs","options","maxRuns","createCronService","jobsSpecs","running","createRunner","fn","nextFireDate","run","self","fireDate","currentRun","nextRun","strapi","setNextRun","createCronJob","jobLabel","Cron","CronCtor","runner","job","paused","sloppyRanges","catch","error","log","attachHandle","current","handle","invoke","cancel","stop","nextInvocation","reschedule","idx","findIndex","jobSpec","next","Proxy","get","_target","property","Reflect","bind","add","tasks","taskExpression","Object","keys","taskValue","taskName","isFunction","task","push","name","remove","remaining","forEach","resume","pause","destroy","jobs"],"mappings":"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"}
@@ -6,7 +6,7 @@ interface Options {
6
6
  status?: 'draft' | 'published';
7
7
  }
8
8
  /**
9
- * Iterate over all relations of a data object and extract all relational document ids.
9
+ * Iterate over all relations and media of a data object and extract their document ids.
10
10
  * Those will later be transformed to entity ids.
11
11
  */
12
12
  declare const extractDataIds: (idMap: IdMap, data: Record<string, any>, source: Options) => Promise<import("@strapi/utils/dist/types").Data>;
@@ -1 +1 @@
1
- {"version":3,"file":"data-ids.d.ts","sourceRoot":"","sources":["../../../../../../src/services/document-service/transform/relations/extract/data-ids.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AAEzC,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AASrC,UAAU,OAAO;IACf,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,MAAM,CAAC,EAAE,OAAO,GAAG,WAAW,CAAC;CAChC;AA8BD;;;GAGG;AACH,QAAA,MAAM,cAAc,GAAI,OAAO,KAAK,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,QAAQ,OAAO,qDA8C/E,CAAC;AAEF,OAAO,EAAE,cAAc,EAAE,CAAC"}
1
+ {"version":3,"file":"data-ids.d.ts","sourceRoot":"","sources":["../../../../../../src/services/document-service/transform/relations/extract/data-ids.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AAEzC,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAUrC,UAAU,OAAO;IACf,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,MAAM,CAAC,EAAE,OAAO,GAAG,WAAW,CAAC;CAChC;AA8BD;;;GAGG;AACH,QAAA,MAAM,cAAc,GAAI,OAAO,KAAK,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,QAAQ,OAAO,qDAyD/E,CAAC;AAEF,OAAO,EAAE,cAAc,EAAE,CAAC"}
@@ -8,6 +8,7 @@ var mapRelation = require('../utils/map-relation.js');
8
8
  var xtoOne = require('../utils/xto-one.js');
9
9
 
10
10
  const { isPolymorphic } = strapiUtils.relations;
11
+ const MEDIA_UID = 'plugin::upload.file';
11
12
  /**
12
13
  * Load a relation documentId into the idMap.
13
14
  */ const addRelationDocId = fp.curry((idMap, source, targetUid, relation)=>{
@@ -31,7 +32,7 @@ const { isPolymorphic } = strapiUtils.relations;
31
32
  });
32
33
  });
33
34
  /**
34
- * Iterate over all relations of a data object and extract all relational document ids.
35
+ * Iterate over all relations and media of a data object and extract their document ids.
35
36
  * Those will later be transformed to entity ids.
36
37
  */ const extractDataIds = (idMap, data, source)=>{
37
38
  return mapRelation.traverseEntityRelations(async ({ attribute, value })=>{
@@ -48,7 +49,14 @@ const { isPolymorphic } = strapiUtils.relations;
48
49
  }
49
50
  // Regular relations will always target the same target
50
51
  // if its a polymorphic relation we need to get it from the data itself
51
- const targetUid = isPolymorphicRelation ? relation.__type : attribute.target;
52
+ let targetUid;
53
+ if (attribute.type === 'media') {
54
+ targetUid = MEDIA_UID;
55
+ } else if (isPolymorphicRelation) {
56
+ targetUid = relation.__type;
57
+ } else {
58
+ targetUid = attribute.target;
59
+ }
52
60
  addDocId(targetUid, relation);
53
61
  // Handle positional arguments
54
62
  const position = relation.position;
@@ -75,7 +83,8 @@ const { isPolymorphic } = strapiUtils.relations;
75
83
  }, normalizedValue);
76
84
  }, {
77
85
  schema: strapi.getModel(source.uid),
78
- getModel: strapi.getModel.bind(strapi)
86
+ getModel: strapi.getModel.bind(strapi),
87
+ includeMedia: true
79
88
  }, data);
80
89
  };
81
90
 
@@ -1 +1 @@
1
- {"version":3,"file":"data-ids.js","sources":["../../../../../../src/services/document-service/transform/relations/extract/data-ids.ts"],"sourcesContent":["import { curry } from 'lodash/fp';\n\nimport type { UID } from '@strapi/types';\nimport { relations } from '@strapi/utils';\nimport { IdMap } from '../../id-map';\nimport { getRelationTargetLocale } from '../utils/i18n';\nimport { getRelationTargetStatus } from '../utils/dp';\nimport { mapRelation, traverseEntityRelations } from '../utils/map-relation';\nimport { normalizeXToOneRelationValue } from '../utils/xto-one';\nimport { LongHandDocument } from '../utils/types';\n\nconst { isPolymorphic } = relations;\n\ninterface Options {\n uid: UID.Schema;\n locale?: string | null;\n status?: 'draft' | 'published';\n}\n\n/**\n * Load a relation documentId into the idMap.\n */\nconst addRelationDocId = curry(\n (idMap: IdMap, source: Options, targetUid: UID.Schema, relation: LongHandDocument) => {\n const targetLocale = getRelationTargetLocale(relation, {\n targetUid,\n sourceUid: source.uid,\n sourceLocale: source.locale,\n });\n\n const targetStatus = getRelationTargetStatus(relation, {\n targetUid,\n sourceUid: source.uid,\n sourceStatus: source.status,\n });\n\n targetStatus.forEach((status) => {\n idMap.add({\n uid: targetUid,\n documentId: relation.documentId,\n locale: targetLocale,\n status,\n });\n });\n }\n);\n\n/**\n * Iterate over all relations of a data object and extract all relational document ids.\n * Those will later be transformed to entity ids.\n */\nconst extractDataIds = (idMap: IdMap, data: Record<string, any>, source: Options) => {\n return traverseEntityRelations(\n async ({ attribute, value }) => {\n if (!attribute) {\n return;\n }\n const isPolymorphicRelation = isPolymorphic(attribute);\n const addDocId = addRelationDocId(idMap, source);\n\n // Skip looking up entries we're about to discard.\n const normalizedValue = normalizeXToOneRelationValue(attribute, value as any);\n\n return mapRelation((relation) => {\n if (!relation || !relation.documentId) {\n return relation;\n }\n\n // Regular relations will always target the same target\n // if its a polymorphic relation we need to get it from the data itself\n const targetUid = isPolymorphicRelation ? relation.__type : attribute.target;\n\n addDocId(targetUid, relation);\n\n // Handle positional arguments\n const position = relation.position;\n\n // The positional relation target uid can be different for polymorphic relations\n let positionTargetUid = targetUid;\n if (isPolymorphicRelation && position?.__type) {\n positionTargetUid = position.__type;\n }\n\n if (position?.before) {\n addDocId(positionTargetUid, { ...relation, ...position, documentId: position.before });\n }\n\n if (position?.after) {\n addDocId(positionTargetUid, { ...relation, ...position, documentId: position.after });\n }\n\n return relation;\n }, normalizedValue as any);\n },\n { schema: strapi.getModel(source.uid), getModel: strapi.getModel.bind(strapi) },\n data\n );\n};\n\nexport { extractDataIds };\n"],"names":["isPolymorphic","relations","addRelationDocId","curry","idMap","source","targetUid","relation","targetLocale","getRelationTargetLocale","sourceUid","uid","sourceLocale","locale","targetStatus","getRelationTargetStatus","sourceStatus","status","forEach","add","documentId","extractDataIds","data","traverseEntityRelations","attribute","value","isPolymorphicRelation","addDocId","normalizedValue","normalizeXToOneRelationValue","mapRelation","__type","target","position","positionTargetUid","before","after","schema","strapi","getModel","bind"],"mappings":"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"}
1
+ {"version":3,"file":"data-ids.js","sources":["../../../../../../src/services/document-service/transform/relations/extract/data-ids.ts"],"sourcesContent":["import { curry } from 'lodash/fp';\n\nimport type { UID } from '@strapi/types';\nimport { relations } from '@strapi/utils';\nimport { IdMap } from '../../id-map';\nimport { getRelationTargetLocale } from '../utils/i18n';\nimport { getRelationTargetStatus } from '../utils/dp';\nimport { mapRelation, traverseEntityRelations } from '../utils/map-relation';\nimport { normalizeXToOneRelationValue } from '../utils/xto-one';\nimport { LongHandDocument } from '../utils/types';\n\nconst { isPolymorphic } = relations;\nconst MEDIA_UID = 'plugin::upload.file' as UID.ContentType;\n\ninterface Options {\n uid: UID.Schema;\n locale?: string | null;\n status?: 'draft' | 'published';\n}\n\n/**\n * Load a relation documentId into the idMap.\n */\nconst addRelationDocId = curry(\n (idMap: IdMap, source: Options, targetUid: UID.Schema, relation: LongHandDocument) => {\n const targetLocale = getRelationTargetLocale(relation, {\n targetUid,\n sourceUid: source.uid,\n sourceLocale: source.locale,\n });\n\n const targetStatus = getRelationTargetStatus(relation, {\n targetUid,\n sourceUid: source.uid,\n sourceStatus: source.status,\n });\n\n targetStatus.forEach((status) => {\n idMap.add({\n uid: targetUid,\n documentId: relation.documentId,\n locale: targetLocale,\n status,\n });\n });\n }\n);\n\n/**\n * Iterate over all relations and media of a data object and extract their document ids.\n * Those will later be transformed to entity ids.\n */\nconst extractDataIds = (idMap: IdMap, data: Record<string, any>, source: Options) => {\n return traverseEntityRelations(\n async ({ attribute, value }) => {\n if (!attribute) {\n return;\n }\n const isPolymorphicRelation = isPolymorphic(attribute);\n const addDocId = addRelationDocId(idMap, source);\n\n // Skip looking up entries we're about to discard.\n const normalizedValue = normalizeXToOneRelationValue(attribute, value as any);\n\n return mapRelation((relation) => {\n if (!relation || !relation.documentId) {\n return relation;\n }\n\n // Regular relations will always target the same target\n // if its a polymorphic relation we need to get it from the data itself\n let targetUid: UID.Schema;\n if (attribute.type === 'media') {\n targetUid = MEDIA_UID;\n } else if (isPolymorphicRelation) {\n targetUid = relation.__type;\n } else {\n targetUid = attribute.target;\n }\n\n addDocId(targetUid, relation);\n\n // Handle positional arguments\n const position = relation.position;\n\n // The positional relation target uid can be different for polymorphic relations\n let positionTargetUid = targetUid;\n if (isPolymorphicRelation && position?.__type) {\n positionTargetUid = position.__type;\n }\n\n if (position?.before) {\n addDocId(positionTargetUid, { ...relation, ...position, documentId: position.before });\n }\n\n if (position?.after) {\n addDocId(positionTargetUid, { ...relation, ...position, documentId: position.after });\n }\n\n return relation;\n }, normalizedValue as any);\n },\n {\n schema: strapi.getModel(source.uid),\n getModel: strapi.getModel.bind(strapi),\n includeMedia: true,\n },\n data\n );\n};\n\nexport { extractDataIds };\n"],"names":["isPolymorphic","relations","MEDIA_UID","addRelationDocId","curry","idMap","source","targetUid","relation","targetLocale","getRelationTargetLocale","sourceUid","uid","sourceLocale","locale","targetStatus","getRelationTargetStatus","sourceStatus","status","forEach","add","documentId","extractDataIds","data","traverseEntityRelations","attribute","value","isPolymorphicRelation","addDocId","normalizedValue","normalizeXToOneRelationValue","mapRelation","type","__type","target","position","positionTargetUid","before","after","schema","strapi","getModel","bind","includeMedia"],"mappings":"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"}
@@ -6,6 +6,7 @@ import { traverseEntityRelations as traverseEntityRelationsCurried, mapRelation
6
6
  import { normalizeXToOneRelationValue } from '../utils/xto-one.mjs';
7
7
 
8
8
  const { isPolymorphic } = relations;
9
+ const MEDIA_UID = 'plugin::upload.file';
9
10
  /**
10
11
  * Load a relation documentId into the idMap.
11
12
  */ const addRelationDocId = curry((idMap, source, targetUid, relation)=>{
@@ -29,7 +30,7 @@ const { isPolymorphic } = relations;
29
30
  });
30
31
  });
31
32
  /**
32
- * Iterate over all relations of a data object and extract all relational document ids.
33
+ * Iterate over all relations and media of a data object and extract their document ids.
33
34
  * Those will later be transformed to entity ids.
34
35
  */ const extractDataIds = (idMap, data, source)=>{
35
36
  return traverseEntityRelationsCurried(async ({ attribute, value })=>{
@@ -46,7 +47,14 @@ const { isPolymorphic } = relations;
46
47
  }
47
48
  // Regular relations will always target the same target
48
49
  // if its a polymorphic relation we need to get it from the data itself
49
- const targetUid = isPolymorphicRelation ? relation.__type : attribute.target;
50
+ let targetUid;
51
+ if (attribute.type === 'media') {
52
+ targetUid = MEDIA_UID;
53
+ } else if (isPolymorphicRelation) {
54
+ targetUid = relation.__type;
55
+ } else {
56
+ targetUid = attribute.target;
57
+ }
50
58
  addDocId(targetUid, relation);
51
59
  // Handle positional arguments
52
60
  const position = relation.position;
@@ -73,7 +81,8 @@ const { isPolymorphic } = relations;
73
81
  }, normalizedValue);
74
82
  }, {
75
83
  schema: strapi.getModel(source.uid),
76
- getModel: strapi.getModel.bind(strapi)
84
+ getModel: strapi.getModel.bind(strapi),
85
+ includeMedia: true
77
86
  }, data);
78
87
  };
79
88
 
@@ -1 +1 @@
1
- {"version":3,"file":"data-ids.mjs","sources":["../../../../../../src/services/document-service/transform/relations/extract/data-ids.ts"],"sourcesContent":["import { curry } from 'lodash/fp';\n\nimport type { UID } from '@strapi/types';\nimport { relations } from '@strapi/utils';\nimport { IdMap } from '../../id-map';\nimport { getRelationTargetLocale } from '../utils/i18n';\nimport { getRelationTargetStatus } from '../utils/dp';\nimport { mapRelation, traverseEntityRelations } from '../utils/map-relation';\nimport { normalizeXToOneRelationValue } from '../utils/xto-one';\nimport { LongHandDocument } from '../utils/types';\n\nconst { isPolymorphic } = relations;\n\ninterface Options {\n uid: UID.Schema;\n locale?: string | null;\n status?: 'draft' | 'published';\n}\n\n/**\n * Load a relation documentId into the idMap.\n */\nconst addRelationDocId = curry(\n (idMap: IdMap, source: Options, targetUid: UID.Schema, relation: LongHandDocument) => {\n const targetLocale = getRelationTargetLocale(relation, {\n targetUid,\n sourceUid: source.uid,\n sourceLocale: source.locale,\n });\n\n const targetStatus = getRelationTargetStatus(relation, {\n targetUid,\n sourceUid: source.uid,\n sourceStatus: source.status,\n });\n\n targetStatus.forEach((status) => {\n idMap.add({\n uid: targetUid,\n documentId: relation.documentId,\n locale: targetLocale,\n status,\n });\n });\n }\n);\n\n/**\n * Iterate over all relations of a data object and extract all relational document ids.\n * Those will later be transformed to entity ids.\n */\nconst extractDataIds = (idMap: IdMap, data: Record<string, any>, source: Options) => {\n return traverseEntityRelations(\n async ({ attribute, value }) => {\n if (!attribute) {\n return;\n }\n const isPolymorphicRelation = isPolymorphic(attribute);\n const addDocId = addRelationDocId(idMap, source);\n\n // Skip looking up entries we're about to discard.\n const normalizedValue = normalizeXToOneRelationValue(attribute, value as any);\n\n return mapRelation((relation) => {\n if (!relation || !relation.documentId) {\n return relation;\n }\n\n // Regular relations will always target the same target\n // if its a polymorphic relation we need to get it from the data itself\n const targetUid = isPolymorphicRelation ? relation.__type : attribute.target;\n\n addDocId(targetUid, relation);\n\n // Handle positional arguments\n const position = relation.position;\n\n // The positional relation target uid can be different for polymorphic relations\n let positionTargetUid = targetUid;\n if (isPolymorphicRelation && position?.__type) {\n positionTargetUid = position.__type;\n }\n\n if (position?.before) {\n addDocId(positionTargetUid, { ...relation, ...position, documentId: position.before });\n }\n\n if (position?.after) {\n addDocId(positionTargetUid, { ...relation, ...position, documentId: position.after });\n }\n\n return relation;\n }, normalizedValue as any);\n },\n { schema: strapi.getModel(source.uid), getModel: strapi.getModel.bind(strapi) },\n data\n );\n};\n\nexport { extractDataIds };\n"],"names":["isPolymorphic","relations","addRelationDocId","curry","idMap","source","targetUid","relation","targetLocale","getRelationTargetLocale","sourceUid","uid","sourceLocale","locale","targetStatus","getRelationTargetStatus","sourceStatus","status","forEach","add","documentId","extractDataIds","data","traverseEntityRelations","attribute","value","isPolymorphicRelation","addDocId","normalizedValue","normalizeXToOneRelationValue","mapRelation","__type","target","position","positionTargetUid","before","after","schema","strapi","getModel","bind"],"mappings":"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"}
1
+ {"version":3,"file":"data-ids.mjs","sources":["../../../../../../src/services/document-service/transform/relations/extract/data-ids.ts"],"sourcesContent":["import { curry } from 'lodash/fp';\n\nimport type { UID } from '@strapi/types';\nimport { relations } from '@strapi/utils';\nimport { IdMap } from '../../id-map';\nimport { getRelationTargetLocale } from '../utils/i18n';\nimport { getRelationTargetStatus } from '../utils/dp';\nimport { mapRelation, traverseEntityRelations } from '../utils/map-relation';\nimport { normalizeXToOneRelationValue } from '../utils/xto-one';\nimport { LongHandDocument } from '../utils/types';\n\nconst { isPolymorphic } = relations;\nconst MEDIA_UID = 'plugin::upload.file' as UID.ContentType;\n\ninterface Options {\n uid: UID.Schema;\n locale?: string | null;\n status?: 'draft' | 'published';\n}\n\n/**\n * Load a relation documentId into the idMap.\n */\nconst addRelationDocId = curry(\n (idMap: IdMap, source: Options, targetUid: UID.Schema, relation: LongHandDocument) => {\n const targetLocale = getRelationTargetLocale(relation, {\n targetUid,\n sourceUid: source.uid,\n sourceLocale: source.locale,\n });\n\n const targetStatus = getRelationTargetStatus(relation, {\n targetUid,\n sourceUid: source.uid,\n sourceStatus: source.status,\n });\n\n targetStatus.forEach((status) => {\n idMap.add({\n uid: targetUid,\n documentId: relation.documentId,\n locale: targetLocale,\n status,\n });\n });\n }\n);\n\n/**\n * Iterate over all relations and media of a data object and extract their document ids.\n * Those will later be transformed to entity ids.\n */\nconst extractDataIds = (idMap: IdMap, data: Record<string, any>, source: Options) => {\n return traverseEntityRelations(\n async ({ attribute, value }) => {\n if (!attribute) {\n return;\n }\n const isPolymorphicRelation = isPolymorphic(attribute);\n const addDocId = addRelationDocId(idMap, source);\n\n // Skip looking up entries we're about to discard.\n const normalizedValue = normalizeXToOneRelationValue(attribute, value as any);\n\n return mapRelation((relation) => {\n if (!relation || !relation.documentId) {\n return relation;\n }\n\n // Regular relations will always target the same target\n // if its a polymorphic relation we need to get it from the data itself\n let targetUid: UID.Schema;\n if (attribute.type === 'media') {\n targetUid = MEDIA_UID;\n } else if (isPolymorphicRelation) {\n targetUid = relation.__type;\n } else {\n targetUid = attribute.target;\n }\n\n addDocId(targetUid, relation);\n\n // Handle positional arguments\n const position = relation.position;\n\n // The positional relation target uid can be different for polymorphic relations\n let positionTargetUid = targetUid;\n if (isPolymorphicRelation && position?.__type) {\n positionTargetUid = position.__type;\n }\n\n if (position?.before) {\n addDocId(positionTargetUid, { ...relation, ...position, documentId: position.before });\n }\n\n if (position?.after) {\n addDocId(positionTargetUid, { ...relation, ...position, documentId: position.after });\n }\n\n return relation;\n }, normalizedValue as any);\n },\n {\n schema: strapi.getModel(source.uid),\n getModel: strapi.getModel.bind(strapi),\n includeMedia: true,\n },\n data\n );\n};\n\nexport { extractDataIds };\n"],"names":["isPolymorphic","relations","MEDIA_UID","addRelationDocId","curry","idMap","source","targetUid","relation","targetLocale","getRelationTargetLocale","sourceUid","uid","sourceLocale","locale","targetStatus","getRelationTargetStatus","sourceStatus","status","forEach","add","documentId","extractDataIds","data","traverseEntityRelations","attribute","value","isPolymorphicRelation","addDocId","normalizedValue","normalizeXToOneRelationValue","mapRelation","type","__type","target","position","positionTargetUid","before","after","schema","strapi","getModel","bind","includeMedia"],"mappings":"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"}
@@ -7,7 +7,7 @@ interface Options {
7
7
  allowMissingId?: boolean;
8
8
  }
9
9
  /**
10
- * Iterate over all relations of a data object and transform all relational document ids to entity ids.
10
+ * Iterate over all relations and media of a data object and transform document ids to entity ids.
11
11
  */
12
12
  declare const transformDataIdsVisitor: (idMap: IdMap, data: Record<string, any>, source: Options) => Promise<import("@strapi/utils/dist/types").Data>;
13
13
  export { transformDataIdsVisitor };
@@ -1 +1 @@
1
- {"version":3,"file":"data-ids.d.ts","sourceRoot":"","sources":["../../../../../../src/services/document-service/transform/relations/transform/data-ids.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AAIzC,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAQrC,UAAU,OAAO;IACf,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,MAAM,CAAC,EAAE,OAAO,GAAG,WAAW,CAAC;IAC/B,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AA+CD;;GAEG;AACH,QAAA,MAAM,uBAAuB,GAAI,OAAO,KAAK,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,QAAQ,OAAO,qDAiExF,CAAC;AAEF,OAAO,EAAE,uBAAuB,EAAE,CAAC"}
1
+ {"version":3,"file":"data-ids.d.ts","sourceRoot":"","sources":["../../../../../../src/services/document-service/transform/relations/transform/data-ids.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AAIzC,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AASrC,UAAU,OAAO;IACf,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,MAAM,CAAC,EAAE,OAAO,GAAG,WAAW,CAAC;IAC/B,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AA+CD;;GAEG;AACH,QAAA,MAAM,uBAAuB,GAAI,OAAO,KAAK,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,QAAQ,OAAO,qDA4ExF,CAAC;AAEF,OAAO,EAAE,uBAAuB,EAAE,CAAC"}
@@ -8,6 +8,7 @@ var mapRelation = require('../utils/map-relation.js');
8
8
  var xtoOne = require('../utils/xto-one.js');
9
9
 
10
10
  const { isPolymorphic } = strapiUtils.relations;
11
+ const MEDIA_UID = 'plugin::upload.file';
11
12
  /**
12
13
  * Get the entry ids for a given documentId.
13
14
  */ const getRelationIds = fp.curry((idMap, source, targetUid, relation)=>{
@@ -42,7 +43,7 @@ const { isPolymorphic } = strapiUtils.relations;
42
43
  return ids;
43
44
  });
44
45
  /**
45
- * Iterate over all relations of a data object and transform all relational document ids to entity ids.
46
+ * Iterate over all relations and media of a data object and transform document ids to entity ids.
46
47
  */ const transformDataIdsVisitor = (idMap, data, source)=>{
47
48
  return mapRelation.traverseEntityRelations(async ({ key, value, attribute }, { set })=>{
48
49
  if (!attribute) {
@@ -59,7 +60,14 @@ const { isPolymorphic } = strapiUtils.relations;
59
60
  }
60
61
  // Find relational attributes, and return the document ids
61
62
  // if its a polymorphic relation we need to get it from the data itself
62
- const targetUid = isPolymorphicRelation ? relation.__type : attribute.target;
63
+ let targetUid;
64
+ if (attribute.type === 'media') {
65
+ targetUid = MEDIA_UID;
66
+ } else if (isPolymorphicRelation) {
67
+ targetUid = relation.__type;
68
+ } else {
69
+ targetUid = attribute.target;
70
+ }
63
71
  const ids = getIds(targetUid, relation);
64
72
  // Handle positional arguments
65
73
  const position = {
@@ -105,7 +113,8 @@ const { isPolymorphic } = strapiUtils.relations;
105
113
  set(key, newRelation);
106
114
  }, {
107
115
  schema: strapi.getModel(source.uid),
108
- getModel: strapi.getModel.bind(strapi)
116
+ getModel: strapi.getModel.bind(strapi),
117
+ includeMedia: true
109
118
  }, data);
110
119
  };
111
120