@directus/api 14.1.2 → 16.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 (207) hide show
  1. package/dist/app.js +8 -6
  2. package/dist/auth/drivers/ldap.js +7 -4
  3. package/dist/auth/drivers/local.js +3 -2
  4. package/dist/auth/drivers/oauth2.js +11 -5
  5. package/dist/auth/drivers/openid.js +11 -5
  6. package/dist/auth/drivers/saml.js +6 -4
  7. package/dist/auth.js +7 -4
  8. package/dist/bus/index.d.ts +1 -0
  9. package/dist/bus/index.js +1 -0
  10. package/dist/bus/lib/use-bus.d.ts +9 -0
  11. package/dist/bus/lib/use-bus.js +21 -0
  12. package/dist/cache.js +9 -9
  13. package/dist/cli/commands/bootstrap/index.js +6 -2
  14. package/dist/cli/commands/count/index.js +2 -1
  15. package/dist/cli/commands/database/install.js +2 -1
  16. package/dist/cli/commands/database/migrate.js +2 -1
  17. package/dist/cli/commands/roles/create.js +2 -1
  18. package/dist/cli/commands/schema/apply.js +46 -34
  19. package/dist/cli/commands/schema/snapshot.js +6 -5
  20. package/dist/cli/commands/users/create.js +4 -3
  21. package/dist/cli/commands/users/passwd.js +5 -4
  22. package/dist/cli/index.js +2 -2
  23. package/dist/cli/load-extensions.js +4 -2
  24. package/dist/cli/utils/create-env/env-stub.liquid +1 -1
  25. package/dist/constants.d.ts +1 -1
  26. package/dist/constants.js +4 -1
  27. package/dist/controllers/assets.js +5 -3
  28. package/dist/controllers/auth.js +5 -4
  29. package/dist/controllers/extensions.js +18 -6
  30. package/dist/controllers/files.js +3 -3
  31. package/dist/controllers/schema.js +3 -2
  32. package/dist/controllers/shares.js +3 -3
  33. package/dist/database/helpers/index.d.ts +1 -1
  34. package/dist/database/index.d.ts +2 -1
  35. package/dist/database/index.js +11 -3
  36. package/dist/database/migrations/20210518A-add-foreign-key-constraints.js +3 -1
  37. package/dist/database/migrations/20210519A-add-system-fk-triggers.js +3 -1
  38. package/dist/database/migrations/20210802A-replace-groups.js +2 -1
  39. package/dist/database/migrations/20230721A-require-shares-fields.js +2 -1
  40. package/dist/database/migrations/20231215A-add-focalpoints.d.ts +3 -0
  41. package/dist/database/migrations/20231215A-add-focalpoints.js +12 -0
  42. package/dist/database/migrations/run.js +2 -1
  43. package/dist/database/run-ast.js +5 -2
  44. package/dist/database/system-data/app-access-permissions/app-access-permissions.yaml +0 -7
  45. package/dist/database/system-data/fields/files.yaml +16 -0
  46. package/dist/database/system-data/relations/relations.yaml +4 -0
  47. package/dist/emitter.d.ts +1 -0
  48. package/dist/emitter.js +4 -1
  49. package/dist/extensions/lib/get-extensions-path.d.ts +1 -1
  50. package/dist/extensions/lib/get-extensions-path.js +2 -1
  51. package/dist/extensions/lib/get-extensions.d.ts +1 -1
  52. package/dist/extensions/lib/get-extensions.js +32 -8
  53. package/dist/extensions/lib/get-shared-deps-mapping.js +7 -5
  54. package/dist/extensions/lib/sandbox/register/call-reference.js +4 -2
  55. package/dist/extensions/lib/sandbox/register/route.d.ts +1 -0
  56. package/dist/extensions/lib/sandbox/sdk/generators/log.js +2 -1
  57. package/dist/extensions/lib/sync-extensions.js +6 -4
  58. package/dist/extensions/manager.d.ts +5 -0
  59. package/dist/extensions/manager.js +84 -34
  60. package/dist/flows.js +13 -7
  61. package/dist/logger.d.ts +7 -6
  62. package/dist/logger.js +116 -91
  63. package/dist/mailer.js +4 -2
  64. package/dist/middleware/cache.js +4 -2
  65. package/dist/middleware/check-ip.js +25 -6
  66. package/dist/middleware/cors.js +2 -1
  67. package/dist/middleware/error-handler.js +5 -5
  68. package/dist/middleware/rate-limiter-global.js +4 -2
  69. package/dist/middleware/rate-limiter-ip.js +16 -12
  70. package/dist/middleware/respond.js +4 -2
  71. package/dist/operations/log/index.js +2 -1
  72. package/dist/rate-limiter.d.ts +2 -1
  73. package/dist/rate-limiter.js +5 -2
  74. package/dist/redis/index.d.ts +3 -0
  75. package/dist/redis/index.js +3 -0
  76. package/dist/redis/lib/create-redis.d.ts +7 -0
  77. package/dist/redis/lib/create-redis.js +12 -0
  78. package/dist/redis/lib/use-redis.d.ts +16 -0
  79. package/dist/redis/lib/use-redis.js +22 -0
  80. package/dist/redis/utils/redis-config-available.d.ts +4 -0
  81. package/dist/redis/utils/redis-config-available.js +8 -0
  82. package/dist/request/request-interceptor.js +7 -5
  83. package/dist/request/response-interceptor.js +2 -2
  84. package/dist/request/validate-ip.d.ts +1 -1
  85. package/dist/request/validate-ip.js +23 -7
  86. package/dist/server.d.ts +2 -0
  87. package/dist/server.js +11 -7
  88. package/dist/services/activity.js +5 -4
  89. package/dist/services/assets.d.ts +2 -0
  90. package/dist/services/assets.js +9 -4
  91. package/dist/services/authentication.js +17 -9
  92. package/dist/services/collections.js +5 -4
  93. package/dist/services/extensions.d.ts +15 -9
  94. package/dist/services/extensions.js +75 -40
  95. package/dist/services/fields.js +9 -4
  96. package/dist/services/files.d.ts +2 -2
  97. package/dist/services/files.js +22 -14
  98. package/dist/services/graphql/index.js +96 -18
  99. package/dist/services/graphql/subscription.js +2 -2
  100. package/dist/services/graphql/types/bigint.js +16 -5
  101. package/dist/services/graphql/utils/process-error.d.ts +4 -1
  102. package/dist/services/graphql/utils/process-error.js +10 -8
  103. package/dist/services/import-export/index.js +5 -3
  104. package/dist/services/items.js +12 -8
  105. package/dist/services/mail/index.js +4 -2
  106. package/dist/services/notifications.js +7 -3
  107. package/dist/services/payload.js +3 -3
  108. package/dist/services/relations.js +19 -10
  109. package/dist/services/server.js +7 -7
  110. package/dist/services/shares.js +3 -2
  111. package/dist/services/specifications.js +5 -4
  112. package/dist/services/users.js +24 -13
  113. package/dist/services/versions.js +6 -5
  114. package/dist/services/webhooks.d.ts +2 -2
  115. package/dist/services/webhooks.js +2 -2
  116. package/dist/services/websocket.d.ts +1 -1
  117. package/dist/services/websocket.js +4 -3
  118. package/dist/storage/register-drivers.js +2 -1
  119. package/dist/storage/register-locations.js +2 -1
  120. package/dist/synchronization.js +3 -1
  121. package/dist/telemetry/index.d.ts +4 -0
  122. package/dist/telemetry/index.js +4 -0
  123. package/dist/telemetry/lib/get-report.d.ts +5 -0
  124. package/dist/telemetry/lib/get-report.js +42 -0
  125. package/dist/telemetry/lib/init-telemetry.d.ts +11 -0
  126. package/dist/telemetry/lib/init-telemetry.js +30 -0
  127. package/dist/telemetry/lib/send-report.d.ts +5 -0
  128. package/dist/telemetry/lib/send-report.js +23 -0
  129. package/dist/telemetry/lib/track.d.ts +10 -0
  130. package/dist/telemetry/lib/track.js +30 -0
  131. package/dist/telemetry/types/report.d.ts +58 -0
  132. package/dist/telemetry/types/report.js +1 -0
  133. package/dist/telemetry/utils/get-item-count.d.ts +26 -0
  134. package/dist/telemetry/utils/get-item-count.js +36 -0
  135. package/dist/telemetry/utils/get-random-wait-time.d.ts +5 -0
  136. package/dist/telemetry/utils/get-random-wait-time.js +5 -0
  137. package/dist/telemetry/utils/get-user-count.d.ts +7 -0
  138. package/dist/telemetry/utils/get-user-count.js +30 -0
  139. package/dist/telemetry/utils/get-user-item-count.d.ts +13 -0
  140. package/dist/telemetry/utils/get-user-item-count.js +18 -0
  141. package/dist/types/assets.d.ts +2 -0
  142. package/dist/utils/apply-diff.js +2 -1
  143. package/dist/utils/apply-query.js +2 -2
  144. package/dist/utils/delete-from-require-cache.js +2 -1
  145. package/dist/utils/get-accountability-for-token.js +3 -2
  146. package/dist/utils/get-auth-providers.js +2 -1
  147. package/dist/utils/get-cache-headers.js +5 -2
  148. package/dist/utils/get-cache-key.js +1 -1
  149. package/dist/utils/get-config-from-env.js +2 -1
  150. package/dist/utils/get-default-value.js +4 -3
  151. package/dist/utils/get-ip-from-req.d.ts +1 -1
  152. package/dist/utils/get-ip-from-req.js +5 -3
  153. package/dist/utils/get-permissions.js +5 -3
  154. package/dist/utils/get-schema.js +5 -2
  155. package/dist/utils/get-snapshot-diff.js +7 -9
  156. package/dist/utils/get-snapshot.js +5 -5
  157. package/dist/utils/get-versioned-hash.js +1 -1
  158. package/dist/utils/ip-in-networks.d.ts +6 -0
  159. package/dist/utils/ip-in-networks.js +13 -0
  160. package/dist/utils/is-url-allowed.js +2 -1
  161. package/dist/utils/job-queue.d.ts +1 -0
  162. package/dist/utils/job-queue.js +3 -0
  163. package/dist/utils/md.d.ts +1 -1
  164. package/dist/utils/md.js +3 -2
  165. package/dist/utils/sanitize-query.js +7 -2
  166. package/dist/utils/sanitize-schema.d.ts +1 -1
  167. package/dist/utils/should-clear-cache.js +2 -1
  168. package/dist/utils/should-skip-cache.js +2 -1
  169. package/dist/utils/transformations.js +95 -12
  170. package/dist/utils/validate-env.js +4 -2
  171. package/dist/utils/validate-query.js +8 -3
  172. package/dist/utils/validate-snapshot.js +3 -3
  173. package/dist/utils/validate-storage.js +4 -2
  174. package/dist/webhooks.js +4 -3
  175. package/dist/websocket/controllers/base.d.ts +2 -0
  176. package/dist/websocket/controllers/base.js +12 -6
  177. package/dist/websocket/controllers/graphql.d.ts +2 -0
  178. package/dist/websocket/controllers/graphql.js +5 -3
  179. package/dist/websocket/controllers/hooks.js +3 -2
  180. package/dist/websocket/controllers/index.d.ts +2 -0
  181. package/dist/websocket/controllers/index.js +4 -2
  182. package/dist/websocket/controllers/rest.d.ts +2 -0
  183. package/dist/websocket/controllers/rest.js +4 -2
  184. package/dist/websocket/errors.js +2 -1
  185. package/dist/websocket/handlers/heartbeat.js +4 -3
  186. package/dist/websocket/handlers/subscribe.d.ts +2 -2
  187. package/dist/websocket/handlers/subscribe.js +5 -4
  188. package/dist/websocket/types.d.ts +3 -1
  189. package/package.json +114 -115
  190. package/dist/__utils__/items-utils.d.ts +0 -2
  191. package/dist/__utils__/items-utils.js +0 -31
  192. package/dist/__utils__/mock-env.d.ts +0 -18
  193. package/dist/__utils__/mock-env.js +0 -41
  194. package/dist/__utils__/schemas.d.ts +0 -13
  195. package/dist/__utils__/schemas.js +0 -301
  196. package/dist/__utils__/snapshots.d.ts +0 -5
  197. package/dist/__utils__/snapshots.js +0 -903
  198. package/dist/env.d.ts +0 -13
  199. package/dist/env.js +0 -505
  200. package/dist/messenger.d.ts +0 -24
  201. package/dist/messenger.js +0 -64
  202. package/dist/utils/package.d.ts +0 -2
  203. package/dist/utils/package.js +0 -6
  204. package/dist/utils/telemetry.d.ts +0 -1
  205. package/dist/utils/telemetry.js +0 -23
  206. package/dist/utils/to-boolean.d.ts +0 -4
  207. package/dist/utils/to-boolean.js +0 -6
package/dist/env.d.ts DELETED
@@ -1,13 +0,0 @@
1
- /**
2
- * @NOTE
3
- * For all possible keys, see: https://docs.directus.io/self-hosted/config-options/
4
- */
5
- export declare const defaults: Record<string, any>;
6
- declare let env: Record<string, any>;
7
- export default env;
8
- /**
9
- * When changes have been made during runtime, like in the CLI, we can refresh the env object with
10
- * the newly created variables
11
- */
12
- export declare function refreshEnv(): Promise<void>;
13
- export declare function processValues(env: Record<string, any>): Record<string, any>;
package/dist/env.js DELETED
@@ -1,505 +0,0 @@
1
- /**
2
- * @NOTE
3
- * For all possible keys, see: https://docs.directus.io/self-hosted/config-options/
4
- */
5
- import { JAVASCRIPT_FILE_EXTS } from '@directus/constants';
6
- import { parseJSON, toArray } from '@directus/utils';
7
- import dotenv from 'dotenv';
8
- import fs from 'fs';
9
- import { clone, toNumber, toString } from 'lodash-es';
10
- import { createRequire } from 'node:module';
11
- import { pathToFileURL } from 'node:url';
12
- import path from 'path';
13
- import getModuleDefault from './utils/get-module-default.js';
14
- import { requireYAML } from './utils/require-yaml.js';
15
- import { toBoolean } from './utils/to-boolean.js';
16
- const require = createRequire(import.meta.url);
17
- // keeping this here for now to prevent a circular import to constants.ts
18
- const allowedEnvironmentVars = [
19
- // general
20
- 'CONFIG_PATH',
21
- 'HOST',
22
- 'PORT',
23
- 'PUBLIC_URL',
24
- 'LOG_LEVEL',
25
- 'LOG_STYLE',
26
- 'LOG_HTTP_IGNORE_PATHS',
27
- 'MAX_PAYLOAD_SIZE',
28
- 'ROOT_REDIRECT',
29
- 'SERVE_APP',
30
- 'GRAPHQL_INTROSPECTION',
31
- 'MAX_BATCH_MUTATION',
32
- 'LOGGER_.+',
33
- 'QUERY_LIMIT_MAX',
34
- 'QUERY_LIMIT_DEFAULT',
35
- 'ROBOTS_TXT',
36
- 'TEMP_PATH',
37
- // server
38
- 'SERVER_.+',
39
- // database
40
- 'DB_.+',
41
- // security
42
- 'KEY',
43
- 'SECRET',
44
- 'ACCESS_TOKEN_TTL',
45
- 'REFRESH_TOKEN_TTL',
46
- 'REFRESH_TOKEN_COOKIE_DOMAIN',
47
- 'REFRESH_TOKEN_COOKIE_SECURE',
48
- 'REFRESH_TOKEN_COOKIE_SAME_SITE',
49
- 'REFRESH_TOKEN_COOKIE_NAME',
50
- 'REDIS',
51
- 'REDIS_HOST',
52
- 'REDIS_PORT',
53
- 'REDIS_USERNAME',
54
- 'REDIS_PASSWORD',
55
- 'REDIS_DB',
56
- 'LOGIN_STALL_TIME',
57
- 'PASSWORD_RESET_URL_ALLOW_LIST',
58
- 'USER_INVITE_URL_ALLOW_LIST',
59
- 'IP_TRUST_PROXY',
60
- 'IP_CUSTOM_HEADER',
61
- 'ASSETS_CONTENT_SECURITY_POLICY',
62
- 'IMPORT_IP_DENY_LIST',
63
- 'CONTENT_SECURITY_POLICY_.+',
64
- 'HSTS_.+',
65
- // hashing
66
- 'HASH_.+',
67
- // cors
68
- 'CORS_ENABLED',
69
- 'CORS_ORIGIN',
70
- 'CORS_METHODS',
71
- 'CORS_ALLOWED_HEADERS',
72
- 'CORS_EXPOSED_HEADERS',
73
- 'CORS_CREDENTIALS',
74
- 'CORS_MAX_AGE',
75
- // rate limiting
76
- 'RATE_LIMITER_GLOBAL_.+',
77
- 'RATE_LIMITER_.+',
78
- // cache
79
- 'CACHE_ENABLED',
80
- 'CACHE_TTL',
81
- 'CACHE_CONTROL_S_MAXAGE',
82
- 'CACHE_AUTO_PURGE',
83
- 'CACHE_AUTO_PURGE_IGNORE_LIST',
84
- 'CACHE_SYSTEM_TTL',
85
- 'CACHE_SCHEMA',
86
- 'CACHE_PERMISSIONS',
87
- 'CACHE_NAMESPACE',
88
- 'CACHE_STORE',
89
- 'CACHE_STATUS_HEADER',
90
- 'CACHE_VALUE_MAX_SIZE',
91
- 'CACHE_SKIP_ALLOWED',
92
- 'CACHE_HEALTHCHECK_THRESHOLD',
93
- // storage
94
- 'STORAGE_LOCATIONS',
95
- 'STORAGE_.+_DRIVER',
96
- 'STORAGE_.+_ROOT',
97
- 'STORAGE_.+_KEY',
98
- 'STORAGE_.+_SECRET',
99
- 'STORAGE_.+_BUCKET',
100
- 'STORAGE_.+_REGION',
101
- 'STORAGE_.+_ENDPOINT',
102
- 'STORAGE_.+_ACL',
103
- 'STORAGE_.+_CONTAINER_NAME',
104
- 'STORAGE_.+_SERVER_SIDE_ENCRYPTION',
105
- 'STORAGE_.+_ACCOUNT_NAME',
106
- 'STORAGE_.+_ACCOUNT_KEY',
107
- 'STORAGE_.+_ENDPOINT',
108
- 'STORAGE_.+_KEY_FILENAME',
109
- 'STORAGE_.+_BUCKET',
110
- 'STORAGE_.+_HEALTHCHECK_THRESHOLD',
111
- // metadata
112
- 'FILE_METADATA_ALLOW_LIST',
113
- // files
114
- 'FILES_MAX_UPLOAD_SIZE',
115
- 'FILES_CONTENT_TYPE_ALLOW_LIST',
116
- // assets
117
- 'ASSETS_CACHE_TTL',
118
- 'ASSETS_TRANSFORM_MAX_CONCURRENT',
119
- 'ASSETS_TRANSFORM_IMAGE_MAX_DIMENSION',
120
- 'ASSETS_TRANSFORM_MAX_OPERATIONS',
121
- 'ASSETS_TRANSFORM_TIMEOUT',
122
- 'ASSETS_CONTENT_SECURITY_POLICY',
123
- 'ASSETS_INVALID_IMAGE_SENSITIVITY_LEVEL',
124
- // auth
125
- 'AUTH_PROVIDERS',
126
- 'AUTH_DISABLE_DEFAULT',
127
- 'AUTH_.+_DRIVER',
128
- 'AUTH_.+_CLIENT_ID',
129
- 'AUTH_.+_CLIENT_SECRET',
130
- 'AUTH_.+_SCOPE',
131
- 'AUTH_.+_AUTHORIZE_URL',
132
- 'AUTH_.+_ACCESS_URL',
133
- 'AUTH_.+_PROFILE_URL',
134
- 'AUTH_.+_IDENTIFIER_KEY',
135
- 'AUTH_.+_EMAIL_KEY',
136
- 'AUTH_.+_FIRST_NAME_KEY',
137
- 'AUTH_.+_LAST_NAME_KEY',
138
- 'AUTH_.+_ALLOW_PUBLIC_REGISTRATION',
139
- 'AUTH_.+_DEFAULT_ROLE_ID',
140
- 'AUTH_.+_ICON',
141
- 'AUTH_.+_LABEL',
142
- 'AUTH_.+_PARAMS',
143
- 'AUTH_.+_ISSUER_URL',
144
- 'AUTH_.+_AUTH_REQUIRE_VERIFIED_EMAIL',
145
- 'AUTH_.+_CLIENT_URL',
146
- 'AUTH_.+_BIND_DN',
147
- 'AUTH_.+_BIND_PASSWORD',
148
- 'AUTH_.+_USER_DN',
149
- 'AUTH_.+_USER_ATTRIBUTE',
150
- 'AUTH_.+_USER_SCOPE',
151
- 'AUTH_.+_MAIL_ATTRIBUTE',
152
- 'AUTH_.+_FIRST_NAME_ATTRIBUTE',
153
- 'AUTH_.+_LAST_NAME_ATTRIBUTE',
154
- 'AUTH_.+_GROUP_DN',
155
- 'AUTH_.+_GROUP_ATTRIBUTE',
156
- 'AUTH_.+_GROUP_SCOPE',
157
- 'AUTH_.+_IDP.+',
158
- 'AUTH_.+_SP.+',
159
- // extensions
160
- 'PACKAGE_FILE_LOCATION',
161
- 'EXTENSIONS_LOCATION',
162
- 'EXTENSIONS_PATH',
163
- 'EXTENSIONS_AUTO_RELOAD',
164
- 'EXTENSIONS_CACHE_TTL',
165
- 'EXTENSIONS_SANDBOX_MEMORY',
166
- 'EXTENSIONS_SANDBOX_TIMEOUT',
167
- // messenger
168
- 'MESSENGER_STORE',
169
- 'MESSENGER_NAMESPACE',
170
- // synchronization
171
- 'SYNCHRONIZATION_STORE',
172
- 'SYNCHRONIZATION_NAMESPACE',
173
- // emails
174
- 'EMAIL_FROM',
175
- 'EMAIL_TRANSPORT',
176
- 'EMAIL_VERIFY_SETUP',
177
- 'EMAIL_SENDMAIL_NEW_LINE',
178
- 'EMAIL_SENDMAIL_PATH',
179
- 'EMAIL_SMTP_NAME',
180
- 'EMAIL_SMTP_HOST',
181
- 'EMAIL_SMTP_PORT',
182
- 'EMAIL_SMTP_USER',
183
- 'EMAIL_SMTP_PASSWORD',
184
- 'EMAIL_SMTP_POOL',
185
- 'EMAIL_SMTP_SECURE',
186
- 'EMAIL_SMTP_IGNORE_TLS',
187
- 'EMAIL_MAILGUN_API_KEY',
188
- 'EMAIL_MAILGUN_DOMAIN',
189
- 'EMAIL_MAILGUN_HOST',
190
- 'EMAIL_SENDGRID_API_KEY',
191
- 'EMAIL_SES_CREDENTIALS__ACCESS_KEY_ID',
192
- 'EMAIL_SES_CREDENTIALS__SECRET_ACCESS_KEY',
193
- 'EMAIL_SES_REGION',
194
- // admin account
195
- 'ADMIN_EMAIL',
196
- 'ADMIN_PASSWORD',
197
- // telemetry
198
- 'TELEMETRY',
199
- // limits & optimization
200
- 'RELATIONAL_BATCH_SIZE',
201
- 'EXPORT_BATCH_SIZE',
202
- // flows
203
- 'FLOWS_ENV_ALLOW_LIST',
204
- 'FLOWS_RUN_SCRIPT_MAX_MEMORY',
205
- 'FLOWS_RUN_SCRIPT_TIMEOUT',
206
- // websockets
207
- 'WEBSOCKETS_.+',
208
- ].map((name) => new RegExp(`^${name}$`));
209
- const acceptedEnvTypes = ['string', 'number', 'regex', 'array', 'json'];
210
- export const defaults = {
211
- CONFIG_PATH: path.resolve(process.cwd(), '.env'),
212
- HOST: '0.0.0.0',
213
- PORT: 8055,
214
- PUBLIC_URL: '/',
215
- MAX_PAYLOAD_SIZE: '1mb',
216
- MAX_RELATIONAL_DEPTH: 10,
217
- QUERY_LIMIT_DEFAULT: 100,
218
- MAX_BATCH_MUTATION: Infinity,
219
- ROBOTS_TXT: 'User-agent: *\nDisallow: /',
220
- TEMP_PATH: './node_modules/.directus',
221
- DB_EXCLUDE_TABLES: 'spatial_ref_sys,sysdiagrams',
222
- STORAGE_LOCATIONS: 'local',
223
- STORAGE_LOCAL_DRIVER: 'local',
224
- STORAGE_LOCAL_ROOT: './uploads',
225
- RATE_LIMITER_ENABLED: false,
226
- RATE_LIMITER_POINTS: 50,
227
- RATE_LIMITER_DURATION: 1,
228
- RATE_LIMITER_STORE: 'memory',
229
- RATE_LIMITER_GLOBAL_ENABLED: false,
230
- RATE_LIMITER_GLOBAL_POINTS: 1000,
231
- RATE_LIMITER_GLOBAL_DURATION: 1,
232
- RATE_LIMITER_GLOBAL_STORE: 'memory',
233
- ACCESS_TOKEN_TTL: '15m',
234
- REFRESH_TOKEN_TTL: '7d',
235
- REFRESH_TOKEN_COOKIE_SECURE: false,
236
- REFRESH_TOKEN_COOKIE_SAME_SITE: 'lax',
237
- REFRESH_TOKEN_COOKIE_NAME: 'directus_refresh_token',
238
- LOGIN_STALL_TIME: 500,
239
- SERVER_SHUTDOWN_TIMEOUT: 1000,
240
- ROOT_REDIRECT: './admin',
241
- CORS_ENABLED: false,
242
- CORS_ORIGIN: false,
243
- CORS_METHODS: 'GET,POST,PATCH,DELETE',
244
- CORS_ALLOWED_HEADERS: 'Content-Type,Authorization',
245
- CORS_EXPOSED_HEADERS: 'Content-Range',
246
- CORS_CREDENTIALS: true,
247
- CORS_MAX_AGE: 18000,
248
- CACHE_ENABLED: false,
249
- CACHE_STORE: 'memory',
250
- CACHE_TTL: '5m',
251
- CACHE_NAMESPACE: 'system-cache',
252
- CACHE_AUTO_PURGE: false,
253
- CACHE_AUTO_PURGE_IGNORE_LIST: 'directus_activity,directus_presets',
254
- CACHE_CONTROL_S_MAXAGE: '0',
255
- CACHE_SCHEMA: true,
256
- CACHE_PERMISSIONS: true,
257
- CACHE_VALUE_MAX_SIZE: false,
258
- CACHE_SKIP_ALLOWED: false,
259
- AUTH_PROVIDERS: '',
260
- AUTH_DISABLE_DEFAULT: false,
261
- PACKAGE_FILE_LOCATION: '.',
262
- EXTENSIONS_PATH: './extensions',
263
- EXTENSIONS_AUTO_RELOAD: false,
264
- EXTENSIONS_SANDBOX_MEMORY: 100,
265
- EXTENSIONS_SANDBOX_TIMEOUT: 1000,
266
- EMAIL_FROM: 'no-reply@example.com',
267
- EMAIL_VERIFY_SETUP: true,
268
- EMAIL_TRANSPORT: 'sendmail',
269
- EMAIL_SENDMAIL_NEW_LINE: 'unix',
270
- EMAIL_SENDMAIL_PATH: '/usr/sbin/sendmail',
271
- TELEMETRY: true,
272
- ASSETS_CACHE_TTL: '30d',
273
- ASSETS_TRANSFORM_MAX_CONCURRENT: 25,
274
- ASSETS_TRANSFORM_IMAGE_MAX_DIMENSION: 6000,
275
- ASSETS_TRANSFORM_MAX_OPERATIONS: 5,
276
- ASSETS_TRANSFORM_TIMEOUT: '7500ms',
277
- ASSETS_INVALID_IMAGE_SENSITIVITY_LEVEL: 'warning',
278
- IP_TRUST_PROXY: true,
279
- IP_CUSTOM_HEADER: false,
280
- IMPORT_IP_DENY_LIST: ['0.0.0.0', '169.254.169.254'],
281
- SERVE_APP: true,
282
- RELATIONAL_BATCH_SIZE: 25000,
283
- EXPORT_BATCH_SIZE: 5000,
284
- FILE_METADATA_ALLOW_LIST: 'ifd0.Make,ifd0.Model,exif.FNumber,exif.ExposureTime,exif.FocalLength,exif.ISO',
285
- GRAPHQL_INTROSPECTION: true,
286
- WEBSOCKETS_ENABLED: false,
287
- WEBSOCKETS_REST_ENABLED: true,
288
- WEBSOCKETS_REST_AUTH: 'handshake',
289
- WEBSOCKETS_REST_AUTH_TIMEOUT: 10,
290
- WEBSOCKETS_REST_PATH: '/websocket',
291
- WEBSOCKETS_GRAPHQL_ENABLED: true,
292
- WEBSOCKETS_GRAPHQL_AUTH: 'handshake',
293
- WEBSOCKETS_GRAPHQL_AUTH_TIMEOUT: 10,
294
- WEBSOCKETS_GRAPHQL_PATH: '/graphql',
295
- WEBSOCKETS_HEARTBEAT_ENABLED: true,
296
- WEBSOCKETS_HEARTBEAT_PERIOD: 30,
297
- FLOWS_ENV_ALLOW_LIST: false,
298
- FLOWS_RUN_SCRIPT_MAX_MEMORY: 32,
299
- FLOWS_RUN_SCRIPT_TIMEOUT: 10000,
300
- PRESSURE_LIMITER_ENABLED: true,
301
- PRESSURE_LIMITER_SAMPLE_INTERVAL: 250,
302
- PRESSURE_LIMITER_MAX_EVENT_LOOP_UTILIZATION: 0.99,
303
- PRESSURE_LIMITER_MAX_EVENT_LOOP_DELAY: 500,
304
- PRESSURE_LIMITER_MAX_MEMORY_RSS: false,
305
- PRESSURE_LIMITER_MAX_MEMORY_HEAP_USED: false,
306
- PRESSURE_LIMITER_RETRY_AFTER: false,
307
- FILES_MIME_TYPE_ALLOW_LIST: '*/*',
308
- };
309
- /**
310
- * Allows us to force certain environment variable into a type, instead of relying
311
- * on the auto-parsed type in processValues.
312
- */
313
- const typeMap = {
314
- HOST: 'string',
315
- PORT: 'string',
316
- DB_NAME: 'string',
317
- DB_USER: 'string',
318
- DB_PASSWORD: 'string',
319
- DB_DATABASE: 'string',
320
- DB_PORT: 'number',
321
- DB_EXCLUDE_TABLES: 'array',
322
- CACHE_SKIP_ALLOWED: 'boolean',
323
- CACHE_AUTO_PURGE_IGNORE_LIST: 'array',
324
- IMPORT_IP_DENY_LIST: 'array',
325
- FILE_METADATA_ALLOW_LIST: 'array',
326
- GRAPHQL_INTROSPECTION: 'boolean',
327
- MAX_BATCH_MUTATION: 'number',
328
- SERVER_SHUTDOWN_TIMEOUT: 'number',
329
- LOG_HTTP_IGNORE_PATHS: 'array',
330
- };
331
- let env = {
332
- ...defaults,
333
- ...process.env,
334
- ...(await processConfiguration()),
335
- };
336
- process.env = env;
337
- env = processValues(env);
338
- export default env;
339
- /**
340
- * When changes have been made during runtime, like in the CLI, we can refresh the env object with
341
- * the newly created variables
342
- */
343
- export async function refreshEnv() {
344
- env = {
345
- ...defaults,
346
- ...process.env,
347
- ...(await processConfiguration()),
348
- };
349
- process.env = env;
350
- env = processValues(env);
351
- }
352
- async function processConfiguration() {
353
- const configPath = path.resolve(process.env['CONFIG_PATH'] || defaults['CONFIG_PATH']);
354
- if (fs.existsSync(configPath) === false)
355
- return {};
356
- const fileExt = path.extname(configPath).toLowerCase().substring(1);
357
- if (JAVASCRIPT_FILE_EXTS.includes(fileExt)) {
358
- const data = await import(pathToFileURL(configPath).toString());
359
- const config = getModuleDefault(data);
360
- if (typeof config === 'function') {
361
- return config(process.env);
362
- }
363
- else if (typeof config === 'object') {
364
- return config;
365
- }
366
- throw new Error(`Invalid JS configuration file export type. Requires one of "function", "object", received: "${typeof config}"`);
367
- }
368
- if (fileExt === 'json') {
369
- return require(configPath);
370
- }
371
- if (fileExt === 'yaml' || fileExt === 'yml') {
372
- const data = requireYAML(configPath);
373
- if (typeof data === 'object') {
374
- return data;
375
- }
376
- throw new Error('Invalid YAML configuration. Root has to be an object.');
377
- }
378
- // Default to env vars plain text files
379
- return dotenv.parse(fs.readFileSync(configPath, { encoding: 'utf8' }));
380
- }
381
- function getVariableType(variable) {
382
- return variable.split(':').slice(0, -1)[0];
383
- }
384
- function getEnvVariableValue(variableValue, variableType) {
385
- return variableValue.split(`${variableType}:`)[1];
386
- }
387
- function getEnvironmentValueWithPrefix(envArray) {
388
- return envArray.map((item) => {
389
- if (isEnvSyntaxPrefixPresent(item)) {
390
- return getEnvironmentValueByType(item);
391
- }
392
- return item;
393
- });
394
- }
395
- function getEnvironmentValueByType(envVariableString) {
396
- const variableType = getVariableType(envVariableString);
397
- const envVariableValue = getEnvVariableValue(envVariableString, variableType);
398
- switch (variableType) {
399
- case 'number':
400
- return toNumber(envVariableValue);
401
- case 'array':
402
- return getEnvironmentValueWithPrefix(toArray(envVariableValue));
403
- case 'regex':
404
- return new RegExp(envVariableValue);
405
- case 'string':
406
- return envVariableValue;
407
- case 'json':
408
- return tryJSON(envVariableValue);
409
- }
410
- }
411
- function isEnvSyntaxPrefixPresent(value) {
412
- return acceptedEnvTypes.some((envType) => value.includes(`${envType}:`));
413
- }
414
- export function processValues(env) {
415
- env = clone(env);
416
- for (let [key, value] of Object.entries(env)) {
417
- // If key ends with '_FILE', try to get the value from the file defined in this variable
418
- // and store it in the variable with the same name but without '_FILE' at the end
419
- let newKey;
420
- if (key.length > 5 && key.endsWith('_FILE')) {
421
- newKey = key.slice(0, -5);
422
- if (allowedEnvironmentVars.some((pattern) => pattern.test(newKey))) {
423
- if (newKey in env && !(newKey in defaults && env[newKey] === defaults[newKey])) {
424
- throw new Error(`Duplicate environment variable encountered: you can't use "${newKey}" and "${key}" simultaneously.`);
425
- }
426
- try {
427
- value = fs.readFileSync(value, { encoding: 'utf8' });
428
- key = newKey;
429
- }
430
- catch {
431
- throw new Error(`Failed to read value from file "${value}", defined in environment variable "${key}".`);
432
- }
433
- }
434
- }
435
- // Convert values with a type prefix
436
- // (see https://docs.directus.io/reference/environment-variables/#environment-syntax-prefix)
437
- if (typeof value === 'string' && isEnvSyntaxPrefixPresent(value)) {
438
- env[key] = getEnvironmentValueByType(value);
439
- continue;
440
- }
441
- // Convert values where the key is defined in typeMap
442
- if (typeMap[key]) {
443
- switch (typeMap[key]) {
444
- case 'number':
445
- env[key] = toNumber(value);
446
- break;
447
- case 'string':
448
- env[key] = toString(value);
449
- break;
450
- case 'array':
451
- env[key] = toArray(value);
452
- break;
453
- case 'json':
454
- env[key] = tryJSON(value);
455
- break;
456
- case 'boolean':
457
- env[key] = toBoolean(value);
458
- }
459
- continue;
460
- }
461
- // Try to convert remaining values:
462
- // - boolean values to boolean
463
- // - 'null' to null
464
- // - number values (> 0 <= Number.MAX_SAFE_INTEGER) to number
465
- if (value === 'true') {
466
- env[key] = true;
467
- continue;
468
- }
469
- if (value === 'false') {
470
- env[key] = false;
471
- continue;
472
- }
473
- if (value === 'null') {
474
- env[key] = null;
475
- continue;
476
- }
477
- if (String(value).startsWith('0') === false &&
478
- isNaN(value) === false &&
479
- value.length > 0 &&
480
- value <= Number.MAX_SAFE_INTEGER) {
481
- env[key] = Number(value);
482
- continue;
483
- }
484
- if (String(value).includes(',')) {
485
- env[key] = toArray(value);
486
- continue;
487
- }
488
- // Try converting the value to a JS object. This allows JSON objects to be passed for nested
489
- // config flags, or custom param names (that aren't camelCased)
490
- env[key] = tryJSON(value);
491
- // If '_FILE' variable hasn't been processed yet, store it as it is (string)
492
- if (newKey) {
493
- env[key] = value;
494
- }
495
- }
496
- return env;
497
- }
498
- function tryJSON(value) {
499
- try {
500
- return parseJSON(value);
501
- }
502
- catch {
503
- return value;
504
- }
505
- }
@@ -1,24 +0,0 @@
1
- import { Redis } from 'ioredis';
2
- export type MessengerSubscriptionCallback = (payload: Record<string, any>) => void;
3
- export interface Messenger {
4
- publish: (channel: string, payload: Record<string, any>) => void;
5
- subscribe: (channel: string, callback: MessengerSubscriptionCallback) => void;
6
- unsubscribe: (channel: string, callback?: MessengerSubscriptionCallback) => void;
7
- }
8
- export declare class MessengerMemory implements Messenger {
9
- handlers: Record<string, Set<MessengerSubscriptionCallback>>;
10
- constructor();
11
- publish(channel: string, payload: Record<string, any>): void;
12
- subscribe(channel: string, callback: MessengerSubscriptionCallback): void;
13
- unsubscribe(channel: string, callback?: MessengerSubscriptionCallback): void;
14
- }
15
- export declare class MessengerRedis implements Messenger {
16
- namespace: string;
17
- pub: Redis;
18
- sub: Redis;
19
- constructor();
20
- publish(channel: string, payload: Record<string, any>): void;
21
- subscribe(channel: string, callback: MessengerSubscriptionCallback): void;
22
- unsubscribe(channel: string): void;
23
- }
24
- export declare function getMessenger(): Messenger;
package/dist/messenger.js DELETED
@@ -1,64 +0,0 @@
1
- import { parseJSON } from '@directus/utils';
2
- import { Redis } from 'ioredis';
3
- import env from './env.js';
4
- import { getConfigFromEnv } from './utils/get-config-from-env.js';
5
- export class MessengerMemory {
6
- handlers;
7
- constructor() {
8
- this.handlers = {};
9
- }
10
- publish(channel, payload) {
11
- this.handlers[channel]?.forEach((callback) => callback(payload));
12
- }
13
- subscribe(channel, callback) {
14
- if (!this.handlers[channel])
15
- this.handlers[channel] = new Set();
16
- this.handlers[channel]?.add(callback);
17
- }
18
- unsubscribe(channel, callback) {
19
- if (!callback) {
20
- delete this.handlers[channel];
21
- }
22
- else {
23
- this.handlers[channel]?.delete(callback);
24
- }
25
- }
26
- }
27
- export class MessengerRedis {
28
- namespace;
29
- pub;
30
- sub;
31
- constructor() {
32
- const config = getConfigFromEnv('REDIS');
33
- this.pub = new Redis(env['REDIS'] ?? config);
34
- this.sub = new Redis(env['REDIS'] ?? config);
35
- this.namespace = env['MESSENGER_NAMESPACE'] ?? 'directus-messenger';
36
- }
37
- publish(channel, payload) {
38
- this.pub.publish(`${this.namespace}:${channel}`, JSON.stringify(payload));
39
- }
40
- subscribe(channel, callback) {
41
- this.sub.subscribe(`${this.namespace}:${channel}`);
42
- this.sub.on('message', (messageChannel, payloadString) => {
43
- const payload = parseJSON(payloadString);
44
- if (messageChannel === `${this.namespace}:${channel}`) {
45
- callback(payload);
46
- }
47
- });
48
- }
49
- unsubscribe(channel) {
50
- this.sub.unsubscribe(`${this.namespace}:${channel}`);
51
- }
52
- }
53
- let messenger;
54
- export function getMessenger() {
55
- if (messenger)
56
- return messenger;
57
- if (env['MESSENGER_STORE'] === 'redis') {
58
- messenger = new MessengerRedis();
59
- }
60
- else {
61
- messenger = new MessengerMemory();
62
- }
63
- return messenger;
64
- }
@@ -1,2 +0,0 @@
1
- declare const name: string, version: string;
2
- export { name, version };
@@ -1,6 +0,0 @@
1
- import { readFileSync } from 'node:fs';
2
- import { dirname, resolve } from 'node:path';
3
- import { fileURLToPath } from 'node:url';
4
- const __dirname = dirname(fileURLToPath(import.meta.url));
5
- const { name, version } = JSON.parse(readFileSync(resolve(__dirname, '../../package.json'), 'utf8'));
6
- export { name, version };
@@ -1 +0,0 @@
1
- export declare function collectTelemetry(): Promise<void>;
@@ -1,23 +0,0 @@
1
- import mid from 'node-machine-id';
2
- import env from '../env.js';
3
- import logger from '../logger.js';
4
- import { version } from './package.js';
5
- export async function collectTelemetry() {
6
- const axios = (await import('axios')).default;
7
- if (env['TELEMETRY'] !== false) {
8
- try {
9
- await axios.post('https://telemetry.directus.io/', {
10
- version: version,
11
- public_url: env['PUBLIC_URL'],
12
- project_id: env['KEY'],
13
- machine_id: await mid.machineId(),
14
- db_client: env['DB_CLIENT'],
15
- });
16
- }
17
- catch (err) {
18
- if (env['NODE_ENV'] === 'development') {
19
- logger.error(err);
20
- }
21
- }
22
- }
23
- }
@@ -1,4 +0,0 @@
1
- /**
2
- * Convert environment variable to Boolean
3
- */
4
- export declare function toBoolean(value: any): boolean;
@@ -1,6 +0,0 @@
1
- /**
2
- * Convert environment variable to Boolean
3
- */
4
- export function toBoolean(value) {
5
- return value === 'true' || value === true || value === '1' || value === 1;
6
- }