directus 9.7.1 → 9.9.1

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 (103) hide show
  1. package/dist/__mocks__/cache.d.ts +5 -0
  2. package/dist/__mocks__/cache.js +7 -0
  3. package/dist/auth/drivers/ldap.js +10 -11
  4. package/dist/auth/drivers/oauth2.js +9 -4
  5. package/dist/auth/drivers/openid.js +7 -4
  6. package/dist/cache.js +2 -2
  7. package/dist/cli/commands/schema/apply.js +9 -3
  8. package/dist/controllers/assets.js +5 -0
  9. package/dist/controllers/files.d.ts +2 -0
  10. package/dist/controllers/files.js +13 -5
  11. package/dist/database/helpers/date/dialects/default.d.ts +3 -0
  12. package/dist/database/helpers/date/dialects/default.js +7 -0
  13. package/dist/database/helpers/date/dialects/mssql.d.ts +1 -9
  14. package/dist/database/helpers/date/dialects/mssql.js +4 -23
  15. package/dist/database/helpers/date/dialects/mysql.d.ts +2 -9
  16. package/dist/database/helpers/date/dialects/mysql.js +7 -22
  17. package/dist/database/helpers/date/dialects/oracle.d.ts +1 -9
  18. package/dist/database/helpers/date/dialects/oracle.js +7 -23
  19. package/dist/database/helpers/date/dialects/sqlite.d.ts +1 -9
  20. package/dist/database/helpers/date/dialects/sqlite.js +8 -24
  21. package/dist/database/helpers/date/index.d.ts +4 -4
  22. package/dist/database/helpers/date/index.js +9 -9
  23. package/dist/database/helpers/date/types.d.ts +3 -9
  24. package/dist/database/helpers/date/types.js +10 -0
  25. package/dist/database/helpers/fn/dialects/mssql.d.ts +13 -0
  26. package/dist/database/helpers/fn/dialects/mssql.js +42 -0
  27. package/dist/database/helpers/{date/dialects/postgres.d.ts → fn/dialects/mysql.d.ts} +3 -2
  28. package/dist/database/helpers/fn/dialects/mysql.js +42 -0
  29. package/dist/database/helpers/fn/dialects/oracle.d.ts +13 -0
  30. package/dist/database/helpers/fn/dialects/oracle.js +42 -0
  31. package/dist/database/helpers/fn/dialects/postgres.d.ts +13 -0
  32. package/dist/database/helpers/{date → fn}/dialects/postgres.js +18 -3
  33. package/dist/database/helpers/fn/dialects/sqlite.d.ts +13 -0
  34. package/dist/database/helpers/fn/dialects/sqlite.js +42 -0
  35. package/dist/database/helpers/fn/index.d.ts +7 -0
  36. package/dist/database/helpers/fn/index.js +17 -0
  37. package/dist/database/helpers/fn/types.d.ts +18 -0
  38. package/dist/database/helpers/fn/types.js +27 -0
  39. package/dist/database/helpers/index.d.ts +4 -1
  40. package/dist/database/helpers/index.js +7 -1
  41. package/dist/database/migrations/20220308A-add-bookmark-icon-and-color.d.ts +3 -0
  42. package/dist/database/migrations/20220308A-add-bookmark-icon-and-color.js +17 -0
  43. package/dist/database/migrations/20220322A-rename-field-typecast-flags.js +6 -2
  44. package/dist/database/migrations/20220323A-add-field-validation.d.ts +3 -0
  45. package/dist/database/migrations/20220323A-add-field-validation.js +17 -0
  46. package/dist/database/migrations/20220325A-fix-typecast-flags.d.ts +3 -0
  47. package/dist/database/migrations/20220325A-fix-typecast-flags.js +49 -0
  48. package/dist/database/migrations/20220325B-add-default-language.d.ts +3 -0
  49. package/dist/database/migrations/20220325B-add-default-language.js +28 -0
  50. package/dist/database/migrations/20220402A-remove-default-value-panel-icon.d.ts +3 -0
  51. package/dist/database/migrations/20220402A-remove-default-value-panel-icon.js +22 -0
  52. package/dist/database/run-ast.js +7 -5
  53. package/dist/database/system-data/fields/activity.yaml +4 -4
  54. package/dist/database/system-data/fields/collections.yaml +1 -1
  55. package/dist/database/system-data/fields/fields.yaml +9 -0
  56. package/dist/database/system-data/fields/presets.yaml +14 -0
  57. package/dist/database/system-data/fields/settings.yaml +12 -1
  58. package/dist/database/system-data/fields/users.yaml +3 -0
  59. package/dist/env.js +5 -3
  60. package/dist/exceptions/index.d.ts +1 -0
  61. package/dist/exceptions/index.js +1 -0
  62. package/dist/exceptions/token-expired.d.ts +4 -0
  63. package/dist/exceptions/token-expired.js +10 -0
  64. package/dist/logger.js +2 -1
  65. package/dist/middleware/cache.js +10 -0
  66. package/dist/services/activity.js +4 -1
  67. package/dist/services/authorization.d.ts +1 -1
  68. package/dist/services/authorization.js +174 -48
  69. package/dist/services/collections.d.ts +2 -0
  70. package/dist/services/collections.js +232 -198
  71. package/dist/services/fields.js +210 -174
  72. package/dist/services/files.d.ts +5 -1
  73. package/dist/services/files.js +59 -40
  74. package/dist/services/graphql.d.ts +2 -3
  75. package/dist/services/graphql.js +53 -10
  76. package/dist/services/items.js +5 -3
  77. package/dist/services/payload.d.ts +2 -1
  78. package/dist/services/payload.js +28 -21
  79. package/dist/services/relations.js +93 -81
  80. package/dist/services/server.js +1 -0
  81. package/dist/services/shares.js +2 -1
  82. package/dist/services/specifications.js +1 -3
  83. package/dist/services/users.js +7 -2
  84. package/dist/types/files.d.ts +8 -0
  85. package/dist/utils/apply-query.js +38 -10
  86. package/dist/utils/apply-snapshot.d.ts +3 -1
  87. package/dist/utils/apply-snapshot.js +34 -5
  88. package/dist/utils/get-ast-from-query.js +15 -3
  89. package/dist/utils/get-column.d.ts +6 -5
  90. package/dist/utils/get-column.js +16 -8
  91. package/dist/utils/get-graphql-type.js +1 -0
  92. package/dist/utils/get-local-type.js +5 -0
  93. package/dist/utils/get-schema.d.ts +1 -1
  94. package/dist/utils/get-schema.js +18 -10
  95. package/dist/utils/jwt.js +1 -1
  96. package/dist/utils/reduce-schema.js +20 -12
  97. package/dist/utils/track.js +3 -2
  98. package/dist/utils/url.d.ts +1 -1
  99. package/dist/utils/url.js +1 -1
  100. package/dist/utils/validate-query.js +19 -15
  101. package/dist/utils/validate-storage.js +3 -1
  102. package/example.env +4 -0
  103. package/package.json +14 -13
@@ -0,0 +1,5 @@
1
+ /// <reference types="jest" />
2
+ export declare const getCache: jest.Mock<any, any>;
3
+ export declare const flushCaches: jest.Mock<any, any>;
4
+ export declare const clearSystemCache: jest.Mock<any, any>;
5
+ export declare const setSystemCache: jest.Mock<any, any>;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.setSystemCache = exports.clearSystemCache = exports.flushCaches = exports.getCache = void 0;
4
+ exports.getCache = jest.fn().mockReturnValue({ cache: undefined, systemCache: undefined, lockCache: undefined });
5
+ exports.flushCaches = jest.fn();
6
+ exports.clearSystemCache = jest.fn();
7
+ exports.setSystemCache = jest.fn();
@@ -71,12 +71,8 @@ class LDAPAuthDriver extends auth_1.AuthDriver {
71
71
  res.on('searchEntry', () => {
72
72
  resolve();
73
73
  });
74
- res.on('error', (err) => {
75
- if (!(err instanceof ldapjs_1.OperationsError)) {
76
- reject(handleError(err));
77
- return;
78
- }
79
- // Rebind on OperationsError
74
+ res.on('error', () => {
75
+ // Attempt to rebind on search error
80
76
  this.bindClient.bind(bindDn, bindPassword, (err) => {
81
77
  if (err) {
82
78
  const error = handleError(err);
@@ -93,8 +89,8 @@ class LDAPAuthDriver extends auth_1.AuthDriver {
93
89
  });
94
90
  });
95
91
  res.on('end', (result) => {
92
+ // Handle edge case where authenticated bind user cannot read their own DN
96
93
  if ((result === null || result === void 0 ? void 0 : result.status) === 0) {
97
- // Handle edge case where authenticated bind user could not fetch their own DN
98
94
  reject(new exceptions_1.UnexpectedResponseException('Failed to find bind user record'));
99
95
  }
100
96
  });
@@ -177,12 +173,12 @@ class LDAPAuthDriver extends auth_1.AuthDriver {
177
173
  return user === null || user === void 0 ? void 0 : user.id;
178
174
  }
179
175
  async getUserID(payload) {
180
- var _a;
176
+ var _a, _b, _c;
181
177
  if (!payload.identifier) {
182
178
  throw new exceptions_1.InvalidCredentialsException();
183
179
  }
184
180
  await this.validateBindClient();
185
- const { userDn, userScope, userAttribute, groupDn, groupScope, groupAttribute } = this.config;
181
+ const { userDn, userScope, userAttribute, groupDn, groupScope, groupAttribute, defaultRoleId } = this.config;
186
182
  const userInfo = await this.fetchUserInfo(userDn, new ldapjs_1.EqualityFilter({
187
183
  attribute: userAttribute !== null && userAttribute !== void 0 ? userAttribute : 'cn',
188
184
  value: payload.identifier,
@@ -209,7 +205,10 @@ class LDAPAuthDriver extends auth_1.AuthDriver {
209
205
  }
210
206
  const userId = await this.fetchUserId(userInfo.dn);
211
207
  if (userId) {
212
- await this.usersService.updateOne(userId, { role: (_a = userRole === null || userRole === void 0 ? void 0 : userRole.id) !== null && _a !== void 0 ? _a : null });
208
+ // Only sync roles if the AD groups are configured
209
+ if (groupDn) {
210
+ await this.usersService.updateOne(userId, { role: (_b = (_a = userRole === null || userRole === void 0 ? void 0 : userRole.id) !== null && _a !== void 0 ? _a : defaultRoleId) !== null && _b !== void 0 ? _b : null });
211
+ }
213
212
  return userId;
214
213
  }
215
214
  if (!userInfo) {
@@ -221,7 +220,7 @@ class LDAPAuthDriver extends auth_1.AuthDriver {
221
220
  last_name: userInfo.lastName,
222
221
  email: userInfo.email,
223
222
  external_identifier: userInfo.dn,
224
- role: userRole === null || userRole === void 0 ? void 0 : userRole.id,
223
+ role: (_c = userRole === null || userRole === void 0 ? void 0 : userRole.id) !== null && _c !== void 0 ? _c : defaultRoleId,
225
224
  });
226
225
  return (await this.fetchUserId(userInfo.dn));
227
226
  }
@@ -8,6 +8,7 @@ const express_1 = require("express");
8
8
  const openid_client_1 = require("openid-client");
9
9
  const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
10
10
  const ms_1 = __importDefault(require("ms"));
11
+ const flat_1 = __importDefault(require("flat"));
11
12
  const local_1 = require("./local");
12
13
  const auth_1 = require("../../auth");
13
14
  const env_1 = __importDefault(require("../../env"));
@@ -91,12 +92,14 @@ class OAuth2AuthDriver extends local_1.LocalAuthDriver {
91
92
  catch (e) {
92
93
  throw handleError(e);
93
94
  }
94
- const { emailKey, identifierKey, allowPublicRegistration } = this.config;
95
+ // Flatten response to support dot indexes
96
+ userInfo = (0, flat_1.default)(userInfo);
97
+ const { provider, emailKey, identifierKey, allowPublicRegistration } = this.config;
95
98
  const email = userInfo[emailKey !== null && emailKey !== void 0 ? emailKey : 'email'];
96
99
  // Fallback to email if explicit identifier not found
97
100
  const identifier = (_a = userInfo[identifierKey]) !== null && _a !== void 0 ? _a : email;
98
101
  if (!identifier) {
99
- logger_1.default.warn(`[OAuth2] Failed to find user identifier for provider "${this.config.provider}"`);
102
+ logger_1.default.warn(`[OAuth2] Failed to find user identifier for provider "${provider}"`);
100
103
  throw new exceptions_1.InvalidCredentialsException();
101
104
  }
102
105
  const userId = await this.fetchUserId(identifier);
@@ -111,11 +114,13 @@ class OAuth2AuthDriver extends local_1.LocalAuthDriver {
111
114
  }
112
115
  // Is public registration allowed?
113
116
  if (!allowPublicRegistration) {
114
- logger_1.default.trace(`[OAuth2] User doesn't exist, and public registration not allowed for provider "${this.config.provider}"`);
117
+ logger_1.default.trace(`[OAuth2] User doesn't exist, and public registration not allowed for provider "${provider}"`);
115
118
  throw new exceptions_1.InvalidCredentialsException();
116
119
  }
117
120
  await this.usersService.createOne({
118
- provider: this.config.provider,
121
+ provider,
122
+ first_name: userInfo[this.config.firstNameKey],
123
+ last_name: userInfo[this.config.lastNameKey],
119
124
  email: email,
120
125
  external_identifier: identifier,
121
126
  role: this.config.defaultRoleId,
@@ -8,6 +8,7 @@ const express_1 = require("express");
8
8
  const openid_client_1 = require("openid-client");
9
9
  const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
10
10
  const ms_1 = __importDefault(require("ms"));
11
+ const flat_1 = __importDefault(require("flat"));
11
12
  const local_1 = require("./local");
12
13
  const auth_1 = require("../../auth");
13
14
  const env_1 = __importDefault(require("../../env"));
@@ -105,12 +106,14 @@ class OpenIDAuthDriver extends local_1.LocalAuthDriver {
105
106
  catch (e) {
106
107
  throw handleError(e);
107
108
  }
108
- const { identifierKey, allowPublicRegistration, requireVerifiedEmail } = this.config;
109
+ // Flatten response to support dot indexes
110
+ userInfo = (0, flat_1.default)(userInfo);
111
+ const { provider, identifierKey, allowPublicRegistration, requireVerifiedEmail } = this.config;
109
112
  const email = userInfo.email;
110
113
  // Fallback to email if explicit identifier not found
111
114
  const identifier = (_a = userInfo[identifierKey !== null && identifierKey !== void 0 ? identifierKey : 'sub']) !== null && _a !== void 0 ? _a : email;
112
115
  if (!identifier) {
113
- logger_1.default.warn(`[OpenID] Failed to find user identifier for provider "${this.config.provider}"`);
116
+ logger_1.default.warn(`[OpenID] Failed to find user identifier for provider "${provider}"`);
114
117
  throw new exceptions_1.InvalidCredentialsException();
115
118
  }
116
119
  const userId = await this.fetchUserId(identifier);
@@ -126,11 +129,11 @@ class OpenIDAuthDriver extends local_1.LocalAuthDriver {
126
129
  const isEmailVerified = !requireVerifiedEmail || userInfo.email_verified;
127
130
  // Is public registration allowed?
128
131
  if (!allowPublicRegistration || !isEmailVerified) {
129
- logger_1.default.trace(`[OpenID] User doesn't exist, and public registration not allowed for provider "${this.config.provider}"`);
132
+ logger_1.default.trace(`[OpenID] User doesn't exist, and public registration not allowed for provider "${provider}"`);
130
133
  throw new exceptions_1.InvalidCredentialsException();
131
134
  }
132
135
  await this.usersService.createOne({
133
- provider: this.config.provider,
136
+ provider,
134
137
  first_name: userInfo.given_name,
135
138
  last_name: userInfo.family_name,
136
139
  email: email,
package/dist/cache.js CHANGED
@@ -16,11 +16,11 @@ let lockCache = null;
16
16
  function getCache() {
17
17
  if (env_1.default.CACHE_ENABLED === true && cache === null) {
18
18
  (0, validate_env_1.validateEnv)(['CACHE_NAMESPACE', 'CACHE_TTL', 'CACHE_STORE']);
19
- cache = getKeyvInstance((0, ms_1.default)(env_1.default.CACHE_TTL));
19
+ cache = getKeyvInstance(env_1.default.CACHE_TTL ? (0, ms_1.default)(env_1.default.CACHE_TTL) : undefined);
20
20
  cache.on('error', (err) => logger_1.default.warn(err, `[cache] ${err}`));
21
21
  }
22
22
  if (systemCache === null) {
23
- systemCache = getKeyvInstance(undefined, '_system');
23
+ systemCache = getKeyvInstance(env_1.default.CACHE_SYSTEM_TTL ? (0, ms_1.default)(env_1.default.CACHE_SYSTEM_TTL) : undefined, '_system');
24
24
  systemCache.on('error', (err) => logger_1.default.warn(err, `[cache] ${err}`));
25
25
  }
26
26
  if (lockCache === null) {
@@ -93,13 +93,19 @@ async function apply(snapshotPath, options) {
93
93
  if (snapshotDiff.fields.length > 0) {
94
94
  message += '\n\n' + chalk_1.default.black.underline.bold('Fields:');
95
95
  for (const { collection, field, diff } of snapshotDiff.fields) {
96
- if (((_e = diff[0]) === null || _e === void 0 ? void 0 : _e.kind) === 'E') {
96
+ if (((_e = diff[0]) === null || _e === void 0 ? void 0 : _e.kind) === 'E' || (0, apply_snapshot_1.isNestedMetaUpdate)(diff[0])) {
97
97
  message += `\n - ${chalk_1.default.blue('Update')} ${collection}.${field}`;
98
98
  for (const change of diff) {
99
+ const path = change.path.slice(1).join('.');
99
100
  if (change.kind === 'E') {
100
- const path = change.path.slice(1).join('.');
101
101
  message += `\n - Set ${path} to ${change.rhs}`;
102
102
  }
103
+ else if (change.kind === 'D') {
104
+ message += `\n - Remove ${path}`;
105
+ }
106
+ else if (change.kind === 'N') {
107
+ message += `\n - Add ${path} and set it to ${change.rhs}`;
108
+ }
103
109
  }
104
110
  }
105
111
  else if (((_f = diff[0]) === null || _f === void 0 ? void 0 : _f.kind) === 'D') {
@@ -143,7 +149,7 @@ async function apply(snapshotPath, options) {
143
149
  }
144
150
  }
145
151
  }
146
- message += 'The following changes will be applied:\n\n' + chalk_1.default.black(message);
152
+ message = 'The following changes will be applied:\n\n' + chalk_1.default.black(message);
147
153
  if (dryRun) {
148
154
  logger_1.default.info(message);
149
155
  process.exit(0);
@@ -126,6 +126,11 @@ router.get('/:pk',
126
126
  res.setHeader('Content-Type', file.type);
127
127
  res.setHeader('Accept-Ranges', 'bytes');
128
128
  res.setHeader('Cache-Control', `${access}, max-age=${(0, ms_1.default)(env_1.default.ASSETS_CACHE_TTL) / 1000}`);
129
+ const unixTime = Date.parse(file.modified_on);
130
+ if (!Number.isNaN(unixTime)) {
131
+ const lastModifiedDate = new Date(unixTime);
132
+ res.setHeader('Last-Modified', lastModifiedDate.toUTCString());
133
+ }
129
134
  if (range) {
130
135
  res.setHeader('Content-Range', `bytes ${range.start}-${range.end || stat.size - 1}/${stat.size}`);
131
136
  res.status(206);
@@ -1,2 +1,4 @@
1
+ import { RequestHandler } from 'express';
1
2
  declare const router: import("express-serve-static-core").Router;
3
+ export declare const multipartHandler: RequestHandler;
2
4
  export default router;
@@ -3,7 +3,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.multipartHandler = void 0;
6
7
  const format_title_1 = __importDefault(require("@directus/format-title"));
8
+ const utils_1 = require("@directus/shared/utils");
7
9
  const busboy_1 = __importDefault(require("busboy"));
8
10
  const express_1 = __importDefault(require("express"));
9
11
  const joi_1 = __importDefault(require("joi"));
@@ -15,10 +17,9 @@ const use_collection_1 = __importDefault(require("../middleware/use-collection")
15
17
  const validate_batch_1 = require("../middleware/validate-batch");
16
18
  const services_1 = require("../services");
17
19
  const async_handler_1 = __importDefault(require("../utils/async-handler"));
18
- const utils_1 = require("@directus/shared/utils");
19
20
  const router = express_1.default.Router();
20
21
  router.use((0, use_collection_1.default)('directus_files'));
21
- const multipartHandler = (0, async_handler_1.default)(async (req, res, next) => {
22
+ const multipartHandler = (req, res, next) => {
22
23
  if (req.is('multipart/form-data') === false)
23
24
  return next();
24
25
  let headers;
@@ -57,6 +58,9 @@ const multipartHandler = (0, async_handler_1.default)(async (req, res, next) =>
57
58
  payload[fieldname] = fieldValue;
58
59
  });
59
60
  busboy.on('file', async (fieldname, fileStream, filename, encoding, mimetype) => {
61
+ if (!filename) {
62
+ return busboy.emit('error', new exceptions_1.InvalidPayloadException(`File is missing filename`));
63
+ }
60
64
  fileCount++;
61
65
  if (!payload.title) {
62
66
  payload.title = (0, format_title_1.default)(path_1.default.parse(filename).name);
@@ -87,12 +91,16 @@ const multipartHandler = (0, async_handler_1.default)(async (req, res, next) =>
87
91
  req.pipe(busboy);
88
92
  function tryDone() {
89
93
  if (savedFiles.length === fileCount) {
94
+ if (fileCount === 0) {
95
+ return next(new exceptions_1.InvalidPayloadException(`No files where included in the body`));
96
+ }
90
97
  res.locals.savedFiles = savedFiles;
91
98
  return next();
92
99
  }
93
100
  }
94
- });
95
- router.post('/', multipartHandler, (0, async_handler_1.default)(async (req, res, next) => {
101
+ };
102
+ exports.multipartHandler = multipartHandler;
103
+ router.post('/', (0, async_handler_1.default)(exports.multipartHandler), (0, async_handler_1.default)(async (req, res, next) => {
96
104
  if (req.is('multipart/form-data') === false) {
97
105
  throw new exceptions_1.UnsupportedMediaTypeException(`Unsupported Content-Type header`);
98
106
  }
@@ -214,7 +222,7 @@ router.patch('/', (0, validate_batch_1.validateBatch)('update'), (0, async_handl
214
222
  }
215
223
  return next();
216
224
  }), respond_1.respond);
217
- router.patch('/:pk', multipartHandler, (0, async_handler_1.default)(async (req, res, next) => {
225
+ router.patch('/:pk', (0, async_handler_1.default)(exports.multipartHandler), (0, async_handler_1.default)(async (req, res, next) => {
218
226
  const service = new services_1.FilesService({
219
227
  accountability: req.accountability,
220
228
  schema: req.schema,
@@ -0,0 +1,3 @@
1
+ import { DateHelper } from '../types';
2
+ export declare class DateHelperDefault extends DateHelper {
3
+ }
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DateHelperDefault = void 0;
4
+ const types_1 = require("../types");
5
+ class DateHelperDefault extends types_1.DateHelper {
6
+ }
7
+ exports.DateHelperDefault = DateHelperDefault;
@@ -1,12 +1,4 @@
1
1
  import { DateHelper } from '../types';
2
- import { Knex } from 'knex';
3
2
  export declare class DateHelperMSSQL extends DateHelper {
4
- year(table: string, column: string): Knex.Raw;
5
- month(table: string, column: string): Knex.Raw;
6
- week(table: string, column: string): Knex.Raw;
7
- day(table: string, column: string): Knex.Raw;
8
- weekday(table: string, column: string): Knex.Raw;
9
- hour(table: string, column: string): Knex.Raw;
10
- minute(table: string, column: string): Knex.Raw;
11
- second(table: string, column: string): Knex.Raw;
3
+ writeTimestamp(date: string): Date;
12
4
  }
@@ -2,30 +2,11 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.DateHelperMSSQL = void 0;
4
4
  const types_1 = require("../types");
5
+ const date_fns_1 = require("date-fns");
5
6
  class DateHelperMSSQL extends types_1.DateHelper {
6
- year(table, column) {
7
- return this.knex.raw('DATEPART(year, ??.??)', [table, column]);
8
- }
9
- month(table, column) {
10
- return this.knex.raw('DATEPART(month, ??.??)', [table, column]);
11
- }
12
- week(table, column) {
13
- return this.knex.raw('DATEPART(week, ??.??)', [table, column]);
14
- }
15
- day(table, column) {
16
- return this.knex.raw('DATEPART(day, ??.??)', [table, column]);
17
- }
18
- weekday(table, column) {
19
- return this.knex.raw('DATEPART(weekday, ??.??)', [table, column]);
20
- }
21
- hour(table, column) {
22
- return this.knex.raw('DATEPART(hour, ??.??)', [table, column]);
23
- }
24
- minute(table, column) {
25
- return this.knex.raw('DATEPART(minute, ??.??)', [table, column]);
26
- }
27
- second(table, column) {
28
- return this.knex.raw('DATEPART(second, ??.??)', [table, column]);
7
+ writeTimestamp(date) {
8
+ const parsedDate = (0, date_fns_1.parseISO)(date);
9
+ return new Date(parsedDate.getTime() + parsedDate.getTimezoneOffset() * 60000);
29
10
  }
30
11
  }
31
12
  exports.DateHelperMSSQL = DateHelperMSSQL;
@@ -1,12 +1,5 @@
1
1
  import { DateHelper } from '../types';
2
- import { Knex } from 'knex';
3
2
  export declare class DateHelperMySQL extends DateHelper {
4
- year(table: string, column: string): Knex.Raw;
5
- month(table: string, column: string): Knex.Raw;
6
- week(table: string, column: string): Knex.Raw;
7
- day(table: string, column: string): Knex.Raw;
8
- weekday(table: string, column: string): Knex.Raw;
9
- hour(table: string, column: string): Knex.Raw;
10
- minute(table: string, column: string): Knex.Raw;
11
- second(table: string, column: string): Knex.Raw;
3
+ readTimestampString(date: string): string;
4
+ writeTimestamp(date: string): Date;
12
5
  }
@@ -2,30 +2,15 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.DateHelperMySQL = void 0;
4
4
  const types_1 = require("../types");
5
+ const date_fns_1 = require("date-fns");
5
6
  class DateHelperMySQL extends types_1.DateHelper {
6
- year(table, column) {
7
- return this.knex.raw('YEAR(??.??)', [table, column]);
7
+ readTimestampString(date) {
8
+ const parsedDate = new Date(date);
9
+ return new Date(parsedDate.getTime() - parsedDate.getTimezoneOffset() * 60000).toISOString();
8
10
  }
9
- month(table, column) {
10
- return this.knex.raw('MONTH(??.??)', [table, column]);
11
- }
12
- week(table, column) {
13
- return this.knex.raw('WEEK(??.??)', [table, column]);
14
- }
15
- day(table, column) {
16
- return this.knex.raw('DAYOFMONTH(??.??)', [table, column]);
17
- }
18
- weekday(table, column) {
19
- return this.knex.raw('DAYOFWEEK(??.??)', [table, column]);
20
- }
21
- hour(table, column) {
22
- return this.knex.raw('HOUR(??.??)', [table, column]);
23
- }
24
- minute(table, column) {
25
- return this.knex.raw('MINUTE(??.??)', [table, column]);
26
- }
27
- second(table, column) {
28
- return this.knex.raw('SECOND(??.??)', [table, column]);
11
+ writeTimestamp(date) {
12
+ const parsedDate = (0, date_fns_1.parseISO)(date);
13
+ return new Date(parsedDate.getTime() + parsedDate.getTimezoneOffset() * 60000);
29
14
  }
30
15
  }
31
16
  exports.DateHelperMySQL = DateHelperMySQL;
@@ -1,12 +1,4 @@
1
1
  import { DateHelper } from '../types';
2
- import { Knex } from 'knex';
3
2
  export declare class DateHelperOracle extends DateHelper {
4
- year(table: string, column: string): Knex.Raw;
5
- month(table: string, column: string): Knex.Raw;
6
- week(table: string, column: string): Knex.Raw;
7
- day(table: string, column: string): Knex.Raw;
8
- weekday(table: string, column: string): Knex.Raw;
9
- hour(table: string, column: string): Knex.Raw;
10
- minute(table: string, column: string): Knex.Raw;
11
- second(table: string, column: string): Knex.Raw;
3
+ fieldFlagForField(fieldType: string): string;
12
4
  }
@@ -3,29 +3,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.DateHelperOracle = void 0;
4
4
  const types_1 = require("../types");
5
5
  class DateHelperOracle extends types_1.DateHelper {
6
- year(table, column) {
7
- return this.knex.raw("TO_CHAR(??.??, 'IYYY')", [table, column]);
8
- }
9
- month(table, column) {
10
- return this.knex.raw("TO_CHAR(??.??, 'MM')", [table, column]);
11
- }
12
- week(table, column) {
13
- return this.knex.raw("TO_CHAR(??.??, 'IW')", [table, column]);
14
- }
15
- day(table, column) {
16
- return this.knex.raw("TO_CHAR(??.??, 'DD')", [table, column]);
17
- }
18
- weekday(table, column) {
19
- return this.knex.raw("TO_CHAR(??.??, 'D')", [table, column]);
20
- }
21
- hour(table, column) {
22
- return this.knex.raw("TO_CHAR(??.??, 'HH24')", [table, column]);
23
- }
24
- minute(table, column) {
25
- return this.knex.raw("TO_CHAR(??.??, 'MI')", [table, column]);
26
- }
27
- second(table, column) {
28
- return this.knex.raw("TO_CHAR(??.??, 'SS')", [table, column]);
6
+ fieldFlagForField(fieldType) {
7
+ switch (fieldType) {
8
+ case 'dateTime':
9
+ return 'cast-datetime';
10
+ default:
11
+ return '';
12
+ }
29
13
  }
30
14
  }
31
15
  exports.DateHelperOracle = DateHelperOracle;
@@ -1,13 +1,5 @@
1
1
  import { DateHelper } from '../types';
2
- import { Knex } from 'knex';
3
2
  export declare class DateHelperSQLite extends DateHelper {
4
- year(table: string, column: string): Knex.Raw;
5
- month(table: string, column: string): Knex.Raw;
6
- week(table: string, column: string): Knex.Raw;
7
- day(table: string, column: string): Knex.Raw;
8
- weekday(table: string, column: string): Knex.Raw;
9
- hour(table: string, column: string): Knex.Raw;
10
- minute(table: string, column: string): Knex.Raw;
11
- second(table: string, column: string): Knex.Raw;
12
3
  parse(date: string): string;
4
+ fieldFlagForField(fieldType: string): string;
13
5
  }
@@ -3,33 +3,17 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.DateHelperSQLite = void 0;
4
4
  const types_1 = require("../types");
5
5
  class DateHelperSQLite extends types_1.DateHelper {
6
- year(table, column) {
7
- return this.knex.raw("strftime('%Y', ??.?? / 1000, 'unixepoch')", [table, column]);
8
- }
9
- month(table, column) {
10
- return this.knex.raw("strftime('%m', ??.?? / 1000, 'unixepoch')", [table, column]);
11
- }
12
- week(table, column) {
13
- return this.knex.raw("strftime('%W', ??.?? / 1000, 'unixepoch')", [table, column]);
14
- }
15
- day(table, column) {
16
- return this.knex.raw("strftime('%d', ??.?? / 1000, 'unixepoch')", [table, column]);
17
- }
18
- weekday(table, column) {
19
- return this.knex.raw("strftime('%w', ??.?? / 1000, 'unixepoch')", [table, column]);
20
- }
21
- hour(table, column) {
22
- return this.knex.raw("strftime('%H', ??.?? / 1000, 'unixepoch')", [table, column]);
23
- }
24
- minute(table, column) {
25
- return this.knex.raw("strftime('%M', ??.?? / 1000, 'unixepoch')", [table, column]);
26
- }
27
- second(table, column) {
28
- return this.knex.raw("strftime('%S', ??.?? / 1000, 'unixepoch')", [table, column]);
29
- }
30
6
  parse(date) {
31
7
  const newDate = new Date(date);
32
8
  return (newDate.getTime() - newDate.getTimezoneOffset() * 60 * 1000).toString();
33
9
  }
10
+ fieldFlagForField(fieldType) {
11
+ switch (fieldType) {
12
+ case 'timestamp':
13
+ return 'cast-timestamp';
14
+ default:
15
+ return '';
16
+ }
17
+ }
34
18
  }
35
19
  exports.DateHelperSQLite = DateHelperSQLite;
@@ -1,7 +1,7 @@
1
- export { DateHelperPostgres as postgres } from './dialects/postgres';
2
- export { DateHelperPostgres as redshift } from './dialects/postgres';
3
- export { DateHelperPostgres as cockroachdb } from './dialects/postgres';
1
+ export { DateHelperDefault as postgres } from './dialects/default';
2
+ export { DateHelperDefault as redshift } from './dialects/default';
3
+ export { DateHelperDefault as cockroachdb } from './dialects/default';
4
4
  export { DateHelperOracle as oracle } from './dialects/oracle';
5
- export { DateHelperSQLite as sqlite } from './dialects/sqlite';
6
5
  export { DateHelperMySQL as mysql } from './dialects/mysql';
7
6
  export { DateHelperMSSQL as mssql } from './dialects/mssql';
7
+ export { DateHelperSQLite as sqlite } from './dialects/sqlite';
@@ -1,17 +1,17 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.mssql = exports.mysql = exports.sqlite = exports.oracle = exports.cockroachdb = exports.redshift = exports.postgres = void 0;
4
- var postgres_1 = require("./dialects/postgres");
5
- Object.defineProperty(exports, "postgres", { enumerable: true, get: function () { return postgres_1.DateHelperPostgres; } });
6
- var postgres_2 = require("./dialects/postgres");
7
- Object.defineProperty(exports, "redshift", { enumerable: true, get: function () { return postgres_2.DateHelperPostgres; } });
8
- var postgres_3 = require("./dialects/postgres");
9
- Object.defineProperty(exports, "cockroachdb", { enumerable: true, get: function () { return postgres_3.DateHelperPostgres; } });
3
+ exports.sqlite = exports.mssql = exports.mysql = exports.oracle = exports.cockroachdb = exports.redshift = exports.postgres = void 0;
4
+ var default_1 = require("./dialects/default");
5
+ Object.defineProperty(exports, "postgres", { enumerable: true, get: function () { return default_1.DateHelperDefault; } });
6
+ var default_2 = require("./dialects/default");
7
+ Object.defineProperty(exports, "redshift", { enumerable: true, get: function () { return default_2.DateHelperDefault; } });
8
+ var default_3 = require("./dialects/default");
9
+ Object.defineProperty(exports, "cockroachdb", { enumerable: true, get: function () { return default_3.DateHelperDefault; } });
10
10
  var oracle_1 = require("./dialects/oracle");
11
11
  Object.defineProperty(exports, "oracle", { enumerable: true, get: function () { return oracle_1.DateHelperOracle; } });
12
- var sqlite_1 = require("./dialects/sqlite");
13
- Object.defineProperty(exports, "sqlite", { enumerable: true, get: function () { return sqlite_1.DateHelperSQLite; } });
14
12
  var mysql_1 = require("./dialects/mysql");
15
13
  Object.defineProperty(exports, "mysql", { enumerable: true, get: function () { return mysql_1.DateHelperMySQL; } });
16
14
  var mssql_1 = require("./dialects/mssql");
17
15
  Object.defineProperty(exports, "mssql", { enumerable: true, get: function () { return mssql_1.DateHelperMSSQL; } });
16
+ var sqlite_1 = require("./dialects/sqlite");
17
+ Object.defineProperty(exports, "sqlite", { enumerable: true, get: function () { return sqlite_1.DateHelperSQLite; } });
@@ -1,13 +1,7 @@
1
1
  import { DatabaseHelper } from '../types';
2
- import { Knex } from 'knex';
3
2
  export declare abstract class DateHelper extends DatabaseHelper {
4
- abstract year(table: string, column: string): Knex.Raw;
5
- abstract month(table: string, column: string): Knex.Raw;
6
- abstract week(table: string, column: string): Knex.Raw;
7
- abstract day(table: string, column: string): Knex.Raw;
8
- abstract weekday(table: string, column: string): Knex.Raw;
9
- abstract hour(table: string, column: string): Knex.Raw;
10
- abstract minute(table: string, column: string): Knex.Raw;
11
- abstract second(table: string, column: string): Knex.Raw;
12
3
  parse(date: string): string;
4
+ readTimestampString(date: string): string;
5
+ writeTimestamp(date: string): Date;
6
+ fieldFlagForField(_fieldType: string): string;
13
7
  }
@@ -2,9 +2,19 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.DateHelper = void 0;
4
4
  const types_1 = require("../types");
5
+ const date_fns_1 = require("date-fns");
5
6
  class DateHelper extends types_1.DatabaseHelper {
6
7
  parse(date) {
7
8
  return date;
8
9
  }
10
+ readTimestampString(date) {
11
+ return date;
12
+ }
13
+ writeTimestamp(date) {
14
+ return (0, date_fns_1.parseISO)(date);
15
+ }
16
+ fieldFlagForField(_fieldType) {
17
+ return '';
18
+ }
9
19
  }
10
20
  exports.DateHelper = DateHelper;
@@ -0,0 +1,13 @@
1
+ import { FnHelper } from '../types';
2
+ import { Knex } from 'knex';
3
+ export declare class FnHelperMSSQL extends FnHelper {
4
+ year(table: string, column: string): Knex.Raw;
5
+ month(table: string, column: string): Knex.Raw;
6
+ week(table: string, column: string): Knex.Raw;
7
+ day(table: string, column: string): Knex.Raw;
8
+ weekday(table: string, column: string): Knex.Raw;
9
+ hour(table: string, column: string): Knex.Raw;
10
+ minute(table: string, column: string): Knex.Raw;
11
+ second(table: string, column: string): Knex.Raw;
12
+ count(table: string, column: string): Knex.Raw<any>;
13
+ }