Search code examples
typescriptfirebasegoogle-cloud-functionsgoogle-cloud-logging

Adding @google-cloud/logging in typescript functions project gives error


EDIT: for others with the same problem - using const Logging: any = require('@google-cloud/logging') together with var logger = Logging() in the body of the class worked like a charm!

Remember to use var logger = Logging() to instantiate the logger library. Otherwise you will still get the logger.log is not a function!

Original post

I've got a firebase functions project, written in typescript - transpiled with webpack. I'm currently trying to implement the @google-cloud/logging library, but I'm having issues. It comes out saying

Could not find a declaration file for module "google-cloud/logging". Try npm install @types/@google-cloud/logging if it exists or add a new declaration (.d.ts) file containing declare module '@google-cloud/logging';

I've tried adding the library the following ways:

import * as Logging from '@google-cloud/logging';
import * as logging from '@google-cloud/logging';
import { Logging } from '@google-cloud/logging';

But I'm still getting this error. Trying to run a function which is using "logging" results in

logging.log is not a function

I have even tried the javascript way of requiring the library, still with no success.

My tsconfig.json:

{
    "compilerOptions": {
        "target": "es6",
        "module": "commonjs",
        "outDir": "./",
        "noImplicitAny": true
    },
    "include": [
        "src/**/*.ts"
    ],
    "exclude": [
        "node_modules"
    ]
}

I've read that some people had success by adding a "d.ts" file to the project manually, though I did not understand much of it. Here is the link to the article in stack overflow - Importing non-typescript module in typescript

How might I go about adding the library in a typescript project?

I can provide more details if needed. This was what I could think of including.


Solution

  • There is not yet type definitions for @google-cloud/logging. So you need to provide some ! In the meantime, you can do

    const Logging: any = require('@google-cloud/logging')
    

    If you have @types/node installed and target nodejs or if you target the browser but use "moduleResolution": "CommonJS" (you also need to provide node typefs).

    Otherwise, you can use

    import * as Logging from '@google-cloud/logging'
    

    But in that case you need to declare the types for this module

    // logging.d.ts
    declare module '@google-cloud/logging' {
    
      interface LogConfig {
        removeCircular: boolean
      }
    
      class Entry {
        metadata: object
        data: object
        constructor (metadata: object | null | undefined, data: object | string)
        constructor (data: object | string)
        toJSON (options?: LogConfig): any
      }
    
      interface WriteOptions {
        gaxOptions: object
        labels: object[]
        resource: object
      }
    
      type LogWriteCallback = (err: Error | null, apiResponse: object) => void
      type DeleteLogCallback = (err: Error | null, apiResponse: object) => void
    
      type LogWriteResponse = object[]
      type DeleteLogResponse = object[]
    
      type EntryArg = Entry | Entry[]
    
      class Log {
        constructor (logging: Logging, name: string, options: LogConfig)
        alert (entry: EntryArg, options?: WriteOptions, callback?: LogWriteCallback): Promise<LogWriteResponse>
        critical (entry: EntryArg, options?: WriteOptions, callback?: LogWriteCallback): Promise<LogWriteResponse>
        debug (entry: EntryArg, options?: WriteOptions, callback?: LogWriteCallback): Promise<LogWriteResponse>
        emergency (entry: EntryArg, options?: WriteOptions, callback?: LogWriteCallback): Promise<LogWriteResponse>
        info (entry: EntryArg, options?: WriteOptions, callback?: LogWriteCallback): Promise<LogWriteResponse>
        notice (entry: EntryArg, options?: WriteOptions, callback?: LogWriteCallback): Promise<LogWriteResponse>
        warning (entry: EntryArg, options?: WriteOptions, callback?: LogWriteCallback): Promise<LogWriteResponse>
        error (entry: EntryArg, options?: WriteOptions, callback?: LogWriteCallback): Promise<LogWriteResponse>
        write (entry: EntryArg, options?: WriteOptions, callback?: LogWriteCallback): Promise<LogWriteResponse>
        delete (gaxOptions: object): Promise<DeleteLogResponse>
        delete (gaxOptions: object, callback?: DeleteLogCallback): Promise<DeleteLogResponse>
        delete (callback?: DeleteLogCallback): Promise<DeleteLogResponse>
      }
    
      interface ClientConfig {
        projectId?: string
        keyFilename?: string
        email?: string
        credentials?: {
          client_email: string
          private_key: string
        }
        autoRetry?: boolean
        maxRetries?: number
        promise?: Function
      }
    
      class Logging {
        constructor (options: ClientConfig)
        log (name: string, options?: LogConfig): Log
        entry (resource: object | string | null | undefined, data: object | string): Entry
      }
      export = Logging
    }
    

    This definition is just a draft and a lot of functions are missing, but I guess it's a necessary first step :-)