knex 0.21.5 → 0.21.6

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # Master (Unreleased)
2
2
 
3
+ # 0.21.6 - 27 September, 2020
4
+
5
+ ### New features:
6
+
7
+ - CLI: New config parameter / CLI flag to prefixing seed filename with timestamp #3873
8
+ - CLI: throw an error when specific seed file cannot be found #4011
9
+ - Warn if whereNot is used with 'in' or 'between' #4038
10
+
11
+ ### Bug fixes:
12
+
13
+ - CLI: Fix double merging of config for migrator #4040
14
+
15
+ ### Typings:
16
+
17
+ - Unify SeedsConfig and SeederConfig #4003
18
+ - Allow string[] type for directory in SeedsConfig #4033
19
+
3
20
  # 0.21.5 - 17 August, 2020
4
21
 
5
22
  ### New features:
package/bin/cli.js CHANGED
@@ -93,7 +93,11 @@ function invoke(env) {
93
93
  'environment, default: process.env.NODE_ENV || development'
94
94
  )
95
95
  .option('--esm', 'Enable ESM interop.')
96
- .option('--specific [path]', 'Specify one seed file to execute.');
96
+ .option('--specific [path]', 'Specify one seed file to execute.')
97
+ .option(
98
+ '--timestamp-filename-prefix',
99
+ 'Enable a timestamp prefix on name of generated seed files.'
100
+ );
97
101
 
98
102
  commander
99
103
  .command('init')
@@ -300,6 +304,11 @@ function invoke(env) {
300
304
  `--stub [<relative/path/from/knexfile>|<name>]`,
301
305
  'Specify the seed stub to use. If using <name> the file must be located in config.seeds.directory'
302
306
  )
307
+ .option(
308
+ '--timestamp-filename-prefix',
309
+ 'Enable a timestamp prefix on name of generated seed files.',
310
+ false
311
+ )
303
312
  .action(async (name) => {
304
313
  const opts = commander.opts();
305
314
  opts.client = opts.client || 'sqlite3'; // We don't really care about client when creating seeds
@@ -311,6 +320,10 @@ function invoke(env) {
311
320
  configOverrides.stub = stub;
312
321
  }
313
322
 
323
+ if (opts.timestampFilenamePrefix) {
324
+ configOverrides.timestampFilenamePrefix = opts.timestampFilenamePrefix;
325
+ }
326
+
314
327
  instance.seed
315
328
  .make(name, configOverrides)
316
329
  .then((name) => {
@@ -2,6 +2,7 @@ const path = require('path');
2
2
  const { writeJsFileUsingTemplate } = require('../util/template');
3
3
  const { getMergedConfig } = require('./configuration-merger');
4
4
  const { ensureDirectoryExists } = require('../util/fs');
5
+ const { yyyymmddhhmmss } = require('../util/timestamp');
5
6
 
6
7
  class MigrationGenerator {
7
8
  constructor(migrationConfig, logger) {
@@ -79,24 +80,4 @@ class MigrationGenerator {
79
80
  }
80
81
  }
81
82
 
82
- // Ensure that we have 2 places for each of the date segments.
83
- function padDate(segment) {
84
- segment = segment.toString();
85
- return segment[1] ? segment : `0${segment}`;
86
- }
87
-
88
- // Get a date object in the correct format, without requiring a full out library
89
- // like "moment.js".
90
- function yyyymmddhhmmss() {
91
- const d = new Date();
92
- return (
93
- d.getFullYear().toString() +
94
- padDate(d.getMonth() + 1) +
95
- padDate(d.getDate()) +
96
- padDate(d.getHours()) +
97
- padDate(d.getMinutes()) +
98
- padDate(d.getSeconds())
99
- );
100
- }
101
-
102
83
  module.exports = MigrationGenerator;
@@ -307,8 +307,7 @@ class Migrator {
307
307
 
308
308
  // Creates a new migration, with a given name.
309
309
  make(name, config) {
310
- this.config = getMergedConfig(config, this.config, this.knex.client.logger);
311
- return this.generator.make(name, this.config, this.knex.client.logger);
310
+ return this.generator.make(name, config, this.knex.client.logger);
312
311
  }
313
312
 
314
313
  _disableProcessing() {
@@ -29,14 +29,16 @@ function getMergedConfig(config, currentConfig, logger = defaultLogger) {
29
29
  if (
30
30
  config &&
31
31
  // If user specifies any FS related config,
32
- // clear existing FsMigrations migrationSource
32
+ // clear specified migrationSource to avoid ambiguity
33
33
  (config.directory ||
34
34
  config.sortDirsSeparately !== undefined ||
35
35
  config.loadExtensions)
36
36
  ) {
37
- logger.warn(
38
- 'FS-related option specified for migration configuration. This resets migrationSource to default FsMigrations'
39
- );
37
+ if (config.migrationSource) {
38
+ logger.warn(
39
+ 'FS-related option specified for migration configuration. This resets migrationSource to default FsMigrations'
40
+ );
41
+ }
40
42
  mergedConfig.migrationSource = null;
41
43
  }
42
44
 
@@ -371,6 +371,13 @@ assign(Builder.prototype, {
371
371
 
372
372
  // Adds an `not where` clause to the query.
373
373
  whereNot() {
374
+ if (arguments.length >= 2) {
375
+ if (arguments[1] === 'in' || arguments[1] === 'between') {
376
+ this.client.logger.warn(
377
+ 'whereNot is not suitable for "in" and "between" type subqueries. You should use "not in" and "not between" instead.'
378
+ );
379
+ }
380
+ }
374
381
  return this._not(true).where.apply(this, arguments);
375
382
  },
376
383
 
@@ -7,6 +7,7 @@ const extend = require('lodash/extend');
7
7
  const includes = require('lodash/includes');
8
8
  const { ensureDirectoryExists, getFilepathsInFolder } = require('../util/fs');
9
9
  const { writeJsFileUsingTemplate } = require('../util/template');
10
+ const { yyyymmddhhmmss } = require('../util/timestamp');
10
11
 
11
12
  const filterByLoadExtensions = (extensions) => (value) => {
12
13
  const extension = path.extname(value);
@@ -25,11 +26,15 @@ class Seeder {
25
26
  // Runs seed files for the given environment.
26
27
  async run(config) {
27
28
  this.config = this.setConfig(config);
28
- const all = await this._listAll();
29
- const files =
30
- config && config.specific
31
- ? all.filter((file) => path.basename(file) === config.specific)
32
- : all;
29
+ let files = await this._listAll();
30
+ if (config && config.specific) {
31
+ files = files.filter((file) => path.basename(file) === config.specific);
32
+ if (files.length === 0) {
33
+ throw new Error(
34
+ `Invalid argument provided: the specific seed "${config.specific}" does not exist.`
35
+ );
36
+ }
37
+ }
33
38
  return this._runSeeds(files);
34
39
  }
35
40
 
@@ -99,7 +104,12 @@ class Seeder {
99
104
 
100
105
  _getNewStubFileName(name) {
101
106
  if (name[0] === '-') name = name.slice(1);
102
- return name + '.' + this.config.extension;
107
+
108
+ if (this.config.timestampFilenamePrefix === true) {
109
+ name = `${yyyymmddhhmmss()}_${name}`;
110
+ }
111
+
112
+ return `${name}.${this.config.extension}`;
103
113
  }
104
114
 
105
115
  _getNewStubFilePath(name) {
@@ -181,6 +191,7 @@ class Seeder {
181
191
  '.ls',
182
192
  '.ts',
183
193
  ],
194
+ timestampFilenamePrefix: false,
184
195
  sortDirsSeparately: false,
185
196
  recursive: false,
186
197
  },
@@ -0,0 +1,16 @@
1
+ // Get a date object in the correct format, without requiring a full out library
2
+ // like "moment.js".
3
+ function yyyymmddhhmmss() {
4
+ const d = new Date();
5
+
6
+ return (
7
+ d.getFullYear().toString() +
8
+ (d.getMonth() + 1).toString().padStart(2, '0') +
9
+ d.getDate().toString().padStart(2, '0') +
10
+ d.getHours().toString().padStart(2, '0') +
11
+ d.getMinutes().toString().padStart(2, '0') +
12
+ d.getSeconds().toString().padStart(2, '0')
13
+ );
14
+ }
15
+
16
+ module.exports = { yyyymmddhhmmss };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "knex",
3
- "version": "0.21.5",
3
+ "version": "0.21.6",
4
4
  "description": "A batteries-included SQL query & schema builder for Postgres, MySQL and SQLite3 and the Browser",
5
5
  "main": "knex.js",
6
6
  "types": "types/index.d.ts",
@@ -79,7 +79,7 @@
79
79
  ]
80
80
  },
81
81
  "devDependencies": {
82
- "@types/node": "^14.0.27",
82
+ "@types/node": "^14.11.1",
83
83
  "JSONStream": "^1.3.5",
84
84
  "chai": "^4.2.0",
85
85
  "chai-as-promised": "^7.1.1",
@@ -88,22 +88,22 @@
88
88
  "coveralls": "^3.1.0",
89
89
  "cross-env": "^7.0.2",
90
90
  "dtslint": "3.6.14",
91
- "eslint": "^7.6.0",
91
+ "eslint": "^7.9.0",
92
92
  "eslint-config-prettier": "^6.11.0",
93
93
  "eslint-plugin-import": "^2.22.0",
94
- "husky": "^4.2.5",
94
+ "husky": "^4.3.0",
95
95
  "jake": "^8.1.1",
96
- "lint-staged": "^10.2.11",
97
- "mocha": "^8.1.1",
98
- "mock-fs": "^4.12.0",
99
- "mssql": "^6.2.1",
96
+ "lint-staged": "^10.4.0",
97
+ "mocha": "^8.1.3",
98
+ "mock-fs": "^4.13.0",
99
+ "mssql": "^6.2.2",
100
100
  "mysql": "^2.18.1",
101
- "mysql2": "^2.1.0",
101
+ "mysql2": "^2.2.2",
102
102
  "nyc": "^15.1.0",
103
103
  "oracledb": "^5.0.0",
104
- "pg": "^8.3.0",
105
- "pg-query-stream": "^3.2.0",
106
- "prettier": "2.0.5",
104
+ "pg": "^8.3.3",
105
+ "pg-query-stream": "^3.2.3",
106
+ "prettier": "2.1.2",
107
107
  "rimraf": "^3.0.2",
108
108
  "sinon": "^9.0.3",
109
109
  "sinon-chai": "^3.5.0",
package/types/index.d.ts CHANGED
@@ -1699,7 +1699,7 @@ declare namespace Knex {
1699
1699
  origImpl: (value: string) => string,
1700
1700
  queryContext: any
1701
1701
  ) => string;
1702
- seeds?: SeedsConfig<SV>;
1702
+ seeds?: SeederConfig<SV>;
1703
1703
  acquireConnectionTimeout?: number;
1704
1704
  useNullAsDefault?: boolean;
1705
1705
  searchPath?: string | readonly string[];
@@ -1943,14 +1943,6 @@ declare namespace Knex {
1943
1943
  migrationSource?: MigrationSource<unknown>;
1944
1944
  }
1945
1945
 
1946
- interface SeedsConfig<V extends {} = any> {
1947
- directory?: string;
1948
- extension?: string;
1949
- loadExtensions?: readonly string[];
1950
- stub?: string;
1951
- variables?: V;
1952
- }
1953
-
1954
1946
  interface Migrator {
1955
1947
  make(name: string, config?: MigratorConfig): Promise<string>;
1956
1948
  latest(config?: MigratorConfig): Promise<any>;
@@ -1963,13 +1955,16 @@ declare namespace Knex {
1963
1955
  forceFreeMigrationsLock(config?: MigratorConfig): Promise<any>;
1964
1956
  }
1965
1957
 
1966
- interface SeederConfig {
1958
+ interface SeederConfig<V extends {} = any> {
1967
1959
  extension?: string;
1968
- directory?: string | string[];
1960
+ directory?: string | readonly string[];
1969
1961
  loadExtensions?: readonly string[];
1970
1962
  specific?: string;
1963
+ timestampFilenamePrefix?: boolean;
1971
1964
  recursive?: boolean;
1972
1965
  sortDirsSeparately?: boolean;
1966
+ stub?: string;
1967
+ variables?: V;
1973
1968
  }
1974
1969
 
1975
1970
  class Seeder {