Skip to content
Snippets Groups Projects
Select Git revision
  • a20ca3c8a5ab063312dd1d076d093954dd447c36
  • main default protected
  • renovate/main-ghcr.io-renovatebot-base-image-10.x
  • renovate/main-ghcr.io-containerbase-devcontainer-13.x
  • next
  • revert-31645-feat/rename-gradle-wrapper-validation-action
  • renovate/main-redis-5.x
  • fix/36615b-branch-reuse-no-cache
  • chore/punycode
  • fix/36615-branch-reuse-bug
  • refactor/pin-new-value
  • feat/36219--git-x509-signing
  • feat/structured-logger
  • hotfix/39.264.1
  • feat/skip-dangling
  • gh-readonly-queue/next/pr-36034-7a061c4ca1024a19e2c295d773d9642625d1c2be
  • hotfix/39.238.3
  • refactor/gitlab-auto-approve
  • feat/template-strings
  • gh-readonly-queue/next/pr-35654-137d934242c784e0c45d4b957362214f0eade1d7
  • fix/32307-global-extends-merging
  • 41.31.1
  • 41.31.0
  • 41.30.5
  • 41.30.4
  • 41.30.3
  • 41.30.2
  • 41.30.1
  • 41.30.0
  • 41.29.1
  • 41.29.0
  • 41.28.2
  • 41.28.1
  • 41.28.0
  • 41.27.1
  • 41.27.0
  • 41.26.2
  • 41.26.1
  • 41.26.0
  • 41.25.1
  • 41.25.0
41 results

utils.ts

Blame
  • user avatar
    Carlin St Pierre authored and Rhys Arkins committed
    fix: Allow Date objects to pass through sanitizeValue without all of the fields being removed (#4809)
    
    This fixes an issue where timestamps were not being logged because `Object.entries<any>(value)` for a Date object would return `{}`.
    a20ca3c8
    History
    utils.ts 2.49 KiB
    import fs from 'fs-extra';
    import bunyan from 'bunyan';
    import { Stream } from 'stream';
    import { sanitize } from '../util/sanitize';
    
    export interface BunyanRecord extends Record<string, any> {
      level: number;
      msg: string;
      module?: string;
    }
    
    const excludeProps = ['pid', 'time', 'v', 'hostname'];
    
    export class ErrorStream extends Stream {
      private _errors: BunyanRecord[] = [];
    
      readable: boolean;
    
      writable: boolean;
    
      constructor() {
        super();
        this.readable = false;
        this.writable = true;
      }
    
      write(data: BunyanRecord) {
        const err = { ...data };
        for (const prop of excludeProps) delete err[prop];
        this._errors.push(err);
        return true;
      }
    
      getErrors() {
        return this._errors;
      }
    }
    
    function sanitizeValue(value: any, seen = new WeakMap()) {
      if (Array.isArray(value)) {
        const length = value.length;
        const arrayResult = Array(length);
        seen.set(value, arrayResult);
        for (let idx = 0; idx < length; idx += 1) {
          const val = value[idx];
          arrayResult[idx] = seen.has(val)
            ? seen.get(val)
            : sanitizeValue(val, seen);
        }
        return arrayResult;
      }
    
      const valueType = typeof value;
    
      if (value != null && valueType !== 'function' && valueType === 'object') {
        if (value instanceof Date) {
          return value;
        }
    
        const objectResult: Record<string, any> = {};
        seen.set(value, objectResult);
        for (const [key, val] of Object.entries<any>(value)) {
          objectResult[key] = seen.has(val)
            ? seen.get(val)
            : sanitizeValue(val, seen);
        }
        return objectResult;
      }
    
      return valueType === 'string' ? sanitize(value) : value;
    }
    
    export function withSanitizer(streamConfig): bunyan.Stream {
      if (streamConfig.type === 'rotating-file')
        throw new Error("Rotating files aren't supported");
    
      const stream = streamConfig.stream;
      if (stream && stream.writable) {
        const write = (chunk: BunyanRecord, enc, cb) => {
          const raw = sanitizeValue(chunk);
          const result =
            streamConfig.type === 'raw'
              ? raw
              : JSON.stringify(raw, bunyan.safeCycles()).replace(/\n?$/, '\n');
          stream.write(result, enc, cb);
        };
    
        return {
          ...streamConfig,
          type: 'raw',
          stream: { write },
        };
      }
    
      if (streamConfig.path) {
        const fileStream = fs.createWriteStream(streamConfig.path, {
          flags: 'a',
          encoding: 'utf8',
        });
    
        return withSanitizer({ ...streamConfig, stream: fileStream });
      }
    
      throw new Error("Missing 'stream' or 'path' for bunyan stream");
    }