Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: update deps & nodejs 22 #2573

Merged
merged 17 commits into from
Jan 8, 2025
Merged
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/release.workflow.yaml
Original file line number Diff line number Diff line change
@@ -17,7 +17,7 @@ jobs:
runs-on: ubuntu-24.04
strategy:
matrix:
node-version: [16, 18, 20]
node-version: [18, 20, 22]
steps:
- uses: actions/checkout@v4

12 changes: 6 additions & 6 deletions .github/workflows/workflow-deployments.yml
Original file line number Diff line number Diff line change
@@ -6,19 +6,19 @@ on:
node_lts_maintenance_version:
description: "Maintenance Node LTS Version"
required: true
default: "16"
default: "18"
type: string

node_lts_active_version:
description: "Active Node LTS Version"
required: true
default: "18"
default: "20"
type: string

node_lts_current_version:
description: "Current Node LTS Version"
required: true
default: "20"
default: "22"
type: string

workflow_dispatch:
@@ -38,19 +38,19 @@ on:
node_lts_maintenance_version:
description: "Maintenance Node LTS Version"
required: true
default: "16"
default: "18"
type: string

node_lts_active_version:
description: "Active Node LTS Version"
required: true
default: "18"
default: "20"
type: string

node_lts_current_version:
description: "Current Node LTS Version"
required: true
default: "20"
default: "22"
type: string

jobs:
7 changes: 4 additions & 3 deletions .github/workflows/workflow.yaml
Original file line number Diff line number Diff line change
@@ -8,9 +8,10 @@ on:
pull_request:

env:
NODE_LTS_MAINTENANCE_VERSION: "16"
NODE_LTS_ACTIVE_VERSION: "18"
NODE_LTS_CURRENT_VERSION: "20"
DOCKER_PLATFORMS: "linux/amd64,linux/arm64,linux/arm/v7"
NODE_LTS_MAINTENANCE_VERSION: "18"
NODE_LTS_ACTIVE_VERSION: "20"
NODE_LTS_CURRENT_VERSION: "22"
ELASTICSEARCH_MAINTENANCE_VERSION: "7"
ELASTICSEARCH_ACTIVE_VERSION: "8"

72 changes: 41 additions & 31 deletions bin/start-kuzzle-server
Original file line number Diff line number Diff line change
@@ -21,46 +21,49 @@
* limitations under the License.
*/

'use strict';
"use strict";

/* eslint-disable no-console */

const fs = require('fs');
const fs = require("fs");

const yargs = require('yargs');
const yargs = require("yargs");

const { Backend } = require('../index');
const { Backend } = require("../index");

function loadJson (path) {
if (! path) {
function loadJson(path) {
if (!path) {
return {};
}

return JSON.parse(fs.readFileSync(path, 'utf8'));
return JSON.parse(fs.readFileSync(path, "utf8"));
}

async function startKuzzle (options = {}) {
const app = new Backend('kuzzle');
async function startKuzzle(options = {}) {
const app = new Backend("kuzzle");

if (options.enablePlugins) {
const additionalPlugins = options.enablePlugins
.trim()
.split(',')
.map(x => x.trim().replace(/(^")|("$)/g, ''));
.split(",")
.map((x) => x.trim().replace(/(^")|("$)/g, ""));

for (const additionalPlugin of additionalPlugins) {
const PluginClass = require(`../plugins/available/${additionalPlugin}`);
const manifest = require(`../plugins/available/${additionalPlugin}/manifest.json`);
const manifest = require(
`../plugins/available/${additionalPlugin}/manifest.json`,
);
const plugin = new PluginClass();

try {
plugin.version = require(`../plugins/available/${additionalPlugin}/package.json`).version;
}
catch (e) {
plugin.version = require(
`../plugins/available/${additionalPlugin}/package.json`,
).version;
} catch (e) {
// ignore
}

app.plugin.use(plugin, { name: manifest.name, manifest });
app.plugin.use(plugin, { manifest, name: manifest.name });
}
}

@@ -74,36 +77,43 @@ async function startKuzzle (options = {}) {

app.vault.file = options.secretsFile;

app.version = '1.0.0';
app.version = "1.0.0";

await app.start();

const { total: admins } = await app.sdk.security.searchUsers({
query: { term: { profileIds: 'admin' } }
query: { term: { profileIds: "admin" } },
});

if (admins.length === 0) {
console.log('[!] [WARNING] There is no administrator user yet: everyone has administrator rights.');
console.log('[ℹ] You can use the CLI or the admin console to create the first administrator user.');
console.log(' For more information: https://docs.kuzzle.io/core/2/guides/essentials/security/');
console.log(
"[!] [WARNING] There is no administrator user yet: everyone has administrator rights.",
);
console.log(
"[ℹ] You can use the CLI or the admin console to create the first administrator user.",
);
console.log(
" For more information: https://docs.kuzzle.io/core/2/guides/essentials/security/",
Copy link

@afondard afondard Jan 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

404 error on this link (but it's not the only one)
Could be replaced by this link: https://docs.kuzzle.io/core/2/api/controllers/security/create-first-admin/

);
}
}

const options = yargs
.usage('start-kuzzle-server [options]')
.describe('fixtures', 'Import data from file')
.describe('mappings', 'Apply mappings from file')
.describe('securities', 'Import roles, profiles and users from file')
.describe('vault-key', 'Vault key used to decrypt secrets')
.describe('secrets-file', 'Output file to write decrypted secrets')
.describe('enable-plugins', 'Enable plugins from "plugins/available" directory')
.argv;
.usage("start-kuzzle-server [options]")
.describe("fixtures", "Import data from file")
.describe("mappings", "Apply mappings from file")
.describe("securities", "Import roles, profiles and users from file")
.describe("vault-key", "Vault key used to decrypt secrets")
.describe("secrets-file", "Output file to write decrypted secrets")
.describe(
"enable-plugins",
'Enable plugins from "plugins/available" directory',
).argv;

const run = async () => {
try {
await startKuzzle(options);
}
catch (error) {
} catch (error) {
console.error(`[x] [ERROR] ${error.stack}`);
process.exit(1);
}
29 changes: 16 additions & 13 deletions bin/wait-kuzzle
Original file line number Diff line number Diff line change
@@ -21,36 +21,38 @@
* limitations under the License.
*/

'use strict';
"use strict";

/* eslint-disable no-console */

const { Kuzzle, WebSocket } = require('kuzzle-sdk');
const { Kuzzle, WebSocket } = require("kuzzle-sdk");

const sleep = seconds => {
return new Promise(resolve => setTimeout(() => resolve(), seconds * 1000));
const sleep = (seconds) => {
return new Promise((resolve) => setTimeout(() => resolve(), seconds * 1000));
};

const kuzzleHost = process.env.KUZZLE_HOST || 'localhost';
const kuzzleHost = process.env.KUZZLE_HOST || "localhost";
const kuzzlePort = process.env.KUZZLE_PORT || 7512;
const maxTries = process.env.MAX_TRIES || 60;

async function waitKuzzle (host, port, timeout) {
const spinner = '|/-\\';
async function waitKuzzle(host, port, timeout) {
const spinner = "|/-\\";
const protocol = new WebSocket(host, { port });
const kuzzle = new Kuzzle(protocol);
let connected = false;

kuzzle.on('connected', () => (connected = true));
kuzzle.on("connected", () => (connected = true));
kuzzle.connect().catch(() => {});

console.log(`[ℹ] Trying to connect to Kuzzle at "${kuzzleHost}:${kuzzlePort}"`);
console.log(
`[ℹ] Trying to connect to Kuzzle at "${kuzzleHost}:${kuzzlePort}"`,
);

for (let seconds = 0; seconds < timeout; seconds++) {
const message = `[${spinner.charAt(seconds % spinner.length)}] Still trying to connect to Kuzzle (${seconds}s)...`;

if (connected) {
console.log(`${' '.repeat(message.length)}\r[✔] Kuzzle is up`);
console.log(`${" ".repeat(message.length)}\r[✔] Kuzzle is up`);
kuzzle.disconnect();
return;
}
@@ -60,15 +62,16 @@ async function waitKuzzle (host, port, timeout) {
await sleep(1);
}

console.log(`Timeout after ${timeout}s: cannot connect to Kuzzle at "${host}:${port}"`);
console.log(
`Timeout after ${timeout}s: cannot connect to Kuzzle at "${host}:${port}"`,
);
process.exit(1);
}

const run = async () => {
try {
await waitKuzzle(kuzzleHost, kuzzlePort, maxTries);
}
catch (error) {
} catch (error) {
console.error(`[x] ${error.message}`);
process.exit(1);
}
17 changes: 17 additions & 0 deletions check-node-version.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/* eslint-disable no-console */

"use strict";

const semver = require("semver");
const { engines } = require("./package.json");

const version = engines.node;
const nodeVersion = process.version;

if (!semver.satisfies(nodeVersion, version)) {
console.error(
"\x1b[31m%s\x1b[0m",
`Required node version ${version} not satisfied with current version ${nodeVersion}`,
);
process.exit(1);
}
1 change: 1 addition & 0 deletions docker/images/kuzzle/Dockerfile
Original file line number Diff line number Diff line change
@@ -32,6 +32,7 @@
ADD ./package-lock.json package-lock.json
ADD ./index.ts index.ts
ADD ./tsconfig.json tsconfig.json
ADD ./check-node-version.js check-node-version.js

RUN npm ci
RUN npm run build
1 change: 1 addition & 0 deletions docker/images/plugin-dev/Dockerfile
Original file line number Diff line number Diff line change
@@ -20,6 +20,7 @@
ADD ./package-lock.json package-lock.json
ADD ./index.ts index.ts
ADD ./tsconfig.json tsconfig.json
ADD ./check-node-version.js check-node-version.js

RUN npm ci
RUN npm run build
2 changes: 1 addition & 1 deletion lib/api/controllers/authController.ts
Original file line number Diff line number Diff line change
@@ -19,7 +19,7 @@
* limitations under the License.
*/
import { IncomingMessage } from "http";
import Cookie from "cookie";
import * as Cookie from "cookie";

import Bluebird from "bluebird";
import { isEmpty } from "lodash";
8 changes: 2 additions & 6 deletions lib/core/security/tokenRepository.ts
Original file line number Diff line number Diff line change
@@ -29,14 +29,10 @@ import { UnauthorizedError } from "../../kerror/errors";
import { Token } from "../../model/security/token";
import { User } from "../../model/security/user";
import ApiKey from "../../model/storage/apiKey";
import debugFactory from "../../util/debug";
import { ObjectRepository } from "../shared/ObjectRepository";
import { sha256 } from "../../util/crypto";

const securityError = kerror.wrap("security", "token");
const debug = debugFactory("kuzzle:bootstrap:tokens");

const BOOTSTRAP_DONE_KEY = "token/bootstrap";

export class TokenRepository extends ObjectRepository<Token> {
private tokenGracePeriod: number;
@@ -229,8 +225,8 @@ export class TokenRepository extends ObjectRepository<Token> {
const maxTTL =
type === "apiKey"
? global.kuzzle.config.security.apiKey.maxTTL
: global.kuzzle.config.security.authToken.maxTTL ??
global.kuzzle.config.security.jwt.maxTTL;
: (global.kuzzle.config.security.authToken.maxTTL ??
global.kuzzle.config.security.jwt.maxTTL);

if (
!bypassMaxTTL &&
10,923 changes: 6,054 additions & 4,869 deletions package-lock.json

Large diffs are not rendered by default.

102 changes: 53 additions & 49 deletions package.json
Original file line number Diff line number Diff line change
@@ -5,6 +5,7 @@
"description": "Kuzzle is an open-source solution that handles all the data management through a secured API, with a large choice of protocols.",
"bin": "bin/start-kuzzle-server",
"scripts": {
"preinstall": "node ./check-node-version.js",
"build": "tsc",
"clean": "touch index.ts && npm run build | grep TSFILE | cut -d' ' -f 2 | xargs rm",
"cucumber": "cucumber.js --fail-fast",
@@ -21,7 +22,7 @@
"test:functional:websocket": "KUZZLE_PROTOCOL=websocket cucumber-js --profile websocket",
"test:functional": "npm run test:functional:http && npm run test:functional:websocket && npm run test:functional:jest",
"test:lint": "eslint ./lib ./test ./bin ./features ./plugins/available/functional-test-plugin",
"test:unit": "DEBUG= npx --node-arg=--trace-warnings mocha --exit",
"test:unit": "npx mocha --exit",
"test": "npm run clean && npm run --silent test:lint && npm run build && npm run test:unit:coverage && npm run test:functional"
},
"directories": {
@@ -30,104 +31,107 @@
"dependencies": {
"aedes": "0.46.3",
"bluebird": "3.7.2",
"cli-color": "2.0.3",
"cookie": "0.6.0",
"debug": "4.3.4",
"cli-color": "2.0.4",
"cookie": "1.0.2",
"debug": "4.4.0",
"denque": "2.1.0",
"didyoumean": "1.2.2",
"dumpme": "1.0.3",
"eventemitter3": "5.0.1",
"inquirer": "9.2.12",
"ioredis": "5.3.2",
"ioredis": "5.4.2",
"js-yaml": "4.1.0",
"json-stable-stringify": "1.1.0",
"json-stable-stringify": "1.2.1",
"json2yaml": "1.1.0",
"jsonwebtoken": "9.0.2",
"koncorde": "4.3.0",
"koncorde": "4.4.0",
"kuzzle-plugin-auth-passport-local": "6.4.1",
"kuzzle-plugin-logger": "3.0.3",
"kuzzle-sdk": "^7.13.0",
"kuzzle-vault": "2.0.4",
"kuzzle-sdk": "^7.14.0",
"kuzzle-vault": "2.1.0",
"lodash": "4.17.21",
"long": "5.2.3",
"moment": "2.29.4",
"moment": "2.30.1",
"ms": "2.1.3",
"murmurhash": "^2.0.1",
"murmurhash": "2.0.1",
"ndjson": "2.0.0",
"node-segfault-handler": "1.4.2",
"passport": "0.7.0",
"protobufjs": "7.2.5",
"protobufjs": "7.4.0",
"rc": "1.2.8",
"sdk-es7": "npm:@elastic/elasticsearch@7.13.0",
"sdk-es8": "npm:@elastic/elasticsearch@8.12.1",
"semver": "7.6.0",
"sdk-es8": "npm:@elastic/elasticsearch@8.17.0",
"semver": "7.6.3",
"sorted-array": "2.0.4",
"uuid": "9.0.1",
"uWebSockets.js": "https://github.com/uNetworking/uWebSockets.js/archive/refs/tags/v20.34.0.tar.gz",
"validator": "13.11.0",
"winston": "3.11.0",
"winston-elasticsearch": "0.17.4",
"winston-syslog": "2.7.0",
"winston-transport": "4.6.0",
"uuid": "11.0.4",
"uWebSockets.js": "https://github.com/uNetworking/uWebSockets.js/archive/refs/tags/v20.51.0.tar.gz",
"validator": "13.12.0",
"winston": "3.17.0",
"winston-elasticsearch": "0.19.0",
"winston-syslog": "2.7.1",
"winston-transport": "4.9.0",
"yargs": "17.7.2",
"zeromq": "6.0.0-beta.6"
"zeromq": "6.3.0"
},
"repository": {
"type": "git",
"url": "git://github.com/kuzzleio/kuzzle.git"
},
"devDependencies": {
"@commitlint/cli": "^17.6.7",
"@commitlint/config-conventional": "^17.6.7",
"@commitlint/cli": "19.6.1",
"@commitlint/config-conventional": "19.6.0",
"@jest/globals": "29.7.0",
"@semantic-release/changelog": "^6.0.3",
"@semantic-release/commit-analyzer": "^10.0.1",
"@semantic-release/git": "^10.0.1",
"@semantic-release/release-notes-generator": "^11.0.4",
"@types/bluebird": "^3.5.42",
"@types/cookie": "^0.6.0",
"@types/jest": "29.5.10",
"@semantic-release/changelog": "6.0.3",
"@semantic-release/commit-analyzer": "13.0.1",
"@semantic-release/git": "10.0.1",
"@semantic-release/release-notes-generator": "14.0.3",
"@types/bluebird": "3.5.42",
"@types/cookie": "1.0.0",
"@types/jest": "29.5.14",
"@types/js-yaml": "4.0.9",
"@types/lodash": "4.14.202",
"@types/lodash": "4.17.14",
"@types/mocha": "^10.0.10",
"async": "3.2.5",
"chokidar": "3.5.3",
"cucumber": "6.0.5",
"cz-conventional-changelog": "^3.3.0",
"chokidar": "4.0.3",
"cucumber": "6.0.7",
"cz-conventional-changelog": "3.3.0",
"ergol": "1.0.2",
"eslint-plugin-kuzzle": "0.0.12",
"eslint-plugin-kuzzle": "0.0.13",
"jest": "29.7.0",
"mocha": "10.2.0",
"mocha": "11.0.1",
"mock-require": "3.0.3",
"mqtt": "5.3.0",
"mqtt": "5.10.3",
"nyc": "15.1.0",
"request": "2.88.2",
"request-promise": "4.2.6",
"rewire": "5.0.0",
"semantic-release-config-kuzzle": "^1.0.0",
"semantic-release-slack-bot": "^4.0.2",
"semantic-release-config-kuzzle": "1.0.0",
"semantic-release-slack-bot": "4.0.2",
"should": "13.2.3",
"should-sinon": "0.0.6",
"sinon": "14.0.2",
"strip-json-comments": "https://github.com/sindresorhus/strip-json-comments/archive/refs/tags/v3.1.1.tar.gz",
"ts-jest": "29.1.1",
"ts-node": "10.9.1",
"ts-jest": "29.2.5",
"ts-node": "10.9.2",
"typescript": "5.3.2",
"yaml": "2.3.4"
"yaml": "2.7.0"
},
"engines": {
"node": ">= 12.13.0"
"node": ">=18.0.0 <23.0.0"
},
"engineStrict": true,
"license": "Apache-2.0",
"files": [
"lib/**/*.js",
"check-node-version.js",
"index.d.ts",
"index.js",
"lib/**/*.d.ts",
"lib/**/*.js",
"lib/**/*.json",
"lib/**/*.proto",
"lib/**/*.yaml",
"package.json",
"index.js",
"index.d.ts",
"LICENSE.md",
"package.json",
"README.md"
]
}
}
7 changes: 6 additions & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
@@ -16,7 +16,12 @@
},
"esModuleInterop": true,
"resolveJsonModule": true,
"skipDefaultLibCheck": true
"skipLibCheck": true,
"skipDefaultLibCheck": true,
"types": [
"node",
"jest"
]
},
"rootDir": "lib/",
"include": [

Unchanged files with check annotations Beta

if (this.config.configs) {
this.log.ok("Configuration files loaded:");
this.config.configs.forEach((f) => this.log.print(`\t- ${f}`));

Check warning on line 65 in bin/.upgrades/lib/context.js

GitHub Actions / Lint - Node.js (18)

Prefer for...of instead of Array.forEach

Check warning on line 65 in bin/.upgrades/lib/context.js

GitHub Actions / Lint - Node.js (20)

Prefer for...of instead of Array.forEach

Check warning on line 65 in bin/.upgrades/lib/context.js

GitHub Actions / Lint - Node.js (22)

Prefer for...of instead of Array.forEach
}
this.version = await this.getVersions();
properties: {
job: { type: "keyword" },
name: { type: "keyword" },
age: { type: "integer" },

Check warning on line 10 in features/fixtures/mappings.js

GitHub Actions / Lint - Node.js (18)

Expected object keys to be in ascending order. 'age' should be before 'name'

Check warning on line 10 in features/fixtures/mappings.js

GitHub Actions / Lint - Node.js (20)

Expected object keys to be in ascending order. 'age' should be before 'name'

Check warning on line 10 in features/fixtures/mappings.js

GitHub Actions / Lint - Node.js (22)

Expected object keys to be in ascending order. 'age' should be before 'name'
city: { type: "keyword" },
},
},
},
"mtp-open-data": {

Check warning on line 15 in features/fixtures/mappings.js

GitHub Actions / Lint - Node.js (18)

Expected object keys to be in ascending order. 'mtp-open-data' should be before 'nyc-open-data'

Check warning on line 15 in features/fixtures/mappings.js

GitHub Actions / Lint - Node.js (20)

Expected object keys to be in ascending order. 'mtp-open-data' should be before 'nyc-open-data'

Check warning on line 15 in features/fixtures/mappings.js

GitHub Actions / Lint - Node.js (22)

Expected object keys to be in ascending order. 'mtp-open-data' should be before 'nyc-open-data'
"green-taxi": {
properties: {
job: { type: "keyword" },
name: { type: "keyword" },
age: { type: "integer" },

Check warning on line 20 in features/fixtures/mappings.js

GitHub Actions / Lint - Node.js (18)

Expected object keys to be in ascending order. 'age' should be before 'name'

Check warning on line 20 in features/fixtures/mappings.js

GitHub Actions / Lint - Node.js (20)

Expected object keys to be in ascending order. 'age' should be before 'name'

Check warning on line 20 in features/fixtures/mappings.js

GitHub Actions / Lint - Node.js (22)

Expected object keys to be in ascending order. 'age' should be before 'name'
city: { type: "keyword" },
},
},
credentials: {
local: {
username: "test-admin",
password: "password",

Check warning on line 14 in features/fixtures/permissions.js

GitHub Actions / Lint - Node.js (18)

Expected object keys to be in ascending order. 'password' should be before 'username'

Check warning on line 14 in features/fixtures/permissions.js

GitHub Actions / Lint - Node.js (20)

Expected object keys to be in ascending order. 'password' should be before 'username'

Check warning on line 14 in features/fixtures/permissions.js

GitHub Actions / Lint - Node.js (22)

Expected object keys to be in ascending order. 'password' should be before 'username'
},
},
},
"default-user": {

Check warning on line 18 in features/fixtures/permissions.js

GitHub Actions / Lint - Node.js (18)

Expected object keys to be in ascending order. 'default-user' should be before 'test-admin'

Check warning on line 18 in features/fixtures/permissions.js

GitHub Actions / Lint - Node.js (20)

Expected object keys to be in ascending order. 'default-user' should be before 'test-admin'

Check warning on line 18 in features/fixtures/permissions.js

GitHub Actions / Lint - Node.js (22)

Expected object keys to be in ascending order. 'default-user' should be before 'test-admin'
content: {
profileIds: ["default"],
},
credentials: {
local: {
username: "default-user",
password: "password",

Check warning on line 25 in features/fixtures/permissions.js

GitHub Actions / Lint - Node.js (18)

Expected object keys to be in ascending order. 'password' should be before 'username'

Check warning on line 25 in features/fixtures/permissions.js

GitHub Actions / Lint - Node.js (20)

Expected object keys to be in ascending order. 'password' should be before 'username'

Check warning on line 25 in features/fixtures/permissions.js

GitHub Actions / Lint - Node.js (22)

Expected object keys to be in ascending order. 'password' should be before 'username'
},
},
},
async function (username, password) {
this.props.result = await this.sdk.auth.login("local", {
username,
password,

Check warning on line 12 in features/step_definitions/auth-steps.js

GitHub Actions / Lint - Node.js (18)

Expected object keys to be in ascending order. 'password' should be before 'username'

Check warning on line 12 in features/step_definitions/auth-steps.js

GitHub Actions / Lint - Node.js (20)

Expected object keys to be in ascending order. 'password' should be before 'username'

Check warning on line 12 in features/step_definitions/auth-steps.js

GitHub Actions / Lint - Node.js (22)

Expected object keys to be in ascending order. 'password' should be before 'username'
});
},
);
const request = {
controller: "bulk",
action: "deleteByQuery",

Check warning on line 48 in features/step_definitions/bulk-steps.js

GitHub Actions / Lint - Node.js (18)

Expected object keys to be in ascending order. 'action' should be before 'controller'

Check warning on line 48 in features/step_definitions/bulk-steps.js

GitHub Actions / Lint - Node.js (20)

Expected object keys to be in ascending order. 'action' should be before 'controller'

Check warning on line 48 in features/step_definitions/bulk-steps.js

GitHub Actions / Lint - Node.js (22)

Expected object keys to be in ascending order. 'action' should be before 'controller'
index: this.props.index,
collection: this.props.collection,

Check warning on line 50 in features/step_definitions/bulk-steps.js

GitHub Actions / Lint - Node.js (18)

Expected object keys to be in ascending order. 'collection' should be before 'index'

Check warning on line 50 in features/step_definitions/bulk-steps.js

GitHub Actions / Lint - Node.js (20)

Expected object keys to be in ascending order. 'collection' should be before 'index'

Check warning on line 50 in features/step_definitions/bulk-steps.js

GitHub Actions / Lint - Node.js (22)

Expected object keys to be in ascending order. 'collection' should be before 'index'
refresh: "wait_for",
body: { query },
};