Pyro-resource - a TypeScript library for generating project resource imports files

Hello all!

I am pleased to announce the 1.0.0 release of pyro-resource, a TypeScript library for generating project resource import files (.zip). As more and more of Ignition's resource structure is moving to plain JSON, JavaScript is becoming a natural language to use when scripting the creation of resources.

This library allows you easily script the creation of new resources, and provides automatic generation of signed resource.json files.

  • Create a project and add your resources
  • Call project.zip()
  • Write the file to disk
  • Import directly into Ignition
import fs from 'fs'
import { newProject, perspective } from '@mussonindustrial/pyro-resource'

const project = newProject({ perspective })

const styleClasses = project.perspective.resources.styleClasses
styleClasses.node('MyStyleClass', {
    'style.json': '{ base: { style: {} } }',
})

const zip = await project.zip()
fs.writeFileSync('./project-import.zip', zip)

And for module developers, custom modules and resource types can be created.

import {
    newFolderResource,
    newModule,
    newNodeResource,
    newProject,
} from '@mussonindustrial/pyro-resource'

const myFolderResource = newFolderResource('my-resource', ['file.json'])

const mySingletonResource = newNodeResource('my-singleton-resource', [
    'file.json',
    'image.png',
    'another.xml',
])

const myModule = newModule('com.acme.module', {
    myFolderResource,
    mySingletonResource,
})

const project = newProject({ myModule })

project.myModule.resources
// (property) resources: {
//     myFolderResource: FolderResource<readonly ["file.json"]>;
//     mySingletonResource: NodeResource<readonly ["file.json", "image.png", "another.xml"]>;
// }

See the GitHub page for full details.

pyro-resource

If you're only interested in the resource.json signature generation, check out pyro-resource-signature located in the same monorepo; this contains all of the signature generation and verification logic. (Big props to @PGriffith for his modification-updater application, from which the signature generation was borrowed).

4 Likes

Very cool! Have you played around with Deno at all? My understanding is it's a typescript-first Node alternative with some niceties that might make for an easy self contained CLI interpreter or something like that.

I'm also curious - where do you find you use this? Fleshing out "skeleton" projects before launch, or actually applying bulk updates to existing projects, or something else? I'm really curious about this space and what we could do first party to meet some of the same needs/help folks out with advanced use cases like this.

I also think a natural followup is a typed builder/DSL for Views :slight_smile: That'd be a fun exercise, I'm sure; trying to make a more dev friendly resource scheme that still ends up with the same JSON as the designer.

I have, it seems to be doing a lot of things right!
Node + TypeScript is fantastic, but there's so much background-knowledge required to set it all up. Any alternative that strives to lower the barriers to entry is a win in my book. Last time I tried it, it didn't have NPM compatibility which turned me off; it looks like that's changed though?

My immediate use case is for generating stub Perspective style classes (with the main CSS located in a custom theme). With this library + my postcss-perspective-style-class plugin, I can reference arbitrary PSC names in my CSS, then at build time, have those PSCs zipped up for import.

// /src/theme.css
[psc='Folder1/class'] {
    color: black;
}

// /dist/theme.css
.psc-Folder1\/class {
    color: black;
}

// /dist/import.zip
com.inductiveautomation.perspective
 style-classes/Folder1/class
   style.json
    resource.json

By itself it's nothing crazy, but when combined with other postcss plugins such as postcss-advanced-variables, postcss-nested, and autoprefixer, the possibilities explode.

@for $count from 1 to 5 by 2 {
  @if $count > 2 {
    [psc=Columns/$count] {
      width: #{$count}0%;
    }
  }
}

Absolutely, I'm very interested in trying to take this to that point.

My next steps are going to be focused on PSCs (I'd like to be able to move the style content from simple selectors directly into the PSC resources, instead of just being stubs).

2 Likes