npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@mcpher/fake-gasenum

v1.0.6

Published

A interpretation of Apps Script Enums on Node

Readme

Fake Gas Enum

Allows creation of Apps Script Style Enums in both Node (npm module) and Apps Script (library available).

installation Node

npm i @mcpher/fake-gas-enum

Usage

import { newFakeGasenum } from '../main.js'
const Fruit = newFakeGasenum (["APPLE", "BANANA", "ORANGE"])

installation Apps Script

Add library bmFakeGasenum (id: 1n-YigdcvdSF-_lY61YR8a3ejbcgqNGiyKTxepcY13jEdNXUx9QNo5Miq)

Usage

const { newFakeGasenum } = bmFakeGasenum.Exports 
const Fruit = newFakeGasenum (["APPLE", "BANANA", "ORANGE"])

Enums in Apps Script

Replicating the Enum structure in Apps Script is tricky, as they are kind of odd structures to us JavaScript, unused as we are to having the kind of Enum structures you'd find in languages like Java. Apps Script is built on a back end infrastructure that is Java influenced, and until a few years ago actual ran on a JVM based JavaScript interpreter. Nowadays it runs on a V8 runtime, but the Java structural influences can still be found all over Apps Script.

Enum properties

Let's look at the SpreadsheetApp.ColorType object, which is documented to have 3 properties

  • UNSUPPORTED
  • RGB
  • THEME

Enum keys

It's not a plain object with the these keys as you'd expect, but instead is an instanciation of a class with these properties

  • toString()
  • name()
  • toJSON()
  • ordinal(
  • compareTo()
  • UNSUPPORTED
  • RGB
  • THEME
  • Symbol(enum_ordinal)

Circularity

Each of the 3 property values (.UNSUPPORTED,.RGB and .THEME) have exactly the same object structure - in other words they reference each other - with only the functions returning like name() returning the value that matches the key name.

Spreadsheet.ColorType returns the exactly same (===) object as Spreadsheet.ColorType.UNSUPPORTED, so they point to the same instance.

This leads to an unusal circularity, where SpreadsheetApp.ColorType.RGB.RGB.RGB.RGB exists and is the same object as Spreadsheet.ColorType.RGB, and even SpreadsheetApp.ColorType.RGB.RGB.RGB.RGB.THEME === Spreadsheet.ColorType.THEME

name(),toJSON() and toString() all return the same value - for example RGB and compareTo is used to compare enums from the same Enum by returning the difference between their ordinals, which is useful for sorting enum values.

The name() of the base object - for example SpreadsheetApp.BandingTheme.toString() returns the default value "LIGHT_GREY" for the enum. In the case of SpreadsheetApp.ColorType, the default value is "UNSUPPORTED" as is often the case with enums that are used when there are builder classes involved.

Approach to replicating

I'm not saying all this circularity is a good thing, by the way, but that's what it is.

Here's a set of tests imitating the Apps Script ColorType Enum

    /// apps script fake example
  const keys = ["UNSUPPORTED", "RGB", "THEME"]

  // imitate the SpreadsheetApp.ColorType enum
  const ColorType = newFakeGasenum (keys)

  t.is(ColorType.toString(), "UNSUPPORTED")
  t.is(ColorType.name(), "UNSUPPORTED")
  t.is(ColorType.toJSON(), "UNSUPPORTED")
  t.is(ColorType.ordinal(), 0)
  t.is(ColorType.compareTo(ColorType.UNSUPPORTED), 0)
  t.is(ColorType.RGB.toString(), "RGB")
  t.is(ColorType.RGB.name(), "RGB")
  t.is(ColorType.RGB.toJSON(), "RGB")
  t.is(ColorType.RGB.ordinal(), 1)
  t.is(ColorType.RGB.compareTo(ColorType.RGB), 0)
  t.is(ColorType.THEME.toString(), "THEME") 
  t.is(ColorType.THEME.name(), "THEME")
  t.is(ColorType.THEME.toJSON(), "THEME")
  t.is(ColorType.THEME.ordinal(), 2)
  t.is(ColorType.THEME.compareTo(ColorType.THEME), 0)

  t.is(ColorType.THEME.compareTo(ColorType), 2)
  t.is(ColorType.RGB.compareTo(ColorType), 1)
  t.is(ColorType.RGB.compareTo(ColorType.THEME), -1)

  t.is(ColorType.THEME.RGB.RGB.THEME.UNSUPPORTED.RGB.RGB.toString(), "RGB", "just some Apps Script weirdness")

Default key

As you'll have seen, the FakeGasenum has a default value. In the case of the ColorType above, ColorType.name() is the same as ColorType.UNSUPPORTED.name(). This is simply the first value in the array of keys you provide to newFakeGasenum(keys).

If you really want to for some reason, you can provide a different default value.

const Fruit = newFakeGasenum (["apple", "banana", "orange"], "orange")

// in this case
t.is(Fruit.name(), "orange")
t.is(Fruit.name(), Fruits.orange.name())

Note that there is no case conversion performed, so in keeping with convention you should probably use upper case for the key names.

const Fruit = newFakeGasenum (["APPLE", "BANANA", "ORANGE"], "ORANGE")

// in this case
t.is(Fruit.name(), "ORANGE")
t.is(Fruit.name(), Fruits.ORANGE.name())

Proxy guarding

To exactly imitate Apps Script, the default behavior when you access an undefined property (CoorType.foo for example) is to return undefined. I prefer to throw an error in these circumstances, so there is a 'safe' variant available.

import { newFakeGasenumSafe } from '../main.js'
const p = newFakeGasenumSafe (["APPLE", "BANANA", "ORANGE"])

All key accesses are checked for validity via a proxy and will throw an error if you try to access a key that doesn't exist.

 t.is( t.threw (()=>p.foo).message, "attempt to get non-existent property foo in fake-gas-enum", "check proxies are guarding")

You can of course still use Reflect to see if an Enum has a particular key defined.

Reflect.has (p, "foo") // false

I recommend using this safe variant. A circumstance where you might prefer to go with the looser unsafe version is if your code (or modules you import) probe for values rather than check for presence of keys.

Custom Values

You can also assign custom values to enum keys by passing an object instead of an array. This is useful when the toString() value of an enum should be different from its key name.

const MyEnum = newFakeGasenum({
  KEY1: "Value 1",
  KEY2: "Value 2"
});

t.is(MyEnum.KEY1.name(), "KEY1");
t.is(MyEnum.KEY1.toString(), "Value 1");
t.is(MyEnum.KEY1.toJSON(), "Value 1");

If you pass values as numbers, they will be stringified for toString() but preserved as numbers for toJSON().

const NumericEnum = newFakeGasenum({ ONE: 1, TWO: 2 });
t.is(NumericEnum.ONE.toString(), "1");
t.is(NumericEnum.ONE.toJSON(), 1);

Conclusion

This project is associated with the project to imitate a synchronous Apps Script environment directly on Node - gas-fakes

You'll find all the Apps Script Enums coded using this technique in the src/services/enums folder