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 🙏

© 2024 – Pkg Stats / Ryan Hefner

@gcanossa/gas-app

v2.0.1

Published

Google Apps Script application building framework

Downloads

7

Readme

Google App Script Frameowrk

The library exists to facilitate the impleentation of an application on the Google App Script platform.

The library is composed of three parts: server, client and mocking.

Server

On the server side (Google App Script) use the function createGasApp(methods) to build an object with the following type:

export type GasApp = {
  invoke(name: string, ...params: any[]): any;
};

The function configures a map of functions scoped by the library that can be invoked indirectly throgh the method invoke

The invoke method of the returned object allows to call a scoped function by name.

On the server side is also avilable the function include that produces an HtmlTemplate from a file and return the evaluated content. Can be used to include/import files in an html template.

In order to use the module functions they must be exposed with a global scope function.

import { createGasApp, include } from "@gcanossa/gas-app/server";

const app = createGasApp({
  sum(a: number, b: number) {
    return a + b;
  },
});

function appinvoke(...params: any[]): any {
  return app.invoke(...params);
}

function myInclude(...params: any[]): string {
  return include(...params);
}

Client

On the client side (an Html page served from Google App Script) are available:

  • createBridge(): implements a Proxy getting type inference for the server side functions through the standard window.google.script interface. Every function returns a Promise<[result, userObject]> and comes in two flavours: <name>(...args) and ctx_<name>(userObject, ...args).
  • createGasAppBridge(invokeFunctionName: string): does the same thing ad createBridge, but for the functions scoped with GasApp init and called throgh GasApp invoke. The parameter invokeFunctionName is the name of the functio used to expose the invoke method.

Mocking

On the client side (an Html page served from Google App Script) the function initMocks(mocks, appMocks) initialize a mock window.google.script object applying the mocks typing. The two configuration parameters are maps of functions which mocks the server side one. The parameter appMocks is a map of functions maps which mocks one or multiple server side gas app. Each key is the name of the function exposing invoke.

Usage

On the server side (Google App Script) create the desired functions:

function sum(a, b) {
  return a + b;
}

function sub(a, b) {
  return a - b;
}

function mul(a, b) {
  return a * b;
}

function div(a, b) {
  return a / b;
}

If necessary scope the with the library:

export type ScopedServerFn = {
  sum: typeof sum;
  mul: typeof mul;
};
export type ServerFn = {
  sub: typeof sub;
  div: typeof div;
};

const app = createGasApp<ScopedServerFn>({ sum, mul };

function myApp(...params:any[]){
  return app.invoke(...params);
}

On the client create the bridges using the server side exported type:

import { ScopedServerFn, ServerFn } from "./code.ts";

const bridge = createBridge<typeof ServerFn>();
const coreBridge = createGasAppBridge<typeof ScopedServerFn>();

Init the mocks in development mode:

if(import.meta.env.DEV){ //expample using with vite
  const gas = initMocks<typeof ServerFn>({
    async sum(a, b) { // NOTE: must be a Promise for every mock to mimic server behaviour
      return a + b;
    },
    ...
  }, {
    myApp:{
      ...
    }
    ...
  });
}

Call the methods:

const [res, _] = await bridge.sum(1, 2);
const [res2, { val }] = await bridge.ctx_sum({ val: "test" }, 1, 2);

const [re3, _] = await appBridge.mul(1, 2);
const [res4, { msg }] = await appBridge.ctx_mul({ msg: "test" }, 1, 2);

Usage in Html template

If you need to include/import a file into another Html template, use the *function exposing the *include** function:

main.html

...

<?!= myInclude('path/to/file', { val: 3 }) ?>
...

path/to/file.html

<h1>Title</h1>

<p>
  Value is:
  <?= val ?>
</p>

Vite plugin

The library contains also a vite function plugin viteGasApp which allows to create simple html pages to be renderd by Google Apps Script.

The plugin explores the input path and expect a structure like this:

/<input>
  /ui
    global.css
    app.js
    utils.js
    /page1
      view.html
      script.js
      style.css
    /page2
      view.html
      script.js
      style.css

Basically a set of .html, .css and .js inside a ui folder. The plugin reproduce the same hierarchy in the destination folder wrapping .js files in <script></script> tags and .css in <style></style> tags and renaming the files in .js.html and .css.html. The script searches the .html files for <script> and <style> tags with the attribute x-gas-include, if found rewrites the tag using the scriptlet <?!= myInclude(...) ?> (example name) effectively inlining the resource. This allows a comfortable local development inlcuding the .js and .css files from the filesystem and an organized clasp folder keeping the script and style resources separated like in local development.