@appweaver/data 0.0.0-stage → 2.0.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 (157) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +61 -2
  3. package/config.d.ts +6 -0
  4. package/config.js +22 -0
  5. package/database/create-client.d.ts +11 -0
  6. package/database/create-client.js +145 -0
  7. package/database/database-config.d.ts +14 -0
  8. package/database/database-config.js +40 -0
  9. package/database/database-error.d.ts +49 -0
  10. package/database/database-error.js +216 -0
  11. package/database/index.d.ts +3 -0
  12. package/database/index.js +19 -0
  13. package/database/prisma-database.d.ts +33 -0
  14. package/database/prisma-database.js +178 -0
  15. package/database/run-transaction.d.ts +21 -0
  16. package/database/run-transaction.js +15 -0
  17. package/export/export-config.d.ts +7 -0
  18. package/export/export-config.js +17 -0
  19. package/export/export-service.d.ts +22 -0
  20. package/export/export-service.js +188 -0
  21. package/export/index.d.ts +1 -0
  22. package/export/index.js +17 -0
  23. package/factory/create-model.d.ts +11 -0
  24. package/factory/create-model.js +479 -0
  25. package/factory/create-policy.d.ts +12 -0
  26. package/factory/create-policy.js +20 -0
  27. package/factory/create-service.d.ts +14 -0
  28. package/factory/create-service.js +116 -0
  29. package/index.d.ts +22 -0
  30. package/index.js +38 -0
  31. package/internal.d.ts +2 -0
  32. package/internal.js +6 -0
  33. package/module.d.ts +3 -0
  34. package/module.js +81 -0
  35. package/package.json +67 -3
  36. package/prisma/client/browser.d.ts +39 -0
  37. package/prisma/client/browser.js +56 -0
  38. package/prisma/client/client.d.ts +58 -0
  39. package/prisma/client/client.js +70 -0
  40. package/prisma/client/commonInputTypes.d.ts +345 -0
  41. package/prisma/client/commonInputTypes.js +11 -0
  42. package/prisma/client/enums.d.ts +1 -0
  43. package/prisma/client/enums.js +11 -0
  44. package/prisma/client/internal/class.d.ts +198 -0
  45. package/prisma/client/internal/class.js +85 -0
  46. package/prisma/client/internal/prismaNamespace.d.ts +1125 -0
  47. package/prisma/client/internal/prismaNamespace.js +204 -0
  48. package/prisma/client/internal/prismaNamespaceBrowser.d.ts +137 -0
  49. package/prisma/client/internal/prismaNamespaceBrowser.js +175 -0
  50. package/prisma/client/models/ApiKey.d.ts +1167 -0
  51. package/prisma/client/models/ApiKey.js +2 -0
  52. package/prisma/client/models/ConnectedAccount.d.ts +1094 -0
  53. package/prisma/client/models/ConnectedAccount.js +2 -0
  54. package/prisma/client/models/File.d.ts +1291 -0
  55. package/prisma/client/models/File.js +2 -0
  56. package/prisma/client/models/OneTimeToken.d.ts +1055 -0
  57. package/prisma/client/models/OneTimeToken.js +2 -0
  58. package/prisma/client/models/Permission.d.ts +1209 -0
  59. package/prisma/client/models/Permission.js +2 -0
  60. package/prisma/client/models/Role.d.ts +1209 -0
  61. package/prisma/client/models/Role.js +2 -0
  62. package/prisma/client/models/Seeder.d.ts +1023 -0
  63. package/prisma/client/models/Seeder.js +2 -0
  64. package/prisma/client/models.d.ts +8 -0
  65. package/prisma/client/models.js +2 -0
  66. package/resource/load-data-resources.d.ts +13 -0
  67. package/resource/load-data-resources.js +37 -0
  68. package/resource/model-schema.d.ts +34 -0
  69. package/resource/model-schema.js +54 -0
  70. package/resource/resource-config.d.ts +16 -0
  71. package/resource/resource-config.js +62 -0
  72. package/resource/resource-loader.d.ts +25 -0
  73. package/resource/resource-loader.js +138 -0
  74. package/resource/resource-service.d.ts +462 -0
  75. package/resource/resource-service.js +1042 -0
  76. package/resource/schemas/index.d.ts +3 -0
  77. package/resource/schemas/index.js +19 -0
  78. package/resource/schemas/resource-aggregate-schema.d.ts +53 -0
  79. package/resource/schemas/resource-aggregate-schema.js +130 -0
  80. package/resource/schemas/resource-filter-schema.d.ts +39 -0
  81. package/resource/schemas/resource-filter-schema.js +153 -0
  82. package/resource/schemas/resource-sort-schema.d.ts +38 -0
  83. package/resource/schemas/resource-sort-schema.js +113 -0
  84. package/resource/utils/aggregate-util.d.ts +113 -0
  85. package/resource/utils/aggregate-util.js +322 -0
  86. package/resource/utils/cursor-util.d.ts +60 -0
  87. package/resource/utils/cursor-util.js +116 -0
  88. package/resource/utils/date-util.d.ts +22 -0
  89. package/resource/utils/date-util.js +112 -0
  90. package/resource/utils/delete-util.d.ts +131 -0
  91. package/resource/utils/delete-util.js +385 -0
  92. package/resource/utils/filter-util.d.ts +24 -0
  93. package/resource/utils/filter-util.js +289 -0
  94. package/resource/utils/prune-util.d.ts +11 -0
  95. package/resource/utils/prune-util.js +56 -0
  96. package/resource/utils/relation-util.d.ts +75 -0
  97. package/resource/utils/relation-util.js +400 -0
  98. package/resource/utils/sort-util.d.ts +31 -0
  99. package/resource/utils/sort-util.js +235 -0
  100. package/resource/utils/text-search-util.d.ts +14 -0
  101. package/resource/utils/text-search-util.js +39 -0
  102. package/resources.d.ts +10 -0
  103. package/resources.js +26 -0
  104. package/security/auth-config.d.ts +23 -0
  105. package/security/auth-config.js +43 -0
  106. package/security/create-auth-resources.d.ts +28 -0
  107. package/security/create-auth-resources.js +163 -0
  108. package/security/helper.d.ts +109 -0
  109. package/security/helper.js +298 -0
  110. package/security/resources/api-key/model.d.ts +2 -0
  111. package/security/resources/api-key/model.js +67 -0
  112. package/security/resources/api-key/policy.d.ts +2 -0
  113. package/security/resources/api-key/policy.js +27 -0
  114. package/security/resources/api-key/service.d.ts +3 -0
  115. package/security/resources/api-key/service.js +34 -0
  116. package/security/resources/connected-account/model.d.ts +2 -0
  117. package/security/resources/connected-account/model.js +57 -0
  118. package/security/resources/connected-account/service.d.ts +2 -0
  119. package/security/resources/connected-account/service.js +7 -0
  120. package/security/resources/one-time-token/model.d.ts +2 -0
  121. package/security/resources/one-time-token/model.js +36 -0
  122. package/security/resources/permission/model.d.ts +2 -0
  123. package/security/resources/permission/model.js +16 -0
  124. package/security/resources/role/model.d.ts +2 -0
  125. package/security/resources/role/model.js +22 -0
  126. package/security/store/database-security-store.d.ts +5 -0
  127. package/security/store/database-security-store.js +54 -0
  128. package/seeder/create-seeder.d.ts +29 -0
  129. package/seeder/create-seeder.js +28 -0
  130. package/seeder/index.d.ts +2 -0
  131. package/seeder/index.js +18 -0
  132. package/seeder/resources/seeder/model.d.ts +2 -0
  133. package/seeder/resources/seeder/model.js +38 -0
  134. package/seeder/seeder.d.ts +29 -0
  135. package/seeder/seeder.js +197 -0
  136. package/storage/file-service.d.ts +133 -0
  137. package/storage/file-service.js +586 -0
  138. package/storage/image-config.d.ts +3 -0
  139. package/storage/image-config.js +11 -0
  140. package/storage/resources/file/model.d.ts +2 -0
  141. package/storage/resources/file/model.js +80 -0
  142. package/types/auth.d.ts +23 -0
  143. package/types/auth.js +2 -0
  144. package/types/generated.d.ts +366 -0
  145. package/types/generated.js +3 -0
  146. package/types/storage.d.ts +35 -0
  147. package/types/storage.js +2 -0
  148. package/utils/export-util.d.ts +8 -0
  149. package/utils/export-util.js +26 -0
  150. package/utils/file-util.d.ts +106 -0
  151. package/utils/file-util.js +254 -0
  152. package/utils/model-util.d.ts +36 -0
  153. package/utils/model-util.js +154 -0
  154. package/utils/policy-util.d.ts +18 -0
  155. package/utils/policy-util.js +28 -0
  156. package/utils/virtual-util.d.ts +11 -0
  157. package/utils/virtual-util.js +53 -0
@@ -0,0 +1,29 @@
1
+ import { Seeder } from './seeder';
2
+ export type CreateSeederParams = {
3
+ /** A relative path where the application source code is located.
4
+ * This is usually the directory from which the createApp() function is called.
5
+ * (default: ./dist/src) */
6
+ scanPath?: string;
7
+ /** A relative path where the seeder functions are located.
8
+ * (default: ./dist/database/seeders) */
9
+ seedersPath?: string;
10
+ /** A flag indication if the seeder should continue execution even if an error occurs.
11
+ * (default: false) */
12
+ continueOnError?: boolean;
13
+ /** A boolean flag indicating whether the seeder should automatically
14
+ * start seeding after being created. (default: true) **/
15
+ autoSeed?: boolean;
16
+ /** A boolean flag indicating whether to automatically fix all warnings
17
+ * related to the seeders like wrong checksum or deleted seeder files.
18
+ * (default: false) **/
19
+ fixWarnings?: boolean;
20
+ };
21
+ /**
22
+ * Creates the database seeder, loading the providers of the project first, and runs the pending seeders unless
23
+ * `autoSeed` is disabled: the seeders of the modules declaring a `seeders` directory first, then the ones of the
24
+ * application.
25
+ *
26
+ * @param {CreateSeederParams} [params={}] - The seeder parameters.
27
+ * @return {Promise<Seeder>} The created seeder.
28
+ */
29
+ export declare function createSeeder(params?: CreateSeederParams): Promise<Seeder>;
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createSeeder = createSeeder;
4
+ const common_1 = require("@appweaver/common");
5
+ const database_config_1 = require("../database/database-config");
6
+ const core_1 = require("@appweaver/core");
7
+ const internal_1 = require("@appweaver/core/internal");
8
+ const seeder_1 = require("./seeder");
9
+ /**
10
+ * Creates the database seeder, loading the providers of the project first, and runs the pending seeders unless
11
+ * `autoSeed` is disabled: the seeders of the modules declaring a `seeders` directory first, then the ones of the
12
+ * application.
13
+ *
14
+ * @param {CreateSeederParams} [params={}] - The seeder parameters.
15
+ * @return {Promise<Seeder>} The created seeder.
16
+ */
17
+ async function createSeeder(params = {}) {
18
+ const scanPath = (0, common_1.resolveSourcePath)(common_1.appConfig.BUILD_PATH, common_1.appConfig.SOURCE_PATH, params.scanPath, './dist/src');
19
+ const seedersPath = (0, common_1.resolveSourcePath)(common_1.appConfig.BUILD_PATH, database_config_1.databaseConfig.SEEDERS_DIR_PATH, params.seedersPath, './dist/database/seeders');
20
+ // Define the providers and the services of the modules
21
+ const modules = await (0, core_1.discoverModules)({ scanPath });
22
+ await (0, internal_1.loadProviders)(modules, scanPath);
23
+ const seeder = new seeder_1.Seeder(seedersPath, params.continueOnError, params.fixWarnings, modules.flatMap(({ module }) => module.seeders ? [{ name: module.name, path: module.seeders }] : []));
24
+ if (params.autoSeed !== false) {
25
+ await seeder.seed();
26
+ }
27
+ return seeder;
28
+ }
@@ -0,0 +1,2 @@
1
+ export * from './create-seeder';
2
+ export * from './seeder';
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./create-seeder"), exports);
18
+ __exportStar(require("./seeder"), exports);
@@ -0,0 +1,2 @@
1
+ declare const _default: import("@appweaver/common").ResourceModel;
2
+ export default _default;
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const create_model_1 = require("../../../factory/create-model");
4
+ exports.default = (0, create_model_1.createModel)({
5
+ name: 'Seeder',
6
+ tableName: '_seeders',
7
+ generateTypes: false,
8
+ id: {
9
+ type: 'string',
10
+ generator: 'uuid()'
11
+ },
12
+ audit: {
13
+ updatedAt: false,
14
+ createdAt: false,
15
+ createdById: false
16
+ },
17
+ scalars: {
18
+ checksum: {
19
+ type: 'string',
20
+ maxLength: 255
21
+ },
22
+ seederName: {
23
+ type: 'string',
24
+ unique: true,
25
+ maxLength: 511
26
+ },
27
+ startedAt: {
28
+ type: 'dateTime'
29
+ },
30
+ finishedAt: {
31
+ type: 'dateTime'
32
+ },
33
+ logs: {
34
+ type: 'string',
35
+ required: false
36
+ }
37
+ }
38
+ });
@@ -0,0 +1,29 @@
1
+ import { LifecycleManager } from '@appweaver/core/internal';
2
+ /** The seeders directory of a module, whose seeders run before the ones of the application. */
3
+ export type ModuleSeeders = {
4
+ /** The name of the module, prefixing the names of its seeders, i.e. `billing/1-plans`. */
5
+ name: string;
6
+ /** The absolute path of the seeders directory. */
7
+ path: string;
8
+ };
9
+ /**
10
+ * Represents a seeder class that manages the application seeders processes.
11
+ */
12
+ export declare class Seeder extends LifecycleManager {
13
+ private readonly _dirPath;
14
+ private readonly _continueOnError;
15
+ private readonly _fixWarnings;
16
+ private readonly _moduleSeeders;
17
+ constructor(_dirPath: string, _continueOnError?: boolean, _fixWarnings?: boolean, _moduleSeeders?: ModuleSeeders[]);
18
+ /**
19
+ * Executes the seeders by discovering, validating, and running seeder files.
20
+ * Logs the seeding process, including warnings for checksum mismatches
21
+ * and files that do not exist but are present in the database table.
22
+ *
23
+ * @return Resolves when all seeders have been processed. Logs relevant
24
+ * information during execution.
25
+ */
26
+ seed(): Promise<void>;
27
+ /** Destroys the services the seeder started, i.e. the database connection. */
28
+ close(): Promise<void>;
29
+ }
@@ -0,0 +1,197 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.Seeder = void 0;
7
+ const node_path_1 = __importDefault(require("node:path"));
8
+ const node_fs_1 = __importDefault(require("node:fs"));
9
+ const promises_1 = __importDefault(require("node:fs/promises"));
10
+ const common_1 = require("@appweaver/common");
11
+ const internal_1 = require("@appweaver/core/internal");
12
+ const core_1 = require("@appweaver/core");
13
+ /**
14
+ * Represents a seeder class that manages the application seeders processes.
15
+ */
16
+ class Seeder extends internal_1.LifecycleManager {
17
+ _dirPath;
18
+ _continueOnError;
19
+ _fixWarnings;
20
+ _moduleSeeders;
21
+ /** @internal */
22
+ _db = (0, core_1.inject)(common_1.Database);
23
+ constructor(_dirPath, _continueOnError = false, _fixWarnings = false, _moduleSeeders = []) {
24
+ super();
25
+ this._dirPath = _dirPath;
26
+ this._continueOnError = _continueOnError;
27
+ this._fixWarnings = _fixWarnings;
28
+ this._moduleSeeders = _moduleSeeders;
29
+ }
30
+ /**
31
+ * Executes the seeders by discovering, validating, and running seeder files.
32
+ * Logs the seeding process, including warnings for checksum mismatches
33
+ * and files that do not exist but are present in the database table.
34
+ *
35
+ * @return Resolves when all seeders have been processed. Logs relevant
36
+ * information during execution.
37
+ */
38
+ async seed() {
39
+ await this.init();
40
+ // The seeders of the modules run first, in their load order
41
+ const directories = [
42
+ ...this._moduleSeeders,
43
+ { name: '', path: this._dirPath }
44
+ ];
45
+ const seederFiles = [];
46
+ const missing = [];
47
+ for (const { name, path: dirPath } of directories) {
48
+ try {
49
+ seederFiles.push(...(await this.loadSeederFiles(dirPath, name)));
50
+ }
51
+ catch {
52
+ console.warn(`Seeders directory ${dirPath} is not accessible`);
53
+ missing.push(name);
54
+ }
55
+ }
56
+ if (missing.length === directories.length) {
57
+ console.error('No seeders directory is accessible');
58
+ return;
59
+ }
60
+ let calledSeedersCount = 0;
61
+ const relativePath = this._dirPath
62
+ .replace(process.cwd(), '.')
63
+ .replace(/\\/g, '/');
64
+ const modulesCount = this._moduleSeeders.length;
65
+ console.log(`${seederFiles.length} seeder${seederFiles.length === 1 ? '' : 's'} found in ${relativePath}${modulesCount > 0
66
+ ? ` and ${modulesCount} module${modulesCount === 1 ? '' : 's'}`
67
+ : ''}`);
68
+ console.log('');
69
+ // For each seeder file, skip if it has already been seeded, otherwise
70
+ // execute all of it's exported functions and write results to a database
71
+ for (const seederFile of seederFiles) {
72
+ const seederName = seederFile.name;
73
+ const seeder = await this.getSeeder(seederName);
74
+ if (seeder) {
75
+ const checksum = await this.seederHash(seederFile.path);
76
+ if (checksum !== seeder.checksum) {
77
+ console.warn(`Warning: seeder ${seederName} has different checksum: ${checksum}, expected checksum: ${seeder.checksum}`);
78
+ if (this._fixWarnings) {
79
+ await this._db.client().seeder.update({
80
+ where: { id: seeder.id },
81
+ data: { checksum }
82
+ });
83
+ console.log('Fix: seeder checksum updated');
84
+ }
85
+ console.log('');
86
+ }
87
+ continue;
88
+ }
89
+ console.log(`Seeding ${seederName}...`);
90
+ await this.executeSeeder(seederFile);
91
+ console.log(`${seederName} seeded`);
92
+ console.log('');
93
+ calledSeedersCount++;
94
+ }
95
+ // The seeders of a missing directory are not reported as deleted
96
+ const seedersWithoutFiles = (await this.findSeedersWithoutFiles(seederFiles)).filter((seeder) => !missing.includes(this.seederOwner(seeder.seederName)));
97
+ for (const seeder of seedersWithoutFiles) {
98
+ console.warn(`Warning: seeder ${seeder.seederName} does not exist but is present in database table`);
99
+ if (this._fixWarnings) {
100
+ await this._db.client().seeder.delete({ where: { id: seeder.id } });
101
+ console.log('Fix: removed seeder from database');
102
+ }
103
+ console.log('');
104
+ }
105
+ if (calledSeedersCount === 0) {
106
+ console.log(`No pending seeders to execute`);
107
+ }
108
+ else {
109
+ console.log(`Executed ${calledSeedersCount} seeder${calledSeedersCount === 1 ? '' : 's'}`);
110
+ }
111
+ }
112
+ /** Destroys the services the seeder started, i.e. the database connection. */
113
+ async close() {
114
+ await this.destroy();
115
+ }
116
+ /** @internal */
117
+ async loadSeederFiles(dirPath, moduleName) {
118
+ const entries = await promises_1.default.readdir(dirPath, { withFileTypes: true });
119
+ return entries
120
+ .filter((e) => e.isFile() && /\.(js|ts)$/.test(e.name) && !e.name.endsWith('.d.ts'))
121
+ .map((e) => e.name)
122
+ .sort((a, b) => a.localeCompare(b, undefined, { numeric: true, sensitivity: 'base' }))
123
+ .map((fileName) => {
124
+ const name = fileName.replace(/\.(js|ts)$/, '');
125
+ return {
126
+ path: node_path_1.default.join(dirPath, fileName),
127
+ name: moduleName ? `${moduleName}/${name}` : name
128
+ };
129
+ });
130
+ }
131
+ /** @internal */
132
+ async executeSeeder(seederFile) {
133
+ const start = new Date();
134
+ const { value, error } = await (0, common_1.importModule)(seederFile.path);
135
+ if (error) {
136
+ if (this._continueOnError) {
137
+ console.error(error);
138
+ return;
139
+ }
140
+ throw error;
141
+ }
142
+ const logs = [];
143
+ // Execute all exported functions from a seeder file and log errors or
144
+ // function responses
145
+ for (const seederFn of Object.values(value)) {
146
+ if ((0, common_1.isFunction)(seederFn)) {
147
+ try {
148
+ const result = await seederFn();
149
+ if (result) {
150
+ logs.push(JSON.stringify(result));
151
+ }
152
+ }
153
+ catch (e) {
154
+ if (!this._continueOnError) {
155
+ throw e;
156
+ }
157
+ console.error(e);
158
+ logs.push(`Error: ${e.message}`);
159
+ }
160
+ }
161
+ }
162
+ const checksum = await this.seederHash(seederFile.path);
163
+ // Insert seeder result into the database
164
+ await this._db.client().seeder.create({
165
+ data: {
166
+ checksum,
167
+ seederName: seederFile.name,
168
+ startedAt: start,
169
+ finishedAt: new Date(),
170
+ logs: logs.length > 0 ? logs.join('\n') : null
171
+ }
172
+ });
173
+ }
174
+ /** @internal */
175
+ async findSeedersWithoutFiles(seederFiles) {
176
+ const seederNames = seederFiles.map((file) => file.name);
177
+ return this._db.client().seeder.findMany({
178
+ where: {
179
+ seederName: { notIn: seederNames }
180
+ }
181
+ });
182
+ }
183
+ /** @internal */
184
+ seederOwner(seederName) {
185
+ const owner = this._moduleSeeders.find(({ name }) => seederName.startsWith(`${name}/`));
186
+ return owner?.name ?? '';
187
+ }
188
+ /** @internal */
189
+ async getSeeder(seederName) {
190
+ return this._db.client().seeder.findFirst({ where: { seederName } });
191
+ }
192
+ /** @internal */
193
+ async seederHash(seederFile) {
194
+ return (0, common_1.makeHash)(node_fs_1.default.createReadStream(seederFile, 'utf8'));
195
+ }
196
+ }
197
+ exports.Seeder = Seeder;
@@ -0,0 +1,133 @@
1
+ import { ContentStream, Resource, ResourceClient, ResourceId } from '@appweaver/common';
2
+ import { File } from '../types/generated';
3
+ import { FileBuffer, UploadedFile, UploadPart } from '../types/storage';
4
+ export type FileStream = {
5
+ content: ContentStream;
6
+ fileName: string;
7
+ mimeType: string;
8
+ start: number;
9
+ end: number;
10
+ };
11
+ /** A file the clients download from the URL of its storage, i.e. a signed URL of a cloud storage. */
12
+ export type FileRedirect = {
13
+ url: string;
14
+ fileName: string;
15
+ mimeType: string;
16
+ };
17
+ export declare class FileService {
18
+ /**
19
+ * Searches for a file by its name from a database.
20
+ *
21
+ * @param {string} fileName - The name of the file to search for.
22
+ * @return {Promise<File>} A promise that resolves to the file object if found.
23
+ * @throws {FileError} Throws an error if the file name is placed under a reserved storage path, if a database error
24
+ * occurs, or if the file is not found.
25
+ */
26
+ findByName(fileName: string): Promise<File>;
27
+ /**
28
+ * Streams a file from storage, handling authorization and range-based requests.
29
+ *
30
+ * @param {string} fileName - The name of the file to stream.
31
+ * @param {string} [range] - An optional range header specifying the byte range to stream.
32
+ * @return {Promise<FileStream>} A promise that resolves to a file stream object containing the content, metadata, and
33
+ * range details.
34
+ * @throws {FileError} `FILE_NOT_FOUND` if the file does not exist.
35
+ * @throws {FileError} `FILE_FORBIDDEN` if user access to the file is forbidden.
36
+ * @throws {FileError} `FILE_STORAGE_ERROR` if an error occurs while reading the file from storage.
37
+ */
38
+ stream(fileName: string, range?: string): Promise<FileStream>;
39
+ /**
40
+ * Opens a file for a download, handling authorization like {@link stream}: the URL of its storage when the storage
41
+ * serves its files directly, otherwise the stream of the file.
42
+ *
43
+ * @param {string} fileName - The name of the file to download.
44
+ * @param {string} [range] - An optional range header specifying the byte range to stream.
45
+ * @return {Promise<FileStream | FileRedirect>} The URL of the file, or its stream.
46
+ * @throws {FileError} The errors of {@link stream}.
47
+ */
48
+ download(fileName: string, range?: string): Promise<FileStream | FileRedirect>;
49
+ /**
50
+ * Saves a file to storage, validates its properties, and associates it with a specific resource and client.
51
+ *
52
+ * @param {UploadedFile} data The multipart file object containing the file data, field name, filename, and metadata.
53
+ * @param {Resource} resource The resource object with which the file is being associated.
54
+ * @param {ResourceClient} client The database client responsible for handling the resource.
55
+ * @return {Promise<File>} A promise that resolves to the saved file object or rejects with an error if the operation
56
+ * fails.
57
+ * @throws {FileError} Throws an error if file validation, storage, or resource association fails.
58
+ */
59
+ saveFile(data: UploadedFile, resource: Resource, client: ResourceClient): Promise<File>;
60
+ /**
61
+ * Saves an in-memory file to storage and associates it with a file field of a specific resource. Behaves exactly like
62
+ * {@link saveFile}, except the content is taken from a buffer instead of a multipart upload, which makes it usable
63
+ * outside a file upload request, for an avatar downloaded from an OAuth2 provider or an image the application
64
+ * generates itself.
65
+ *
66
+ * @param {string} fieldName The file field of the resource the file is saved to.
67
+ * @param {FileBuffer} file The file content, along with its original name and media type.
68
+ * @param {Resource} resource The resource object with which the file is being associated.
69
+ * @param {ResourceClient} client The database client responsible for handling the resource.
70
+ * @return {Promise<File>} A promise that resolves to the saved file object or rejects with an error if the operation
71
+ * fails.
72
+ * @throws {FileError} Throws an error if file validation, storage, or resource association fails.
73
+ */
74
+ saveBuffer(fieldName: string, file: FileBuffer, resource: Resource, client: ResourceClient): Promise<File>;
75
+ /**
76
+ * Saves files received as an asynchronous iterable of multipart data.
77
+ *
78
+ * @param {AsyncIterableIterator<UploadPart>} parts - The asynchronous iterable providing multipart data where each
79
+ * part is expected to represent a file or other data.
80
+ * @param {Resource} resource - The resource associated with the files being saved, providing additional contextual
81
+ * information.
82
+ * @param {ResourceClient} client - The database client responsible for handling resource-related operations, such as
83
+ * database interaction.
84
+ * @return {Promise<File[]>} A promise that resolves to an array of successfully saved files. Rejects with an error
85
+ * if one or more files fail to save.
86
+ */
87
+ saveFiles(parts: AsyncIterableIterator<UploadPart>, resource: Resource, client: ResourceClient): Promise<File[]>;
88
+ /**
89
+ * Deletes a file from the storage and database if it meets the specified conditions.
90
+ *
91
+ * @param {string} fileName - The name of the file to be deleted.
92
+ * @param {string} fieldName - The field associated with the resource to which the file belongs.
93
+ * @param {Resource} resource - The resource that the file is associated with.
94
+ * @param {ResourceClient} client - The client instance representing the resource's type.
95
+ * @return {Promise<File>} A promise that resolves with the deleted file information upon successful deletion.
96
+ * @throws {FileError} If the file is not associated with the provided resource or client,
97
+ * if the current user does not have permission to delete the file,
98
+ * if there is an error removing the file from storage,
99
+ * or if there is an error deleting the file from the database.
100
+ */
101
+ deleteFile(fileName: string, fieldName: string, resource: Resource, client: ResourceClient): Promise<File>;
102
+ /**
103
+ * Deletes a list of files associated with a given resource using the provided resource client.
104
+ *
105
+ * @param {Record<string, string | string[]>} fileNames - An object where the keys correspond to file fields and the
106
+ * values are either a string (single file name) or an array of file names to be deleted.
107
+ * @param {Resource} resource - The resource instance associated with the files to be deleted.
108
+ * @param {ResourceClient} client - The resource a client used to handle deletion operations.
109
+ * @return {Promise<File[]>} A promise that resolves to an array of files that were successfully deleted. Rejects with
110
+ * an error if no files could be deleted.
111
+ */
112
+ deleteFiles(fileNames: Record<string, string | string[]>, resource: Resource, client: ResourceClient): Promise<File[]>;
113
+ /**
114
+ * Deletes all files associated with a resource removed from the database,
115
+ * for the file fields not set to `onResourceDeleted: 'keep'`.
116
+ *
117
+ * @param {string} resourceName - The resource model name.
118
+ * @param {ResourceId} id - The ID of the deleted resource.
119
+ * @return {Promise<File[]>} A promise that resolves to the list of successfully deleted files.
120
+ */
121
+ deleteResourceFiles(resourceName: string, id: ResourceId): Promise<File[]>;
122
+ /**
123
+ * Deletes all files associated with the given deleted resources of one model from the storage and the database. A
124
+ * resource removed from the database loses the files of every field not set to `onResourceDeleted: 'keep'`, while a
125
+ * soft deleted resource only loses the files of the fields set to `onResourceSoftDeleted: 'delete'`.
126
+ *
127
+ * @param {string} resourceName - The resource model name.
128
+ * @param {ResourceId[]} ids - The IDs of the deleted resources.
129
+ * @param {boolean} [softDeleted=false] - Whether the resources were soft deleted.
130
+ * @return {Promise<File[]>} A promise that resolves to the list of successfully deleted files.
131
+ */
132
+ deleteResourcesFiles(resourceName: string, ids: ResourceId[], softDeleted?: boolean): Promise<File[]>;
133
+ }