@jrmc/adonis-attachment 6.0.0-alpha.0 → 6.0.0-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (199) hide show
  1. package/build/commands/make/attachment_v5_migration.d.ts.map +1 -1
  2. package/build/commands/make/attachment_v5_migration.js +6 -3
  3. package/build/commands/make/attachment_v5_migration.js.map +1 -1
  4. package/build/commands/make/attachments_table.d.ts.map +1 -1
  5. package/build/commands/make/attachments_table.js +8 -2
  6. package/build/commands/make/attachments_table.js.map +1 -1
  7. package/build/index.d.ts +23 -22
  8. package/build/index.d.ts.map +1 -1
  9. package/build/index.js +15 -14
  10. package/build/index.js.map +1 -1
  11. package/build/providers/attachment_provider.d.ts.map +1 -1
  12. package/build/providers/attachment_provider.js +16 -0
  13. package/build/providers/attachment_provider.js.map +1 -1
  14. package/build/src/core/attachment.d.ts +37 -2
  15. package/build/src/core/attachment.d.ts.map +1 -1
  16. package/build/src/core/attachment.js +108 -5
  17. package/build/src/core/attachment.js.map +1 -1
  18. package/build/src/core/attachment_options.d.ts +32 -0
  19. package/build/src/core/attachment_options.d.ts.map +1 -0
  20. package/build/src/core/attachment_options.js +24 -0
  21. package/build/src/core/attachment_options.js.map +1 -0
  22. package/build/src/core/attachment_service.d.ts +7 -1
  23. package/build/src/core/attachment_service.d.ts.map +1 -1
  24. package/build/src/core/attachment_service.js +50 -4
  25. package/build/src/core/attachment_service.js.map +1 -1
  26. package/build/src/core/index.d.ts +2 -1
  27. package/build/src/core/index.d.ts.map +1 -1
  28. package/build/src/core/index.js +2 -1
  29. package/build/src/core/index.js.map +1 -1
  30. package/build/src/define_config.d.ts +17 -0
  31. package/build/src/define_config.d.ts.map +1 -1
  32. package/build/src/define_config.js +9 -0
  33. package/build/src/define_config.js.map +1 -1
  34. package/build/src/integrations/lucid/column/attachment_column.d.ts +18 -0
  35. package/build/src/integrations/lucid/column/attachment_column.d.ts.map +1 -0
  36. package/build/src/integrations/lucid/{attachment_column.js → column/attachment_column.js} +26 -13
  37. package/build/src/integrations/lucid/column/attachment_column.js.map +1 -0
  38. package/build/src/integrations/lucid/index.d.ts +16 -12
  39. package/build/src/integrations/lucid/index.d.ts.map +1 -1
  40. package/build/src/integrations/lucid/index.js +16 -12
  41. package/build/src/integrations/lucid/index.js.map +1 -1
  42. package/build/src/integrations/lucid/migrations/legacy/legacy_attachment_migration_stub.d.ts +20 -0
  43. package/build/src/integrations/lucid/migrations/legacy/legacy_attachment_migration_stub.d.ts.map +1 -0
  44. package/build/src/integrations/lucid/migrations/legacy/legacy_attachment_migration_stub.js +18 -0
  45. package/build/src/integrations/lucid/migrations/legacy/legacy_attachment_migration_stub.js.map +1 -0
  46. package/build/src/integrations/lucid/{migrate_legacy_attachment.d.ts → migrations/legacy/migrate_legacy_attachment.d.ts} +25 -9
  47. package/build/src/integrations/lucid/migrations/legacy/migrate_legacy_attachment.d.ts.map +1 -0
  48. package/build/src/integrations/lucid/migrations/legacy/migrate_legacy_attachment.js +94 -0
  49. package/build/src/integrations/lucid/migrations/legacy/migrate_legacy_attachment.js.map +1 -0
  50. package/build/src/integrations/lucid/{migrate_legacy_attachment_records.d.ts → migrations/legacy/migrate_legacy_attachment_records.d.ts} +3 -3
  51. package/build/src/integrations/lucid/migrations/legacy/migrate_legacy_attachment_records.d.ts.map +1 -0
  52. package/build/src/integrations/lucid/{migrate_legacy_attachment_records.js → migrations/legacy/migrate_legacy_attachment_records.js} +7 -6
  53. package/build/src/integrations/lucid/migrations/legacy/migrate_legacy_attachment_records.js.map +1 -0
  54. package/build/src/integrations/lucid/models/attachment_link_model.d.ts +30 -0
  55. package/build/src/integrations/lucid/models/attachment_link_model.d.ts.map +1 -0
  56. package/build/src/integrations/lucid/models/attachment_link_model.js +58 -0
  57. package/build/src/integrations/lucid/models/attachment_link_model.js.map +1 -0
  58. package/build/src/integrations/lucid/{attachment_model.d.ts → models/attachment_model.d.ts} +2 -6
  59. package/build/src/integrations/lucid/models/attachment_model.d.ts.map +1 -0
  60. package/build/src/integrations/lucid/{attachment_model.js → models/attachment_model.js} +1 -13
  61. package/build/src/integrations/lucid/models/attachment_model.js.map +1 -0
  62. package/build/src/integrations/lucid/persistence/lucid_attachment_lifecycle_service.d.ts +34 -0
  63. package/build/src/integrations/lucid/persistence/lucid_attachment_lifecycle_service.d.ts.map +1 -0
  64. package/build/src/integrations/lucid/persistence/lucid_attachment_lifecycle_service.js +195 -0
  65. package/build/src/integrations/lucid/persistence/lucid_attachment_lifecycle_service.js.map +1 -0
  66. package/build/src/integrations/lucid/{lucid_attachment_repository.d.ts → persistence/lucid_attachment_repository.d.ts} +3 -3
  67. package/build/src/integrations/lucid/persistence/lucid_attachment_repository.d.ts.map +1 -0
  68. package/build/src/integrations/lucid/{lucid_attachment_repository.js → persistence/lucid_attachment_repository.js} +1 -1
  69. package/build/src/integrations/lucid/persistence/lucid_attachment_repository.js.map +1 -0
  70. package/build/src/integrations/lucid/persistence/lucid_attachment_store.d.ts +48 -0
  71. package/build/src/integrations/lucid/persistence/lucid_attachment_store.d.ts.map +1 -0
  72. package/build/src/integrations/lucid/persistence/lucid_attachment_store.js +224 -0
  73. package/build/src/integrations/lucid/persistence/lucid_attachment_store.js.map +1 -0
  74. package/build/src/integrations/lucid/{lucid_variant_generation_service.d.ts → persistence/lucid_variant_generation_service.d.ts} +3 -3
  75. package/build/src/integrations/lucid/persistence/lucid_variant_generation_service.d.ts.map +1 -0
  76. package/build/src/integrations/lucid/persistence/lucid_variant_generation_service.js.map +1 -0
  77. package/build/src/integrations/lucid/{attachment_owner.d.ts → relations/attachment_owner.d.ts} +2 -1
  78. package/build/src/integrations/lucid/relations/attachment_owner.d.ts.map +1 -0
  79. package/build/src/integrations/lucid/relations/attachment_owner.js.map +1 -0
  80. package/build/src/integrations/lucid/relations/attachment_relation.d.ts +71 -0
  81. package/build/src/integrations/lucid/relations/attachment_relation.d.ts.map +1 -0
  82. package/build/src/integrations/lucid/relations/attachment_relation.js +266 -0
  83. package/build/src/integrations/lucid/relations/attachment_relation.js.map +1 -0
  84. package/build/src/integrations/lucid/schema/attachment_schema_service.d.ts +24 -0
  85. package/build/src/integrations/lucid/schema/attachment_schema_service.d.ts.map +1 -0
  86. package/build/src/integrations/lucid/schema/attachment_schema_service.js +68 -0
  87. package/build/src/integrations/lucid/schema/attachment_schema_service.js.map +1 -0
  88. package/build/src/integrations/lucid/schema/attachment_table_names.d.ts +15 -0
  89. package/build/src/integrations/lucid/schema/attachment_table_names.d.ts.map +1 -0
  90. package/build/src/integrations/lucid/schema/attachment_table_names.js +20 -0
  91. package/build/src/integrations/lucid/schema/attachment_table_names.js.map +1 -0
  92. package/build/src/integrations/lucid/schema/attachments_table_stub.d.ts.map +1 -0
  93. package/build/src/integrations/lucid/{attachments_table_stub.js → schema/attachments_table_stub.js} +2 -4
  94. package/build/src/integrations/lucid/schema/attachments_table_stub.js.map +1 -0
  95. package/build/src/integrations/lucid/schema/configure_lucid_attachment_tables.d.ts +12 -0
  96. package/build/src/integrations/lucid/schema/configure_lucid_attachment_tables.d.ts.map +1 -0
  97. package/build/src/integrations/lucid/schema/configure_lucid_attachment_tables.js +19 -0
  98. package/build/src/integrations/lucid/schema/configure_lucid_attachment_tables.js.map +1 -0
  99. package/build/src/sources/attachment_manager.d.ts +14 -12
  100. package/build/src/sources/attachment_manager.d.ts.map +1 -1
  101. package/build/src/sources/attachment_manager.js +14 -6
  102. package/build/src/sources/attachment_manager.js.map +1 -1
  103. package/build/stubs/migrations/attachments_table.stub +7 -24
  104. package/build/{src/integrations/lucid/render_legacy_attachment_migration_script.js → stubs/migrations/legacy_attachment_migration.stub} +13 -15
  105. package/build/tests/attachment_manager.spec.js +21 -18
  106. package/build/tests/attachment_manager.spec.js.map +1 -1
  107. package/build/tests/attachment_manager_service.spec.js +2 -2
  108. package/build/tests/attachment_manager_service.spec.js.map +1 -1
  109. package/build/tests/attachment_options.spec.d.ts +2 -0
  110. package/build/tests/attachment_options.spec.d.ts.map +1 -0
  111. package/build/tests/attachment_options.spec.js +31 -0
  112. package/build/tests/attachment_options.spec.js.map +1 -0
  113. package/build/tests/attachment_provider.spec.js +30 -1
  114. package/build/tests/attachment_provider.spec.js.map +1 -1
  115. package/build/tests/{create_legacy_attachment_migration_script.spec.d.ts → attachment_schema_service.spec.d.ts} +1 -1
  116. package/build/tests/attachment_schema_service.spec.d.ts.map +1 -0
  117. package/build/tests/attachment_schema_service.spec.js +38 -0
  118. package/build/tests/attachment_schema_service.spec.js.map +1 -0
  119. package/build/tests/attachment_service.spec.js +55 -0
  120. package/build/tests/attachment_service.spec.js.map +1 -1
  121. package/build/tests/attachment_table_names.spec.d.ts +8 -0
  122. package/build/tests/attachment_table_names.spec.d.ts.map +1 -0
  123. package/build/tests/attachment_table_names.spec.js +36 -0
  124. package/build/tests/attachment_table_names.spec.js.map +1 -0
  125. package/build/tests/attachments_table_stub.spec.js +41 -5
  126. package/build/tests/attachments_table_stub.spec.js.map +1 -1
  127. package/build/tests/define_config.spec.js +34 -0
  128. package/build/tests/define_config.spec.js.map +1 -1
  129. package/build/tests/helpers/lucid_test_database.d.ts.map +1 -1
  130. package/build/tests/helpers/lucid_test_database.js +16 -6
  131. package/build/tests/helpers/lucid_test_database.js.map +1 -1
  132. package/build/tests/legacy_attachment_migration_stub.spec.d.ts +8 -0
  133. package/build/tests/legacy_attachment_migration_stub.spec.d.ts.map +1 -0
  134. package/build/tests/legacy_attachment_migration_stub.spec.js +57 -0
  135. package/build/tests/legacy_attachment_migration_stub.spec.js.map +1 -0
  136. package/build/tests/lucid_attachment_collection_store.spec.d.ts +2 -0
  137. package/build/tests/lucid_attachment_collection_store.spec.d.ts.map +1 -0
  138. package/build/tests/lucid_attachment_collection_store.spec.js +53 -0
  139. package/build/tests/lucid_attachment_collection_store.spec.js.map +1 -0
  140. package/build/tests/lucid_attachment_column.spec.js +57 -1
  141. package/build/tests/lucid_attachment_column.spec.js.map +1 -1
  142. package/build/tests/lucid_attachment_lifecycle_service.spec.js +117 -111
  143. package/build/tests/lucid_attachment_lifecycle_service.spec.js.map +1 -1
  144. package/build/tests/lucid_attachment_relation.spec.d.ts +8 -0
  145. package/build/tests/lucid_attachment_relation.spec.d.ts.map +1 -0
  146. package/build/tests/lucid_attachment_relation.spec.js +295 -0
  147. package/build/tests/lucid_attachment_relation.spec.js.map +1 -0
  148. package/build/tests/lucid_attachment_repository.spec.js +1 -1
  149. package/build/tests/lucid_attachment_repository.spec.js.map +1 -1
  150. package/build/tests/lucid_attachment_store.spec.js +24 -50
  151. package/build/tests/lucid_attachment_store.spec.js.map +1 -1
  152. package/build/tests/lucid_sqlite_integration.spec.js +23 -18
  153. package/build/tests/lucid_sqlite_integration.spec.js.map +1 -1
  154. package/build/tests/lucid_variant_generation_service.spec.js +1 -1
  155. package/build/tests/lucid_variant_generation_service.spec.js.map +1 -1
  156. package/build/tests/migrate_legacy_attachment.spec.js +114 -67
  157. package/build/tests/migrate_legacy_attachment.spec.js.map +1 -1
  158. package/build/tests/migrate_legacy_attachment_records.spec.js +4 -3
  159. package/build/tests/migrate_legacy_attachment_records.spec.js.map +1 -1
  160. package/package.json +4 -2
  161. package/build/src/integrations/lucid/attachment_column.d.ts +0 -11
  162. package/build/src/integrations/lucid/attachment_column.d.ts.map +0 -1
  163. package/build/src/integrations/lucid/attachment_column.js.map +0 -1
  164. package/build/src/integrations/lucid/attachment_model.d.ts.map +0 -1
  165. package/build/src/integrations/lucid/attachment_model.js.map +0 -1
  166. package/build/src/integrations/lucid/attachment_owner.d.ts.map +0 -1
  167. package/build/src/integrations/lucid/attachment_owner.js.map +0 -1
  168. package/build/src/integrations/lucid/attachments_table_stub.d.ts.map +0 -1
  169. package/build/src/integrations/lucid/attachments_table_stub.js.map +0 -1
  170. package/build/src/integrations/lucid/create_legacy_attachment_migration_script.d.ts +0 -13
  171. package/build/src/integrations/lucid/create_legacy_attachment_migration_script.d.ts.map +0 -1
  172. package/build/src/integrations/lucid/create_legacy_attachment_migration_script.js +0 -20
  173. package/build/src/integrations/lucid/create_legacy_attachment_migration_script.js.map +0 -1
  174. package/build/src/integrations/lucid/lucid_attachment_lifecycle_service.d.ts +0 -21
  175. package/build/src/integrations/lucid/lucid_attachment_lifecycle_service.d.ts.map +0 -1
  176. package/build/src/integrations/lucid/lucid_attachment_lifecycle_service.js +0 -68
  177. package/build/src/integrations/lucid/lucid_attachment_lifecycle_service.js.map +0 -1
  178. package/build/src/integrations/lucid/lucid_attachment_repository.d.ts.map +0 -1
  179. package/build/src/integrations/lucid/lucid_attachment_repository.js.map +0 -1
  180. package/build/src/integrations/lucid/lucid_attachment_store.d.ts +0 -27
  181. package/build/src/integrations/lucid/lucid_attachment_store.d.ts.map +0 -1
  182. package/build/src/integrations/lucid/lucid_attachment_store.js +0 -84
  183. package/build/src/integrations/lucid/lucid_attachment_store.js.map +0 -1
  184. package/build/src/integrations/lucid/lucid_variant_generation_service.d.ts.map +0 -1
  185. package/build/src/integrations/lucid/lucid_variant_generation_service.js.map +0 -1
  186. package/build/src/integrations/lucid/migrate_legacy_attachment.d.ts.map +0 -1
  187. package/build/src/integrations/lucid/migrate_legacy_attachment.js +0 -67
  188. package/build/src/integrations/lucid/migrate_legacy_attachment.js.map +0 -1
  189. package/build/src/integrations/lucid/migrate_legacy_attachment_records.d.ts.map +0 -1
  190. package/build/src/integrations/lucid/migrate_legacy_attachment_records.js.map +0 -1
  191. package/build/src/integrations/lucid/render_legacy_attachment_migration_script.d.ts +0 -11
  192. package/build/src/integrations/lucid/render_legacy_attachment_migration_script.d.ts.map +0 -1
  193. package/build/src/integrations/lucid/render_legacy_attachment_migration_script.js.map +0 -1
  194. package/build/tests/create_legacy_attachment_migration_script.spec.d.ts.map +0 -1
  195. package/build/tests/create_legacy_attachment_migration_script.spec.js +0 -31
  196. package/build/tests/create_legacy_attachment_migration_script.spec.js.map +0 -1
  197. /package/build/src/integrations/lucid/{lucid_variant_generation_service.js → persistence/lucid_variant_generation_service.js} +0 -0
  198. /package/build/src/integrations/lucid/{attachment_owner.js → relations/attachment_owner.js} +0 -0
  199. /package/build/src/integrations/lucid/{attachments_table_stub.d.ts → schema/attachments_table_stub.d.ts} +0 -0
@@ -5,7 +5,8 @@
5
5
  * @copyright Jeremy Chaufourier <jeremy@chaufourier.fr>
6
6
  */
7
7
  import { test } from '@japa/runner';
8
- import { LucidAttachmentLifecycleService } from '../src/integrations/lucid/lucid_attachment_lifecycle_service.js';
8
+ import { AttachmentService } from '../src/core/attachment_service.js';
9
+ import { LucidAttachmentLifecycleService } from '../src/integrations/lucid/persistence/lucid_attachment_lifecycle_service.js';
9
10
  const attachment = {
10
11
  id: 'attachment-id',
11
12
  disk: 'public',
@@ -16,45 +17,89 @@ const attachment = {
16
17
  extname: 'jpg',
17
18
  size: 42,
18
19
  };
19
- function makeRow(value, id = value.id) {
20
+ function makeBlob(value) {
21
+ return {
22
+ id: value.id,
23
+ toAttachment() {
24
+ return value;
25
+ },
26
+ };
27
+ }
28
+ function makeLink(value, id = `link-${value.id}`) {
29
+ const blob = makeBlob(value);
20
30
  return {
21
31
  id,
32
+ attachmentId: value.id,
33
+ attachment: blob,
22
34
  toAttachment() {
23
35
  return value;
24
36
  },
25
37
  };
26
38
  }
39
+ function makeStore(overrides = {}) {
40
+ const link = makeLink(attachment);
41
+ return {
42
+ async createOriginal() {
43
+ return link;
44
+ },
45
+ async findOriginal() {
46
+ return null;
47
+ },
48
+ async listVariants() {
49
+ return [];
50
+ },
51
+ async releaseOwner() { },
52
+ async restoreOwner() { },
53
+ async remove() {
54
+ return [];
55
+ },
56
+ async createCollectionItem() {
57
+ return link;
58
+ },
59
+ async findCollectionItem() {
60
+ return null;
61
+ },
62
+ async listCollection() {
63
+ return [];
64
+ },
65
+ async moveCollectionItem() {
66
+ return [];
67
+ },
68
+ async removeCollectionItem() {
69
+ return [];
70
+ },
71
+ ...overrides,
72
+ };
73
+ }
27
74
  test.group('LucidAttachmentLifecycleService', () => {
28
- test('persists the file before creating its polymorphic row', async ({ assert }) => {
75
+ test('persists a manager draft before creating its polymorphic link', async ({ assert }) => {
29
76
  const events = [];
30
- const service = new LucidAttachmentLifecycleService({
31
- async create() {
32
- events.push('write');
33
- return attachment;
77
+ const attachments = new AttachmentService({
78
+ defaultDisk: 'fs',
79
+ createId: () => attachment.id,
80
+ queue: { async enqueue() { } },
81
+ storage: {
82
+ async write() {
83
+ events.push('write');
84
+ },
85
+ async read() {
86
+ return new Uint8Array();
87
+ },
88
+ async remove() { },
34
89
  },
35
- async remove() { },
36
- }, {
90
+ });
91
+ const draft = attachments.createDraft({ body: new Uint8Array([1]), originalName: 'profile.jpg' });
92
+ const service = new LucidAttachmentLifecycleService(attachments, makeStore({
37
93
  async createOriginal() {
38
- events.push('persist');
39
- return {};
40
- },
41
- async findOriginal() {
42
- return null;
94
+ events.push('link');
95
+ return makeLink(attachment);
43
96
  },
44
- async listVariants() {
45
- return [];
46
- },
47
- async releaseOwner() { },
48
- async restoreOwner() { },
49
- async remove() { },
50
- });
51
- await service.attach({ type: 'users', id: '42', field: 'avatar' }, {
52
- body: new Uint8Array(),
53
- originalName: 'profile.jpg',
54
- });
55
- assert.deepEqual(events, ['write', 'persist']);
97
+ }));
98
+ await service.attach({ type: 'users', id: '42', field: 'avatar' }, draft);
99
+ assert.isTrue(draft.isPersisted);
100
+ assert.deepEqual(events, ['write', 'link']);
56
101
  });
57
- test('removes a new file when database persistence fails', async ({ assert }) => {
102
+ test('removes a new file when blob or link persistence fails', async ({ assert }) => {
58
103
  const removed = [];
59
104
  const service = new LucidAttachmentLifecycleService({
60
105
  async create() {
@@ -63,144 +108,105 @@ test.group('LucidAttachmentLifecycleService', () => {
63
108
  async remove(value) {
64
109
  removed.push(value);
65
110
  },
66
- }, {
111
+ }, makeStore({
67
112
  async createOriginal() {
68
113
  throw new Error('database unavailable');
69
114
  },
70
- async findOriginal() {
71
- return null;
72
- },
73
- async listVariants() {
74
- return [];
75
- },
76
- async releaseOwner() { },
77
- async restoreOwner() { },
78
- async remove() { },
79
- });
115
+ }));
80
116
  await assert.rejects(() => service.attach({ type: 'users', id: '42', field: 'avatar' }, {
81
117
  body: new Uint8Array(),
82
118
  originalName: 'profile.jpg',
83
119
  }), 'database unavailable');
84
120
  assert.deepEqual(removed, [attachment]);
85
121
  });
86
- test('replaces the persisted row before removing the previous file', async ({ assert }) => {
122
+ test('replaces a link before purging its unreferenced blob', async ({ assert }) => {
87
123
  const events = [];
88
124
  const previousAttachment = { ...attachment, id: 'previous-id', path: 'users/42/previous.jpg' };
89
125
  const currentAttachment = { ...attachment, id: 'current-id', path: 'users/42/current.jpg' };
90
- const previous = makeRow(previousAttachment);
91
- const current = makeRow(currentAttachment);
126
+ const previous = makeLink(previousAttachment);
127
+ const current = makeLink(currentAttachment);
92
128
  const service = new LucidAttachmentLifecycleService({
93
129
  async create() {
94
- events.push('write-current');
130
+ events.push('write');
95
131
  return currentAttachment;
96
132
  },
97
133
  async remove(value) {
98
134
  events.push(`remove-file:${value.id}`);
99
135
  },
100
- }, {
136
+ }, makeStore({
101
137
  async createOriginal() {
102
- events.push('persist-current');
138
+ events.push('create-link');
103
139
  return current;
104
140
  },
105
141
  async findOriginal() {
106
142
  return previous;
107
143
  },
108
- async listVariants() {
109
- return [];
110
- },
111
144
  async releaseOwner() {
112
- events.push('release-previous');
145
+ events.push('release-link');
113
146
  },
114
- async restoreOwner() { },
115
- async remove(row) {
116
- events.push(`remove-row:${row.id}`);
147
+ async remove() {
148
+ events.push('remove-link');
149
+ return [makeBlob(previousAttachment)];
117
150
  },
118
- });
119
- const row = await service.replace({ type: 'users', id: '42', field: 'avatar' }, {
151
+ }));
152
+ await service.replace({ type: 'users', id: '42', field: 'avatar' }, {
120
153
  body: new Uint8Array(),
121
154
  originalName: 'profile.jpg',
122
155
  });
123
- assert.equal(row, current);
124
156
  assert.deepEqual(events, [
125
- 'write-current',
126
- 'release-previous',
127
- 'persist-current',
128
- 'remove-row:previous-id',
157
+ 'write',
158
+ 'release-link',
159
+ 'create-link',
160
+ 'remove-link',
129
161
  'remove-file:previous-id',
130
162
  ]);
131
163
  });
132
- test('restores the previous owner when replacement persistence fails', async ({ assert }) => {
133
- const events = [];
134
- const previous = makeRow(attachment, 'previous-id');
135
- const currentAttachment = { ...attachment, id: 'current-id', path: 'users/42/current.jpg' };
164
+ test('only removes files for blobs that became unreferenced', async ({ assert }) => {
165
+ const removed = [];
136
166
  const service = new LucidAttachmentLifecycleService({
137
167
  async create() {
138
- events.push('write-current');
139
- return currentAttachment;
168
+ return attachment;
140
169
  },
141
170
  async remove(value) {
142
- events.push(`remove-file:${value.id}`);
143
- },
144
- }, {
145
- async createOriginal() {
146
- throw new Error('database unavailable');
171
+ removed.push(value.id);
147
172
  },
173
+ }, makeStore({
148
174
  async findOriginal() {
149
- return previous;
175
+ return makeLink(attachment);
150
176
  },
151
- async listVariants() {
177
+ async remove() {
152
178
  return [];
153
179
  },
154
- async releaseOwner() {
155
- events.push('release-previous');
156
- },
157
- async restoreOwner() {
158
- events.push('restore-previous');
159
- },
160
- async remove() { },
161
- });
162
- await assert.rejects(() => service.replace({ type: 'users', id: '42', field: 'avatar' }, {
163
- body: new Uint8Array(),
164
- originalName: 'profile.jpg',
165
- }), 'database unavailable');
166
- assert.deepEqual(events, [
167
- 'write-current',
168
- 'release-previous',
169
- 'restore-previous',
170
- 'remove-file:current-id',
171
- ]);
180
+ }));
181
+ await service.detach({ type: 'users', id: '42', field: 'avatar' });
182
+ assert.deepEqual(removed, []);
172
183
  });
173
- test('detaches the original and every persisted variant', async ({ assert }) => {
174
- const removedRows = [];
175
- const removedFiles = [];
176
- const original = makeRow(attachment);
177
- const variant = makeRow({ ...attachment, id: 'variant-id', path: 'users/42/thumbnail.webp' });
184
+ test('adds and removes ordered collection links', async ({ assert }) => {
185
+ const item = makeLink(attachment);
186
+ const removed = [];
178
187
  const service = new LucidAttachmentLifecycleService({
179
188
  async create() {
180
189
  return attachment;
181
190
  },
182
191
  async remove(value) {
183
- removedFiles.push(value.id);
184
- },
185
- }, {
186
- async createOriginal() {
187
- return original;
192
+ removed.push(value.id);
188
193
  },
189
- async findOriginal() {
190
- return original;
194
+ }, makeStore({
195
+ async createCollectionItem() {
196
+ return item;
191
197
  },
192
- async listVariants() {
193
- return [variant];
198
+ async findCollectionItem() {
199
+ return item;
194
200
  },
195
- async releaseOwner() { },
196
- async restoreOwner() { },
197
- async remove(row) {
198
- removedRows.push(row.id);
201
+ async removeCollectionItem() {
202
+ return [makeBlob(attachment)];
199
203
  },
200
- });
201
- await service.detach({ type: 'users', id: '42', field: 'avatar' });
202
- assert.deepEqual(removedRows, ['attachment-id']);
203
- assert.sameDeepMembers(removedFiles, ['attachment-id', 'variant-id']);
204
+ }));
205
+ const added = await service.add({ type: 'users', id: '42', field: 'gallery' }, { body: new Uint8Array(), originalName: 'profile.jpg' });
206
+ const didRemove = await service.removeCollectionItem({ type: 'users', id: '42', field: 'gallery' }, added.id);
207
+ assert.equal(added.id, item.id);
208
+ assert.isTrue(didRemove);
209
+ assert.deepEqual(removed, [attachment.id]);
204
210
  });
205
211
  });
206
212
  //# sourceMappingURL=lucid_attachment_lifecycle_service.spec.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"lucid_attachment_lifecycle_service.spec.js","sourceRoot":"","sources":["../../tests/lucid_attachment_lifecycle_service.spec.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"lucid_attachment_lifecycle_service.spec.js","sourceRoot":"","sources":["../../tests/lucid_attachment_lifecycle_service.spec.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * @jrmc/adonis-attachment
3
+ *
4
+ * @license MIT
5
+ * @copyright Jeremy Chaufourier <jeremy@chaufourier.fr>
6
+ */
7
+ export {};
8
+ //# sourceMappingURL=lucid_attachment_relation.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lucid_attachment_relation.spec.d.ts","sourceRoot":"","sources":["../../tests/lucid_attachment_relation.spec.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
@@ -0,0 +1,295 @@
1
+ /**
2
+ * @jrmc/adonis-attachment
3
+ *
4
+ * @license MIT
5
+ * @copyright Jeremy Chaufourier <jeremy@chaufourier.fr>
6
+ */
7
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
8
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
9
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
10
+ 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;
11
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
12
+ };
13
+ import { setApp } from "@adonisjs/core/services/app";
14
+ import { BaseModel, column } from "@adonisjs/lucid/orm";
15
+ import { test } from "@japa/runner";
16
+ import { attachmentRelation, attachmentsRelation, } from "../index.js";
17
+ import { AttachmentService } from "../src/core/attachment_service.js";
18
+ import { AttachmentModel } from "../src/integrations/lucid/models/attachment_model.js";
19
+ import { LucidAttachmentStore } from "../src/integrations/lucid/persistence/lucid_attachment_store.js";
20
+ import { createLucidTestDatabase } from "./helpers/lucid_test_database.js";
21
+ class RelationUser extends BaseModel {
22
+ static table = "relation_users";
23
+ static selfAssignPrimaryKey = true;
24
+ }
25
+ __decorate([
26
+ column({ isPrimary: true })
27
+ ], RelationUser.prototype, "id", void 0);
28
+ __decorate([
29
+ column()
30
+ ], RelationUser.prototype, "name", void 0);
31
+ __decorate([
32
+ attachmentRelation({
33
+ disk: "decorator",
34
+ folder: ({ model }) => `avatars/${model.id}`,
35
+ rename: false,
36
+ })
37
+ ], RelationUser.prototype, "avatar", void 0);
38
+ __decorate([
39
+ attachmentsRelation({
40
+ folder: ({ model }) => `gallery/${model.id}`,
41
+ rename: false,
42
+ })
43
+ ], RelationUser.prototype, "gallery", void 0);
44
+ let database;
45
+ let attachments;
46
+ let removed;
47
+ let writes;
48
+ let queued;
49
+ let nextId = 0;
50
+ function createDraft(name, options = {}) {
51
+ return attachments.createDraft({
52
+ body: Buffer.from(name),
53
+ originalName: name,
54
+ mimeType: "text/plain",
55
+ }, options);
56
+ }
57
+ async function createUser(id = "user-1") {
58
+ const user = new RelationUser();
59
+ user.id = id;
60
+ user.name = id;
61
+ await user.save();
62
+ return user;
63
+ }
64
+ async function getAvatarOrFail(user) {
65
+ const avatar = await user.avatar.get();
66
+ if (!avatar) {
67
+ throw new Error("Expected a persisted avatar link");
68
+ }
69
+ return avatar;
70
+ }
71
+ test.group("Lucid attachment relations", (group) => {
72
+ group.setup(async () => {
73
+ database = await createLucidTestDatabase();
74
+ RelationUser.useAdapter(database.modelAdapter());
75
+ await database
76
+ .connection()
77
+ .schema.createTable("relation_users", (table) => {
78
+ table.string("id").primary();
79
+ table.string("name").notNullable().unique();
80
+ });
81
+ });
82
+ group.each.setup(async () => {
83
+ await database.from("attachments").delete();
84
+ await database.from("relation_users").delete();
85
+ removed = [];
86
+ writes = [];
87
+ queued = [];
88
+ nextId = 0;
89
+ attachments = new AttachmentService({
90
+ defaultDisk: "fs",
91
+ defaults: { disk: "config", folder: "config" },
92
+ createId: () => `attachment-${++nextId}`,
93
+ queue: {
94
+ async enqueue(job) {
95
+ queued.push(job.attachmentId);
96
+ },
97
+ },
98
+ storage: {
99
+ async write(input) {
100
+ writes.push({ disk: input.disk, path: input.path });
101
+ },
102
+ async read() {
103
+ return new Uint8Array();
104
+ },
105
+ async remove(location) {
106
+ removed.push(location.path);
107
+ },
108
+ },
109
+ });
110
+ setApp({
111
+ container: {
112
+ async make(binding) {
113
+ if (binding !== "jrmc.attachment") {
114
+ throw new Error(`Unexpected binding: ${binding}`);
115
+ }
116
+ return attachments;
117
+ },
118
+ },
119
+ });
120
+ });
121
+ group.teardown(async () => {
122
+ await database.manager.closeAll();
123
+ });
124
+ test("stages singular changes until the Lucid model is saved", async ({ assert, }) => {
125
+ const user = new RelationUser();
126
+ user.id = "user-1";
127
+ user.name = "user-1";
128
+ const first = createDraft("first.txt");
129
+ user.avatar.attach(first);
130
+ assert.isFalse(first.isPersisted);
131
+ await user.save();
132
+ const original = await getAvatarOrFail(user);
133
+ assert.isTrue(first.isPersisted);
134
+ assert.equal(original.attachableType, "relation_users");
135
+ assert.equal(original.attachableId, user.id);
136
+ assert.equal(original.field, "avatar");
137
+ assert.equal(first.disk, "decorator");
138
+ assert.equal(first.path, "avatars/user-1/first.txt");
139
+ assert.equal((await user.avatar.get())?.id, original.id);
140
+ user.avatar.attach(createDraft("duplicate.txt"));
141
+ await assert.rejects(() => user.save(), /already has an attachment/);
142
+ const replacement = createDraft("replacement.txt", {
143
+ disk: "manager",
144
+ folder: "imports",
145
+ });
146
+ user.avatar.set(replacement);
147
+ await user.save();
148
+ const current = await getAvatarOrFail(user);
149
+ await new LucidAttachmentStore().createVariant(current.attachment, "thumbnail", {
150
+ id: "variant-id",
151
+ disk: "manager",
152
+ path: "imports/thumbnail.txt",
153
+ name: "thumbnail.txt",
154
+ originalName: "replacement.txt",
155
+ mimeType: "text/plain",
156
+ extname: "txt",
157
+ size: 1,
158
+ });
159
+ assert.equal(replacement.path, "imports/replacement.txt");
160
+ assert.deepEqual((await user.avatar.variants()).map((variant) => variant.id), ["variant-id"]);
161
+ assert.isTrue(await user.avatar.regenerateVariants(["thumbnail"]));
162
+ assert.deepEqual(queued, [current.attachmentId]);
163
+ user.avatar.detach();
164
+ await user.save();
165
+ assert.isNull(await user.avatar.get());
166
+ assert.sameDeepMembers(removed, [
167
+ first.toAttachment().path,
168
+ replacement.toAttachment().path,
169
+ "imports/thumbnail.txt",
170
+ ]);
171
+ assert.deepEqual(writes, [
172
+ { disk: "decorator", path: "avatars/user-1/first.txt" },
173
+ { disk: "manager", path: "imports/replacement.txt" },
174
+ ]);
175
+ });
176
+ test("stages ordered collection changes until the Lucid model is saved", async ({ assert, }) => {
177
+ const user = await createUser();
178
+ user.gallery.add(createDraft("first.txt"));
179
+ user.gallery.add(createDraft("second.txt"));
180
+ user.gallery.add(createDraft("before.txt"), 0);
181
+ await user.save();
182
+ const [before, first, second] = await user.gallery.all();
183
+ if (!before || !first || !second) {
184
+ throw new Error("Expected persisted gallery links");
185
+ }
186
+ assert.deepEqual((await user.gallery.all()).map((item) => item.id), [before.id, first.id, second.id]);
187
+ user.gallery.move(second.id, 0);
188
+ await user.save();
189
+ assert.deepEqual((await user.gallery.all()).map((item) => item.id), [second.id, before.id, first.id]);
190
+ user.gallery.remove(before.id);
191
+ user.gallery.remove("missing-id");
192
+ await user.save();
193
+ user.gallery.replaceAll([
194
+ createDraft("replacement-1.txt"),
195
+ createDraft("replacement-2.txt"),
196
+ ]);
197
+ await user.save();
198
+ const replacement = await user.gallery.all();
199
+ assert.deepEqual(replacement.map((item) => item.position), [0, 1]);
200
+ user.gallery.clear();
201
+ await user.save();
202
+ assert.deepEqual(await user.gallery.all(), []);
203
+ assert.equal(removed.length, 5);
204
+ });
205
+ test("can flush a staged relation explicitly for a persisted owner", async ({ assert }) => {
206
+ const user = await createUser();
207
+ const draft = createDraft("immediate.txt");
208
+ user.avatar.set(draft);
209
+ const avatar = await user.avatar.persist();
210
+ assert.isNotNull(avatar);
211
+ assert.isTrue(draft.isPersisted);
212
+ assert.equal((await user.avatar.get())?.id, avatar?.id);
213
+ });
214
+ test("requires the Lucid owner to be persisted", async ({ assert }) => {
215
+ const user = new RelationUser();
216
+ user.id = "user-1";
217
+ await assert.rejects(() => user.avatar.get(), /require a persisted Lucid model/);
218
+ });
219
+ test("uses the owner transaction and cleans up a new file after rollback", async ({ assert, }) => {
220
+ const user = await createUser();
221
+ const draft = createDraft("rollback.txt");
222
+ await assert.rejects(() => database.transaction(async (trx) => {
223
+ const transactionalUser = await RelationUser.query({ client: trx })
224
+ .where("id", user.id)
225
+ .firstOrFail();
226
+ transactionalUser.useTransaction(trx);
227
+ transactionalUser.avatar.attach(draft);
228
+ await transactionalUser.save();
229
+ assert.isNotNull(await transactionalUser.avatar.get());
230
+ throw new Error("Rollback requested");
231
+ }), /Rollback requested/);
232
+ assert.isNull(await user.avatar.get());
233
+ assert.deepEqual(removed, [draft.path]);
234
+ });
235
+ test("defers file deletion until an owner transaction commits", async ({ assert }) => {
236
+ const user = await createUser();
237
+ const draft = createDraft("avatar.txt");
238
+ user.avatar.attach(draft);
239
+ await user.save();
240
+ removed = [];
241
+ await assert.rejects(() => database.transaction(async (trx) => {
242
+ const transactionalUser = await RelationUser.query({ client: trx })
243
+ .where("id", user.id)
244
+ .firstOrFail();
245
+ transactionalUser.useTransaction(trx);
246
+ transactionalUser.avatar.detach();
247
+ await transactionalUser.save();
248
+ assert.isNull(await transactionalUser.avatar.get());
249
+ throw new Error("Rollback requested");
250
+ }), /Rollback requested/);
251
+ assert.equal((await user.avatar.get())?.attachmentId, draft.id);
252
+ assert.deepEqual(removed, []);
253
+ });
254
+ test("purges relation links and unreferenced blobs when the owner is deleted", async ({ assert, }) => {
255
+ const user = await createUser();
256
+ user.avatar.attach(createDraft("avatar.txt"));
257
+ user.gallery.add(createDraft("gallery.txt"));
258
+ await user.save();
259
+ const avatar = await getAvatarOrFail(user);
260
+ const [gallery] = await user.gallery.all();
261
+ if (!gallery) {
262
+ throw new Error("Expected a persisted gallery link");
263
+ }
264
+ removed = [];
265
+ await user.delete();
266
+ assert.isNull(await user.avatar.get());
267
+ assert.deepEqual(await user.gallery.all(), []);
268
+ assert.isNull(await AttachmentModel.find(avatar.attachmentId));
269
+ assert.isNull(await AttachmentModel.find(gallery.attachmentId));
270
+ assert.sameDeepMembers(removed, [
271
+ avatar.toAttachment().path,
272
+ gallery.toAttachment().path,
273
+ ]);
274
+ });
275
+ test("keeps a shared blob until its last owner link is deleted", async ({ assert }) => {
276
+ const firstUser = await createUser("user-1");
277
+ const secondUser = await createUser("user-2");
278
+ firstUser.avatar.attach(createDraft("shared.txt"));
279
+ await firstUser.save();
280
+ const firstLink = await getAvatarOrFail(firstUser);
281
+ secondUser.avatar.attachExisting(firstLink.attachmentId);
282
+ await secondUser.save();
283
+ const secondLink = await getAvatarOrFail(secondUser);
284
+ removed = [];
285
+ assert.notEqual(firstLink.id, secondLink.id);
286
+ assert.equal(firstLink.attachmentId, secondLink.attachmentId);
287
+ await firstUser.delete();
288
+ assert.isNotNull(await AttachmentModel.find(firstLink.attachmentId));
289
+ assert.deepEqual(removed, []);
290
+ await secondUser.delete();
291
+ assert.isNull(await AttachmentModel.find(firstLink.attachmentId));
292
+ assert.deepEqual(removed, [firstLink.toAttachment().path]);
293
+ });
294
+ });
295
+ //# sourceMappingURL=lucid_attachment_relation.spec.js.map