Skip to content

Commit

Permalink
Updated js-yaml to v4 (elastic#190678)
Browse files Browse the repository at this point in the history
## Summary
Updated `js-yaml` to `4.1.0`.

This PR also introduces a type override for the `js-yaml` load function
to maintain compatibility across the codebase. Specifically, updated
type definition of the load function looks as follows:

```typescript
function load<T = any>(str: string, opts?: jsyaml.LoadOptions): T;
```

The original type definition of the load function in `js-yaml` changed
from `any` to `unknown`. This change would require extensive type
updates throughout the entire repository to accommodate the `unknown`
type. To avoid widespread type changes and potential issues in the
codebase, the type is overriden back to `any` for now.
This is a temporary measure, we plan to address the necessary type
changes in subsequent PRs, where teams will gradually update the
codebase to work with the `unknown` type.


### Checklist

- [x] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios

## Release note
Updated `js-yaml` to `4.1.0`.

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
Co-authored-by: Maxim Palenov <maxim.palenov@elastic.co>
  • Loading branch information
3 people committed Sep 19, 2024
1 parent eabb102 commit 28aa274
Show file tree
Hide file tree
Showing 130 changed files with 514 additions and 490 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,13 @@ async function main() {

const preamble = locationFileLines.slice(0, 1);

// eslint-disable-next-line @kbn/eslint/no_unsafe_js_yaml
const locationObj = jsYaml.load(
locationFileLines.slice(1).join('\n')
) as BackstageLocationResource;
locationObj.spec.targets = pipelines.map(
(fileName) => `${resourceDefinitionsBaseUrl}/${fileName}`
);

// eslint-disable-next-line @kbn/eslint/no_unsafe_js_yaml
const locationYaml = jsYaml.dump(locationObj, { lineWidth: 400 });

fs.writeFileSync(locationFile, `${preamble.join('\n')}\n${locationYaml}`);
Expand Down
1 change: 0 additions & 1 deletion .buildkite/pipeline-utils/agent_images.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
* License v3.0 only", or the "Server Side Public License, v 1".
*/

// eslint-disable-next-line @kbn/eslint/no_unsafe_js_yaml
import { dump } from 'js-yaml';
import { BuildkiteClient, BuildkiteCommandStep } from './buildkite';

Expand Down
1 change: 0 additions & 1 deletion .buildkite/pipeline-utils/buildkite/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import axios, { AxiosInstance } from 'axios';
import { execSync, ExecSyncOptions } from 'child_process';

// eslint-disable-next-line @kbn/eslint/no_unsafe_js_yaml
import { dump } from 'js-yaml';

import { parseLinkHeader } from './parse_link_header';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import * as Fs from 'fs';
import * as globby from 'globby';
import minimatch from 'minimatch';

// eslint-disable-next-line @kbn/eslint/no_unsafe_js_yaml
import { load as loadYaml } from 'js-yaml';

import { BuildkiteClient, BuildkiteStep } from '../buildkite';
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -1130,7 +1130,7 @@
"jquery": "^3.5.0",
"js-search": "^1.4.3",
"js-sha256": "^0.9.0",
"js-yaml": "^3.14.1",
"js-yaml": "^4.1.0",
"json-schema-to-ts": "^2.9.1",
"json-stable-stringify": "^1.0.1",
"json-stringify-pretty-compact": "1.2.0",
Expand Down Expand Up @@ -1560,7 +1560,7 @@
"@types/jest": "^29.5.3",
"@types/jquery": "^3.3.31",
"@types/js-search": "^1.4.0",
"@types/js-yaml": "^3.11.1",
"@types/js-yaml": "^4.0.9",
"@types/jsdom": "^20.0.1",
"@types/json-schema": "^7",
"@types/json-stable-stringify": "^1.0.32",
Expand Down
4 changes: 2 additions & 2 deletions packages/kbn-apm-config-loader/src/utils/read_config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@
*/

import { readFileSync } from 'fs';
import { safeLoad } from 'js-yaml';
import { load } from 'js-yaml';

import { set } from '@kbn/safer-lodash-set';
import { ensureDeepObject } from '@kbn/std';
import { isPlainObject } from 'lodash';

const readYaml = (path: string) => {
try {
return safeLoad(readFileSync(path, 'utf8'));
return load(readFileSync(path, 'utf8'));
} catch (e) {
/* tslint:disable:no-empty */
}
Expand Down
6 changes: 3 additions & 3 deletions packages/kbn-config/src/raw/read_config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@
*/

import { readFileSync } from 'fs';
import { safeLoad } from 'js-yaml';
import { load } from 'js-yaml';
import { set } from '@kbn/safer-lodash-set';
import { isPlainObject } from 'lodash';
import { ensureValidObjectPath } from '@kbn/std';
import { splitKey, getUnsplittableKey, replaceEnvVarRefs } from './utils';

const readYaml = (path: string) => safeLoad(readFileSync(path, 'utf8'));
const readYaml = (path: string) => load(readFileSync(path, 'utf8'));

interface YamlEntry {
path: string[];
Expand Down Expand Up @@ -76,7 +76,7 @@ export const getConfigFromFiles = (configFiles: readonly string[]) => {

for (const configFile of configFiles) {
const yaml = readYaml(configFile);
if (yaml !== null) {
if (yaml) {
yamlEntries.push(...listEntries(yaml));
}
}
Expand Down
2 changes: 1 addition & 1 deletion packages/kbn-docs-utils/src/mdx/get_all_doc_file_ids.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export async function getAllDocFileIds(outputDir: string) {

let fm;
try {
fm = Yaml.safeLoad(fmYaml.slice(0, fmEnd.index));
fm = Yaml.load(fmYaml.slice(0, fmEnd.index));
if (typeof fm !== 'object' || fm === null) {
throw new Error('expected yaml to produce an object');
}
Expand Down
1 change: 1 addition & 0 deletions packages/kbn-docs-utils/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
},
"include": [
"**/*.ts",
"../../typings/**/*"
],
"exclude": [
"**/__fixtures__/**",
Expand Down
2 changes: 1 addition & 1 deletion packages/kbn-es/src/utils/read_roles_from_resource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

import fs from 'fs';
import { extname } from 'path';
import { safeLoad as loadYaml } from 'js-yaml';
import { load as loadYaml } from 'js-yaml';

export const readRolesFromResource = (resourcePath: string) => {
if (!fs.existsSync(resourcePath) || extname(resourcePath) !== '.yml') {
Expand Down
1 change: 0 additions & 1 deletion packages/kbn-eslint-config/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,6 @@ module.exports = {
'@kbn/eslint/no_constructor_args_in_property_initializers': 'error',
'@kbn/eslint/no_this_in_property_initializers': 'error',
'@kbn/eslint/no_unsafe_console': 'error',
'@kbn/eslint/no_unsafe_js_yaml': 'error',
'@kbn/imports/no_unresolvable_imports': 'error',
'@kbn/imports/uniform_imports': 'error',
'@kbn/imports/no_unused_imports': 'error',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export class ServerlessAuthProvider implements AuthProvider {
}

getSupportedRoleDescriptors(): Record<string, unknown> {
return readRolesDescriptorsFromResource(this.rolesDefinitionPath);
return readRolesDescriptorsFromResource(this.rolesDefinitionPath) as Record<string, unknown>;
}
getDefaultRole(): string {
return getDefaultServerlessRole(this.projectType);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {
export class StatefulAuthProvider implements AuthProvider {
private readonly rolesDefinitionPath = resolve(REPO_ROOT, STATEFUL_ROLES_ROOT_PATH, 'roles.yml');
getSupportedRoleDescriptors(): Record<string, unknown> {
return readRolesDescriptorsFromResource(this.rolesDefinitionPath);
return readRolesDescriptorsFromResource(this.rolesDefinitionPath) as Record<string, unknown>;
}
getDefaultRole() {
return 'editor';
Expand Down
1 change: 1 addition & 0 deletions packages/kbn-ftr-common-functional-services/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
},
"include": [
"**/*.ts",
"../../typings/**/*"
],
"kbn_references": [
"@kbn/core-saved-objects-server",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
*/

import chalk from 'chalk';
import { safeDump } from 'js-yaml';
import { dump } from 'js-yaml';
import { isPlainObjectType } from './is_plain_object_type';

/**
Expand All @@ -33,7 +33,7 @@ export function extractByJsonPointer(document: unknown, pointer: string): unknow
throw new Error(
`JSON Pointer ${chalk.bold(pointer)} resolution failure. Expected ${chalk.magenta(
path.join('/')
)} to be a plain object but it has type "${typeof target}" in \n\n${safeDump(document, {
)} to be a plain object but it has type "${typeof target}" in \n\n${dump(document, {
skipInvalid: true,
})}`
);
Expand Down Expand Up @@ -69,7 +69,7 @@ export function extractObjectByJsonPointer(
throw new Error(
`JSON Pointer resolution failure. Expected ${chalk.magenta(
pointer
)} to be a plain object in \n\n${safeDump(document, { skipInvalid: true })}`
)} to be a plain object in \n\n${dump(document, { skipInvalid: true })}`
);
}

Expand Down
35 changes: 26 additions & 9 deletions packages/kbn-openapi-bundler/src/utils/read_document.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

import fs from 'fs/promises';
import { basename, extname } from 'path';
import { safeLoad } from 'js-yaml';
import { load } from 'js-yaml';
import chalk from 'chalk';
import { logger } from '../logger';
import { isPlainObjectType } from './is_plain_object_type';
Expand Down Expand Up @@ -43,15 +43,32 @@ async function readFile(filePath: string): Promise<unknown> {
}

async function readYamlFile(filePath: string): Promise<Record<string, unknown>> {
// Typing load's result to Record<string, unknown> is optimistic as we can't be sure
// there is object inside a yaml file. We don't have this validation layer so far
// but using JSON Schemas here should mitigate this problem.
return safeLoad(await fs.readFile(filePath, { encoding: 'utf8' }));
const fileContent = await fs.readFile(filePath, { encoding: 'utf8' });
const maybeObject = load(fileContent);

if (!isPlainObjectType(maybeObject)) {
throw new Error(
`Expected ${chalk.bold(filePath)} to contain an object but got ${typeof maybeObject}`
);
}

return maybeObject;
}

async function readJsonFile(filePath: string): Promise<Record<string, unknown>> {
// Typing load's result to Record<string, unknown> is optimistic as we can't be sure
// there is object inside a yaml file. We don't have this validation layer so far
// but using JSON Schemas here should mitigate this problem.
return await JSON.parse(await fs.readFile(filePath, { encoding: 'utf8' }));
const fileContent = await fs.readFile(filePath, { encoding: 'utf8' });

try {
const maybeObject = JSON.parse(fileContent);

if (!isPlainObjectType(maybeObject)) {
throw new Error(
`Expected ${chalk.bold(filePath)} to contain an object but got ${typeof maybeObject}`
);
}

return maybeObject;
} catch {
throw new Error(`Unable to parse ${chalk.bold(filePath)}`);
}
}
6 changes: 3 additions & 3 deletions packages/kbn-openapi-bundler/src/utils/write_yaml_document.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
*/

import fs from 'fs/promises';
import { safeDump } from 'js-yaml';
import { dump } from 'js-yaml';
import { dirname } from 'path';

export async function writeYamlDocument(filePath: string, document: unknown): Promise<void> {
Expand All @@ -26,14 +26,14 @@ function stringifyToYaml(document: unknown): string {
try {
// Disable YAML Anchors https://yaml.org/spec/1.2.2/#3222-anchors-and-aliases
// It makes YAML much more human readable
return safeDump(document, {
return dump(document, {
noRefs: true,
sortKeys: sortYamlKeys,
skipInvalid: true, // Skip invalid types like `undefined`
});
} catch (e) {
// Try to stringify with YAML Anchors enabled
return safeDump(document, { noRefs: false, sortKeys: sortYamlKeys, skipInvalid: true });
return dump(document, { noRefs: false, sortKeys: sortYamlKeys, skipInvalid: true });
}
}

Expand Down
6 changes: 3 additions & 3 deletions packages/kbn-openapi-bundler/tests/bundler/bundle_specs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
unlinkSync,
writeFileSync,
} from 'fs';
import { safeDump, safeLoad } from 'js-yaml';
import { dump, load } from 'js-yaml';
import { OpenAPIV3 } from 'openapi-types';
import { bundle, BundlerConfig } from '../../src/openapi_bundler';

Expand Down Expand Up @@ -59,7 +59,7 @@ function dumpSpecs(folderPath: string, oasSpecs: Record<string, OpenAPIV3.Docume
for (const [fileName, oasSpec] of Object.entries(oasSpecs)) {
writeFileSync(
join(folderPath, `${fileName}.schema.yaml`),
safeDump(oasSpec, { skipInvalid: true }) // Skip invalid types like `undefined`
dump(oasSpec, { skipInvalid: true }) // Skip invalid types like `undefined`
);
}
}
Expand All @@ -70,7 +70,7 @@ export function readBundledSpecs(folderPath: string): Record<string, OpenAPIV3.D
for (const fileName of readdirSync(folderPath)) {
const yaml = readFileSync(join(folderPath, fileName), { encoding: 'utf8' });

bundledSpecs[fileName] = safeLoad(yaml);
bundledSpecs[fileName] = load(yaml) as OpenAPIV3.Document;
}

return bundledSpecs;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
*/

import { readFileSync } from 'fs';
import { safeLoad } from 'js-yaml';
import { load } from 'js-yaml';
import { join } from 'path';
import { bundleFolder, readBundledSpecs } from './bundle_specs';

Expand All @@ -26,7 +26,7 @@ describe('OpenAPI Bundler - specs with multiple modifications', () => {

const [bundledSpec] = Object.values(readBundledSpecs(outputFolderPath));

const expected = safeLoad(
const expected = load(
readFileSync(join(folderToBundlePath, 'expected.yaml'), { encoding: 'utf8' })
);

Expand Down
5 changes: 2 additions & 3 deletions packages/kbn-openapi-bundler/tests/bundler/circular.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* License v3.0 only", or the "Server Side Public License, v 1".
*/

import { safeDump } from 'js-yaml';
import { dump } from 'js-yaml';
import { OpenAPIV3 } from 'openapi-types';
import { bundleSpecs } from './bundle_specs';
import { createOASDocument } from '../create_oas_document';
Expand Down Expand Up @@ -49,8 +49,7 @@ describe('OpenAPI Bundler - circular specs', () => {
})
);

expect(safeDump(bundledSpec.paths['/api/some_api']!.get!.responses['200']))
.toMatchInlineSnapshot(`
expect(dump(bundledSpec.paths['/api/some_api']!.get!.responses['200'])).toMatchInlineSnapshot(`
"content:
application/json:
schema: &ref_0
Expand Down
6 changes: 3 additions & 3 deletions packages/kbn-openapi-bundler/tests/merger/merge_specs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
unlinkSync,
writeFileSync,
} from 'fs';
import { safeDump, safeLoad } from 'js-yaml';
import { dump, load } from 'js-yaml';
import { OpenAPIV3 } from 'openapi-types';
import { merge, MergerConfig } from '../../src/openapi_merger';

Expand Down Expand Up @@ -59,7 +59,7 @@ function dumpSpecs(folderPath: string, oasSpecs: Record<string, OpenAPIV3.Docume
for (const [fileName, oasSpec] of Object.entries(oasSpecs)) {
writeFileSync(
join(folderPath, `${fileName}.schema.yaml`),
safeDump(oasSpec, { skipInvalid: true })
dump(oasSpec, { skipInvalid: true })
);
}
}
Expand All @@ -70,7 +70,7 @@ export function readMergedSpecs(folderPath: string): Record<string, OpenAPIV3.Do
for (const fileName of readdirSync(folderPath)) {
const yaml = readFileSync(join(folderPath, fileName), { encoding: 'utf8' });

mergedSpecs[fileName] = safeLoad(yaml);
mergedSpecs[fileName] = load(yaml);
}

return mergedSpecs;
Expand Down
2 changes: 1 addition & 1 deletion packages/kbn-openapi-bundler/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@
},
"exclude": ["target/**/*"],
"extends": "../../tsconfig.base.json",
"include": ["**/*.ts"],
"include": ["**/*.ts", "../../typings/**/*"],
"kbn_references": ["@kbn/tooling-log"]
}
4 changes: 2 additions & 2 deletions packages/kbn-optimizer/src/limits.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export function readLimits(path: string): Limits {
}
}

return yaml ? Yaml.safeLoad(yaml) : {};
return yaml ? Yaml.load(yaml) : {};
}

export function validateLimitsForAllBundles(
Expand Down Expand Up @@ -136,6 +136,6 @@ export function updateBundleLimits({
pageLoadAssetSize,
};

Fs.writeFileSync(limitsPath, Yaml.safeDump(newLimits));
Fs.writeFileSync(limitsPath, Yaml.dump(newLimits));
log.success(`wrote updated limits to ${limitsPath}`);
}
3 changes: 2 additions & 1 deletion packages/kbn-optimizer/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
]
},
"include": [
"**/*.ts"
"**/*.ts",
"../../typings/**/*"
],
"exclude": [
"**/__fixtures__/**/*",
Expand Down
Loading

0 comments on commit 28aa274

Please sign in to comment.