FirestoreGoogleAppsScript icon indicating copy to clipboard operation
FirestoreGoogleAppsScript copied to clipboard

How to import typings for Typescript apps script development

Open davidbielik opened this issue 4 years ago • 1 comments

I see that since #87 this library was converted to Typescript. What's the correct way to import typescript definitions so that it can be used within VSCode?

Minimal Code to Reproduce the Problem

Explain the Problem in Detail

I've tried importing it as a reference:

/// <reference path="../node_modules/firestore_google-apps-script/typings/index.d.ts" />

But this only imports a FirestoreAPI which comes from typings/index.d.ts

It's unclear how I should use this to develop in a Typescript environment.

Thanks in advance!

Library Version: 33

davidbielik avatar Jan 12 '22 00:01 davidbielik

I haven't used VSCode with this project yet, but I can't imagine it would be too difficult. Sorry I can't help further with this. But I pretty much used command line tools to integrate with GAS to update the library.

LaughDonor avatar Feb 04 '22 22:02 LaughDonor

@davidbielik Any luck with this? I am interested in importing typescript types for local development as well.

BarryMolina avatar Sep 01 '22 18:09 BarryMolina

@davidbielik @BarryMolina

Here's my firestore.ts file that's also used to import the other typings:

// This is required because it "imports" the typings (importing them breaks the runtime and tsconfig doesn't seem to detect them.)
/// <reference path="../../../node_modules/@types/google-apps-script/index.d.ts" />

// These are required because they "import" the FirestoreApp library.
/// <reference path="../../../node_modules/firestore_google-apps-script/typings/index.d.ts" />
/// <reference path="../../../node_modules/firestore_google-apps-script/Document.ts" />
/// <reference path="../../../node_modules/firestore_google-apps-script/Firestore.ts" />

/**
 * Documentation:
 * https://github.com/grahamearley/FirestoreGoogleAppsScript
 */
export const firestore = getFirestore();

// The libary is provided through this object, but the ts references above don't.
declare const FirestoreApp: {
  getFirestore(email: string, key: string, projectId: string, apiVersion?: Version): Firestore;
};

export function getFirestore() {
  const email = PropertiesService.getScriptProperties().getProperty("SERVICE_ACCOUNT_EMAIL");

  // replaceAll is necessary, because the property value doesn't allow newlines
  const key = PropertiesService.getScriptProperties().getProperty("SERVICE_ACCOUNT_KEY")?.replaceAll("\\n", "\n");
  const projectId = "die-ringe-bodyworkout-app";

  return FirestoreApp.getFirestore(email!, key!, projectId);
}

export function unwrapObject(obj: Document): ValueObject {
  return Object.entries(obj.fields || {}).reduce(
    (o: Record<string, Value>, [key, val]: [string, FirestoreAPI.Value]) => {
      o[key] = unwrapValue(val);
      return o;
    },
    {}
  );
}

function unwrapValue(obj: FirestoreAPI.Value): Value {
  // eslint-disable-next-line prefer-const
  let [type, val]: [string, any] = Object.entries(obj)[0];
  switch (type) {
    case "referenceValue":
    case "bytesValue":
    case "stringValue":
    case "booleanValue":
    case "geoPointValue":
      return val;
    case "doubleValue":
      return parseFloat(val as string);
    case "integerValue":
      return parseInt(val as string);
    case "mapValue":
      return unwrapObject(val as FirestoreAPI.MapValue);
    case "arrayValue":
      return unwrapArray(val.values);
    case "timestampValue":
      return unwrapDate(val as string);
    case "nullValue":
    default:
      return null;
  }
}

function unwrapArray(wrappedArray: FirestoreAPI.Value[] = []): Value[] {
  return wrappedArray.map(unwrapValue, this);
}

function unwrapDate(wrappedDate: string): Date {
  // Copied from Util_.regexDatePrecision
  const regex = /(\.\d{3})\d+/;

  // Trim out extra microsecond precision
  return new Date(wrappedDate.replace(regex, "$1"));
}

looks like a pretty hacky solution to me, but it seems to work pretty neatly so far.

ciriousjoker avatar Sep 09 '22 13:09 ciriousjoker

I would like to also know how I can use this library outside of the web based editor. The above solution does not work in the context of my project!

jay-cascade avatar Mar 20 '24 10:03 jay-cascade