From daa0f2258782d763afaff6742dad15cf48085185 Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Mon, 15 Mar 2021 20:17:54 +0000 Subject: [PATCH] chore(NA): ensure scripts run with --preserve-symlinks (#94046) * chore(NA): ensure scripts run with --preserve-symlinks * chore(NA): run webpack configs with symlinks: false * chore(NA): fix pkg json load on kbn test * chore(NA): add script into setup node env * chore(NA): fix kbn test for relative improt * chore(NA): fix change on docs * chore(NA): move ensure node preserve symlinks into setup node env * chore(NA): update changed docs * chore(NA): update jest unit test * chore(NA): fix wrapper script exit code * chore(NA): updated generated plugin list docs * fix(NA): make functional test runner use kbn utils repo_root * chore(NA): fix eslint imports * chore(NA): missing react correct config on eslint package * chore(NA): use correct value to make test pass locally * chore(NA): fix jest tests * chore(NA): try remove extra preserve symlinks * chore(NA): fix windows environment * chore(NA): fix kbn-optimizer to run with preserve-symlinks * chore(NA): fix integration jest test for kbn/optimizer * chore(NA): remove require.resolve from eslintrc.js * chore(NA): avoid load json file * chore(NA): move kbn/utils import into kbn/dev-utils * chore(NA): use correct dependencies on eslint config package Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../elastic-eslint-config-kibana/package.json | 5 +- .../elastic-eslint-config-kibana/react.js | 4 +- .../typescript.js | 2 +- .../src/plugin_list/generate_plugin_list.ts | 3 +- .../basic_optimization.test.ts | 2 +- .../src/optimizer/observe_worker.ts | 1 + .../src/worker/webpack.config.ts | 1 + packages/kbn-pm/webpack.config.js | 1 + .../src/functional_tests/lib/paths.js | 3 +- .../functional_tests/lib/run_kibana_server.js | 6 +- .../kbn-test/src/legacy_es/es_test_config.js | 2 +- .../src/mocha/junit_report_generation.js | 3 +- packages/kbn-ui-shared-deps/webpack.config.js | 1 + packages/kbn-utils/src/repo_root.ts | 3 +- scripts/build_kibana_platform_plugins.js | 1 + scripts/jest.js | 1 + scripts/jest_integration.js | 1 + scripts/kbn.js | 1 + scripts/precommit_hook.js | 1 + scripts/test_hardening.js | 2 + src/dev/cli_dev_mode/dev_server.test.ts | 5 +- .../ensure_node_preserve_symlinks.js | 63 +++++++++++++++++++ src/setup_node_env/no_transpilation.js | 2 + tsconfig.base.json | 2 + x-pack/package.json | 4 +- .../plugins/apm/e2e/cypress/webpack.config.js | 1 + .../shareable_runtime/webpack.config.js | 1 + .../canvas/storybook/webpack.config.js | 1 + .../canvas/storybook/webpack.dll.config.js | 1 + x-pack/tasks/build.ts | 16 +++-- 30 files changed, 118 insertions(+), 22 deletions(-) create mode 100644 src/setup_node_env/ensure_node_preserve_symlinks.js diff --git a/packages/elastic-eslint-config-kibana/package.json b/packages/elastic-eslint-config-kibana/package.json index 5fb485b86fd38..71283df00a8dd 100644 --- a/packages/elastic-eslint-config-kibana/package.json +++ b/packages/elastic-eslint-config-kibana/package.json @@ -16,5 +16,8 @@ "bugs": { "url": "https://github.com/elastic/kibana/tree/master/packages/elastic-eslint-config-kibana" }, - "homepage": "https://github.com/elastic/kibana/tree/master/packages/elastic-eslint-config-kibana" + "homepage": "https://github.com/elastic/kibana/tree/master/packages/elastic-eslint-config-kibana", + "dependencies": { + "@kbn/dev-utils": "link:../kbn-dev-utils" + } } \ No newline at end of file diff --git a/packages/elastic-eslint-config-kibana/react.js b/packages/elastic-eslint-config-kibana/react.js index f0e05db4d3c60..29000bdb15684 100644 --- a/packages/elastic-eslint-config-kibana/react.js +++ b/packages/elastic-eslint-config-kibana/react.js @@ -1,5 +1,5 @@ -const semver = require('semver') -const PKG = require('../../package.json') +const semver = require('semver'); +const { kibanaPackageJson: PKG } = require('@kbn/dev-utils'); module.exports = { plugins: [ diff --git a/packages/elastic-eslint-config-kibana/typescript.js b/packages/elastic-eslint-config-kibana/typescript.js index b439f5297032b..1a0ef81ae2f1e 100644 --- a/packages/elastic-eslint-config-kibana/typescript.js +++ b/packages/elastic-eslint-config-kibana/typescript.js @@ -4,7 +4,7 @@ // as this package was moved from typescript-eslint-parser to @typescript-eslint/parser const semver = require('semver'); -const PKG = require('../../package.json'); +const { kibanaPackageJson: PKG } = require('@kbn/dev-utils'); const eslintConfigPrettierTypescriptEslintRules = require('eslint-config-prettier/@typescript-eslint').rules; diff --git a/packages/kbn-dev-utils/src/plugin_list/generate_plugin_list.ts b/packages/kbn-dev-utils/src/plugin_list/generate_plugin_list.ts index 127e2a9904a4f..b88382c3b0da4 100644 --- a/packages/kbn-dev-utils/src/plugin_list/generate_plugin_list.ts +++ b/packages/kbn-dev-utils/src/plugin_list/generate_plugin_list.ts @@ -6,6 +6,7 @@ * Side Public License, v 1. */ +import Fs from 'fs'; import Path from 'path'; import normalizePath from 'normalize-path'; @@ -48,7 +49,7 @@ NOTE: node scripts/build_plugin_list_docs You can update the template within ${normalizePath( - Path.relative(REPO_ROOT, Path.resolve(__dirname, __filename)) + Path.relative(REPO_ROOT, Fs.realpathSync(Path.resolve(__dirname, __filename))) )} //// diff --git a/packages/kbn-optimizer/src/integration_tests/basic_optimization.test.ts b/packages/kbn-optimizer/src/integration_tests/basic_optimization.test.ts index 4dd5a5381a1d3..f378b029d32e7 100644 --- a/packages/kbn-optimizer/src/integration_tests/basic_optimization.test.ts +++ b/packages/kbn-optimizer/src/integration_tests/basic_optimization.test.ts @@ -150,9 +150,9 @@ it('builds expected bundles, saves bundle counts to metadata', async () => { expect(bar.cache.getReferencedFiles()).toMatchInlineSnapshot(` Array [ + /node_modules/@kbn/optimizer/postcss.config.js, /node_modules/css-loader/package.json, /node_modules/style-loader/package.json, - /packages/kbn-optimizer/postcss.config.js, /packages/kbn-optimizer/src/__fixtures__/__tmp__/mock_repo/plugins/bar/kibana.json, /packages/kbn-optimizer/src/__fixtures__/__tmp__/mock_repo/plugins/bar/public/index.scss, /packages/kbn-optimizer/src/__fixtures__/__tmp__/mock_repo/plugins/bar/public/index.ts, diff --git a/packages/kbn-optimizer/src/optimizer/observe_worker.ts b/packages/kbn-optimizer/src/optimizer/observe_worker.ts index 87d3ab3a56735..edf4545ae52b3 100644 --- a/packages/kbn-optimizer/src/optimizer/observe_worker.ts +++ b/packages/kbn-optimizer/src/optimizer/observe_worker.ts @@ -63,6 +63,7 @@ function usingWorkerProc( (): ProcResource => { const proc = execa.node(require.resolve('../worker/run_worker'), [], { nodeOptions: [ + ...process.execArgv, ...(inspectFlag && config.inspectWorkers ? [`${inspectFlag}=${inspectPortCounter++}`] : []), diff --git a/packages/kbn-optimizer/src/worker/webpack.config.ts b/packages/kbn-optimizer/src/worker/webpack.config.ts index c4beb959284cc..ffe31396422c8 100644 --- a/packages/kbn-optimizer/src/worker/webpack.config.ts +++ b/packages/kbn-optimizer/src/worker/webpack.config.ts @@ -224,6 +224,7 @@ export function getWebpackConfig(bundle: Bundle, bundleRefs: BundleRefs, worker: alias: { core_app_image_assets: Path.resolve(worker.repoRoot, 'src/core/public/core_app/images'), }, + symlinks: false, }, performance: { diff --git a/packages/kbn-pm/webpack.config.js b/packages/kbn-pm/webpack.config.js index 1f28b95915910..bb71aa9717f16 100644 --- a/packages/kbn-pm/webpack.config.js +++ b/packages/kbn-pm/webpack.config.js @@ -23,6 +23,7 @@ module.exports = { resolve: { extensions: ['.ts', '.js'], + symlinks: false, }, module: { diff --git a/packages/kbn-test/src/functional_tests/lib/paths.js b/packages/kbn-test/src/functional_tests/lib/paths.js index 99277d040ffdc..0bdfa8a312ea5 100644 --- a/packages/kbn-test/src/functional_tests/lib/paths.js +++ b/packages/kbn-test/src/functional_tests/lib/paths.js @@ -6,6 +6,7 @@ * Side Public License, v 1. */ +import { REPO_ROOT } from '@kbn/utils'; import { resolve, relative } from 'path'; // resolve() treats relative paths as relative to process.cwd(), @@ -16,7 +17,7 @@ function resolveRelative(path) { export const KIBANA_EXEC = 'node'; export const KIBANA_EXEC_PATH = resolveRelative('scripts/kibana'); -export const KIBANA_ROOT = resolve(__dirname, '../../../../../'); +export const KIBANA_ROOT = REPO_ROOT; export const KIBANA_FTR_SCRIPT = resolve(KIBANA_ROOT, 'scripts/functional_test_runner'); export const PROJECT_ROOT = resolve(__dirname, '../../../../../../'); export const FUNCTIONAL_CONFIG_PATH = resolve(KIBANA_ROOT, 'test/functional/config'); diff --git a/packages/kbn-test/src/functional_tests/lib/run_kibana_server.js b/packages/kbn-test/src/functional_tests/lib/run_kibana_server.js index a43d3a09c7d70..4abbc3d29fe7c 100644 --- a/packages/kbn-test/src/functional_tests/lib/run_kibana_server.js +++ b/packages/kbn-test/src/functional_tests/lib/run_kibana_server.js @@ -62,11 +62,15 @@ function collectCliArgs(config, { installDir, extraKbnOpts }) { const buildArgs = config.get('kbnTestServer.buildArgs') || []; const sourceArgs = config.get('kbnTestServer.sourceArgs') || []; const serverArgs = config.get('kbnTestServer.serverArgs') || []; + const execArgv = process.execArgv || []; return pipe( serverArgs, (args) => (installDir ? args.filter((a) => a !== '--oss') : args), - (args) => (installDir ? [...buildArgs, ...args] : [KIBANA_EXEC_PATH, ...sourceArgs, ...args]), + (args) => + installDir + ? [...buildArgs, ...args] + : [...execArgv, KIBANA_EXEC_PATH, ...sourceArgs, ...args], (args) => args.concat(extraKbnOpts || []) ); } diff --git a/packages/kbn-test/src/legacy_es/es_test_config.js b/packages/kbn-test/src/legacy_es/es_test_config.js index 2aff2d04a05a9..151587d95ca2f 100644 --- a/packages/kbn-test/src/legacy_es/es_test_config.js +++ b/packages/kbn-test/src/legacy_es/es_test_config.js @@ -6,8 +6,8 @@ * Side Public License, v 1. */ +import { kibanaPackageJson as pkg } from '@kbn/dev-utils'; import url, { format as formatUrl } from 'url'; -import pkg from '../../../../package.json'; import { adminTestUser } from '../kbn'; export const esTestConfig = new (class EsTestConfig { diff --git a/packages/kbn-test/src/mocha/junit_report_generation.js b/packages/kbn-test/src/mocha/junit_report_generation.js index e68544eca5522..f662e9ccccb25 100644 --- a/packages/kbn-test/src/mocha/junit_report_generation.js +++ b/packages/kbn-test/src/mocha/junit_report_generation.js @@ -6,6 +6,7 @@ * Side Public License, v 1. */ +import { REPO_ROOT } from '@kbn/utils'; import { dirname, relative } from 'path'; import { writeFileSync, mkdirSync } from 'fs'; import { inspect } from 'util'; @@ -21,7 +22,7 @@ const dateNow = Date.now.bind(Date); export function setupJUnitReportGeneration(runner, options = {}) { const { reportName = 'Unnamed Mocha Tests', - rootDirectory = dirname(require.resolve('../../../../package.json')), + rootDirectory = REPO_ROOT, getTestMetadata = () => ({}), } = options; diff --git a/packages/kbn-ui-shared-deps/webpack.config.js b/packages/kbn-ui-shared-deps/webpack.config.js index cc761dae3bfe9..7a996e98762ce 100644 --- a/packages/kbn-ui-shared-deps/webpack.config.js +++ b/packages/kbn-ui-shared-deps/webpack.config.js @@ -101,6 +101,7 @@ exports.getWebpackConfig = ({ dev = false } = {}) => ({ moment: MOMENT_SRC, }, extensions: ['.js', '.ts'], + symlinks: false, }, optimization: { diff --git a/packages/kbn-utils/src/repo_root.ts b/packages/kbn-utils/src/repo_root.ts index e8ad07acf4882..20a25023f4166 100644 --- a/packages/kbn-utils/src/repo_root.ts +++ b/packages/kbn-utils/src/repo_root.ts @@ -7,7 +7,6 @@ */ import Path from 'path'; -import Fs from 'fs'; import loadJsonFile from 'load-json-file'; @@ -31,7 +30,7 @@ const findKibanaPackageJson = () => { // search for the kibana directory, since this file is moved around it might // not be where we think but should always be a relatively close parent // of this directory - const startDir = Fs.realpathSync(__dirname); + const startDir = __dirname; const { root: rootDir } = Path.parse(startDir); let cursor = startDir; while (true) { diff --git a/scripts/build_kibana_platform_plugins.js b/scripts/build_kibana_platform_plugins.js index 809e21bc652d0..fa630e0bb1808 100644 --- a/scripts/build_kibana_platform_plugins.js +++ b/scripts/build_kibana_platform_plugins.js @@ -6,6 +6,7 @@ * Side Public License, v 1. */ +require('../src/setup_node_env/ensure_node_preserve_symlinks'); require('@kbn/optimizer').runKbnOptimizerCli({ defaultLimitsPath: require.resolve('../packages/kbn-optimizer/limits.yml'), }); diff --git a/scripts/jest.js b/scripts/jest.js index 48d202994c139..0ff6a0dcf5373 100755 --- a/scripts/jest.js +++ b/scripts/jest.js @@ -6,4 +6,5 @@ * Side Public License, v 1. */ +require('../src/setup_node_env/ensure_node_preserve_symlinks'); require('@kbn/test').runJest(); diff --git a/scripts/jest_integration.js b/scripts/jest_integration.js index a1851e039f45c..7332f368b31e2 100755 --- a/scripts/jest_integration.js +++ b/scripts/jest_integration.js @@ -6,6 +6,7 @@ * Side Public License, v 1. */ +require('../src/setup_node_env/ensure_node_preserve_symlinks'); process.argv.push('--runInBand'); require('@kbn/test').runJest('jest.config.integration.js'); diff --git a/scripts/kbn.js b/scripts/kbn.js index 3536157656b59..f384c13a3acfc 100644 --- a/scripts/kbn.js +++ b/scripts/kbn.js @@ -6,5 +6,6 @@ * Side Public License, v 1. */ +require('../src/setup_node_env/ensure_node_preserve_symlinks'); require('../src/setup_node_env/node_version_validator'); require('../packages/kbn-pm/cli'); diff --git a/scripts/precommit_hook.js b/scripts/precommit_hook.js index 17ce14af50273..1a4176bf142a0 100644 --- a/scripts/precommit_hook.js +++ b/scripts/precommit_hook.js @@ -6,5 +6,6 @@ * Side Public License, v 1. */ +require('../src/setup_node_env/ensure_node_preserve_symlinks'); require('@kbn/optimizer').registerNodeAutoTranspilation(); require('../src/dev/run_precommit_hook'); diff --git a/scripts/test_hardening.js b/scripts/test_hardening.js index cc058d742751d..a719d77c517ee 100644 --- a/scripts/test_hardening.js +++ b/scripts/test_hardening.js @@ -6,6 +6,8 @@ * Side Public License, v 1. */ +require('../src/setup_node_env/ensure_node_preserve_symlinks'); + var execFileSync = require('child_process').execFileSync; var path = require('path'); var syncGlob = require('glob').sync; diff --git a/src/dev/cli_dev_mode/dev_server.test.ts b/src/dev/cli_dev_mode/dev_server.test.ts index d29e6eb04cb92..c296c7caca63a 100644 --- a/src/dev/cli_dev_mode/dev_server.test.ts +++ b/src/dev/cli_dev_mode/dev_server.test.ts @@ -122,7 +122,10 @@ describe('#run$', () => { "ELASTIC_APM_SERVICE_NAME": "kibana", "isDevCliChild": "true", }, - "nodeOptions": Array [], + "nodeOptions": Array [ + "--preserve-symlinks-main", + "--preserve-symlinks", + ], "stdio": "pipe", }, ], diff --git a/src/setup_node_env/ensure_node_preserve_symlinks.js b/src/setup_node_env/ensure_node_preserve_symlinks.js new file mode 100644 index 0000000000000..0d72ec85e6c87 --- /dev/null +++ b/src/setup_node_env/ensure_node_preserve_symlinks.js @@ -0,0 +1,63 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +(function () { + var cp = require('child_process'); + + var preserveSymlinksOption = '--preserve-symlinks'; + var preserveSymlinksMainOption = '--preserve-symlinks-main'; + var nodeOptions = (process && process.env && process.env.NODE_OPTIONS) || []; + var nodeExecArgv = (process && process.execArgv) || []; + + var isPreserveSymlinksPresent = + nodeOptions.includes(preserveSymlinksOption) || nodeExecArgv.includes(preserveSymlinksOption); + var isPreserveSymlinksMainPresent = + nodeOptions.includes(preserveSymlinksMainOption) || + nodeExecArgv.includes(preserveSymlinksMainOption); + + if (isPreserveSymlinksPresent && isPreserveSymlinksMainPresent) { + return; + } + + var nodeArgv = (process && process.argv) || []; + var isFirstArgNode = nodeArgv.length > 0 && nodeArgv[0].includes('node') ? nodeArgv[0] : null; + if (!isFirstArgNode) { + return; + } + + var missingNodeArgs = []; + if (!isPreserveSymlinksMainPresent) { + missingNodeArgs.push(preserveSymlinksMainOption); + } + + if (!isPreserveSymlinksPresent) { + missingNodeArgs.push(preserveSymlinksOption); + } + + var nodeArgs = nodeExecArgv.concat(missingNodeArgs); + var restArgs = nodeArgv.length >= 2 ? nodeArgv.slice(1, nodeArgv.length) : []; + + var getExitCodeFromSpawnResult = function (spawnResult) { + if (spawnResult.status !== null) { + return spawnResult.status; + } + + if (spawnResult.signal !== null) { + return 128 + spawnResult.signal; + } + + if (spawnResult.error) { + return 1; + } + + return 0; + }; + + var spawnResult = cp.spawnSync(nodeArgv[0], nodeArgs.concat(restArgs), { stdio: 'inherit' }); + process.exit(getExitCodeFromSpawnResult(spawnResult)); +})(); diff --git a/src/setup_node_env/no_transpilation.js b/src/setup_node_env/no_transpilation.js index c52eba70f4ad3..1826f5bb0297d 100644 --- a/src/setup_node_env/no_transpilation.js +++ b/src/setup_node_env/no_transpilation.js @@ -6,6 +6,8 @@ * Side Public License, v 1. */ +require('./ensure_node_preserve_symlinks'); + // The following require statements MUST be executed before any others - BEGIN require('./exit_on_warning'); require('./harden'); diff --git a/tsconfig.base.json b/tsconfig.base.json index 865806cffe5bb..5220601e794b0 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -36,6 +36,8 @@ // Resolve modules in the same way as Node.js. Aka make `require` works the // same in TypeScript as it does in Node.js. "moduleResolution": "node", + // Do not resolve the real path of symlinks + "preserveSymlinks": true, // "resolveJsonModule" allows for importing, extracting types from and generating .json files. "resolveJsonModule": true, // Disallow inconsistently-cased references to the same file. diff --git a/x-pack/package.json b/x-pack/package.json index 97fe5144f135a..14c59cf89a74e 100644 --- a/x-pack/package.json +++ b/x-pack/package.json @@ -9,9 +9,7 @@ "kbn": "node ../scripts/kbn", "kbn:bootstrap": "node plugins/canvas/scripts/storybook --clean", "start": "node ../scripts/kibana --dev", - "build": "../node_modules/.bin/gulp build", - "testonly": "echo 'Deprecated, use `yarn test`'", - "test": "../node_modules/.bin/gulp test", + "build": "node --preserve-symlinks ../node_modules/.bin/gulp build", "test:jest": "node ../scripts/jest" }, "kibana": { diff --git a/x-pack/plugins/apm/e2e/cypress/webpack.config.js b/x-pack/plugins/apm/e2e/cypress/webpack.config.js index d22e947515db8..afeb527cd6b08 100644 --- a/x-pack/plugins/apm/e2e/cypress/webpack.config.js +++ b/x-pack/plugins/apm/e2e/cypress/webpack.config.js @@ -8,6 +8,7 @@ module.exports = { resolve: { extensions: ['.ts', '.js'], + symlinks: false, }, node: { fs: 'empty', child_process: 'empty', readline: 'empty' }, module: { diff --git a/x-pack/plugins/canvas/shareable_runtime/webpack.config.js b/x-pack/plugins/canvas/shareable_runtime/webpack.config.js index 91df495d1552d..34fade58ffc8d 100644 --- a/x-pack/plugins/canvas/shareable_runtime/webpack.config.js +++ b/x-pack/plugins/canvas/shareable_runtime/webpack.config.js @@ -43,6 +43,7 @@ module.exports = { core_app_image_assets: path.resolve(KIBANA_ROOT, 'src/core/public/core_app/images'), }, extensions: ['.js', '.json', '.ts', '.tsx', '.scss'], + symlinks: false, }, module: { rules: [ diff --git a/x-pack/plugins/canvas/storybook/webpack.config.js b/x-pack/plugins/canvas/storybook/webpack.config.js index 0523680148b04..77b8d343a2bea 100644 --- a/x-pack/plugins/canvas/storybook/webpack.config.js +++ b/x-pack/plugins/canvas/storybook/webpack.config.js @@ -190,6 +190,7 @@ module.exports = async ({ config: storybookConfig }) => { '../tasks/mocks/uiAbsoluteToParsedUrl' ), }, + symlinks: false, }, }; diff --git a/x-pack/plugins/canvas/storybook/webpack.dll.config.js b/x-pack/plugins/canvas/storybook/webpack.dll.config.js index 5c474ddebfa5f..3051bbebdaf0c 100644 --- a/x-pack/plugins/canvas/storybook/webpack.dll.config.js +++ b/x-pack/plugins/canvas/storybook/webpack.dll.config.js @@ -82,6 +82,7 @@ module.exports = { alias: { ui: path.resolve(KIBANA_ROOT, 'src/legacy/ui/public'), }, + symlinks: false, }, module: { rules: [ diff --git a/x-pack/tasks/build.ts b/x-pack/tasks/build.ts index 4b6bc29284748..1b52b073b3cef 100644 --- a/x-pack/tasks/build.ts +++ b/x-pack/tasks/build.ts @@ -94,12 +94,16 @@ async function copySourceAndBabelify() { } async function buildCanvasShareableRuntime() { - await execa(process.execPath, ['plugins/canvas/scripts/shareable_runtime'], { - cwd: XPACK_DIR, - stdio: ['ignore', 'inherit', 'inherit'], - // @ts-ignore Incorrect @types - execa supports `buffer` - buffer: false, - }); + await execa( + process.execPath, + ['--preserve-symlinks', 'plugins/canvas/scripts/shareable_runtime'], + { + cwd: XPACK_DIR, + stdio: ['ignore', 'inherit', 'inherit'], + // @ts-ignore Incorrect @types - execa supports `buffer` + buffer: false, + } + ); } async function generateNoticeText() {