Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New command: create a document of a pack as JSON file #39

Open
Lyokolux opened this issue Oct 4, 2023 · 0 comments
Open

New command: create a document of a pack as JSON file #39

Lyokolux opened this issue Oct 4, 2023 · 0 comments

Comments

@Lyokolux
Copy link

Lyokolux commented Oct 4, 2023

Description

For the sake of clarity, I refer to the following as a document: an object or item in a pack.

Managing a pack as a group of JSON files is proficient for developers. In our carbonsquad project, we are starting to use the following flow in our game module: JSON files -> build packs -> the Foundry server reads the packs. We get advantages: the packs can be created without having to wait for the UI to support each item property. It is a good win for prototyping, or integrating a bunch of documents in a row. It is also a good way to version the documents in git, and generating the packs from them automatically.

As I searched through modules, everyone used this flow or the interface to add new items. Both should be supported for a great experience. There is no official way to do it though, and each project has to implement its own version. It results in a waste of time that could be used for something else.

What advantages does it bring?

  • there is already a way to do it. So it can be used and called a day instead of understanding it first, then recreating a small tool for it.
  • it will be more robust than a quick implementation in 2 hours
  • all item boilerplate will be generated:
    • id
    • type
    • img base path if one exists
    • properties of the related template.json type
  • avoid some typo mistakes in the generated properties

How to use it

I don't know yet how to, but I am thinking of this CLI as actions on resources: on packs, on documents, etc... So one way could be:

fvtt document create <pack-name>

The user is then asked some questions (similar to RPG) in order to create the document. Each step can then be validated, or everything can be provided as parameters of the command.

The function that generates the JSON file could be exported and reused by other projects if one has specific needs as it is already done by the other commands.

I am also open to suggestions, as I am searching for an easy and safe flow. I am looking forward to implementing it.

Implementation

I still don't understand some pieces that makes a robust and reusable document ID in Foundry. ``!${type}!${documentSlug}` seems ok but it is somehow not a good fit.

Here is a raw implementation as a simple js script, in which we get the structure (parameters, some checking, generating the JSON object, and saving the file.

import fs from "fs"
import path from "path"

// this can be set in a config file for example
const BASE_DIR = path.join("packs", "src")
// This can be set in a config file for example
const BASE_IMG_REF = "systems/<pack-name>/media/"

const TYPES = ["actors", "adventures", "cards", "messages", "combats", "fog", "folders", "items", "journal", "macros", "playlists", "tables",
  "scenes", "settings", "users"]

/**
 * @param {number} len
 * @returns {string}
 */
const generateID = (len = 16) => {
  const p = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
  return [...Array(len)].reduce(a => a + p[~~(Math.random() * p.length)], "")
}

/**
 * @param {string} s
 * @returns {string}
 */
const slugify = s => s.replaceAll(" ", "-").toLowerCase()

// read the parameters as passed to the cli
const [_, _2, type, name, dirpath] = process.argv

if (!type || !name) {
  console.error("ERR: A type and a name must be provided. Use the following")
  console.error("npm run generateDocumentTpl <type> <name> <dir>")
  process.exit(1)
}

if (!dirpath) {
  console.error("ERR: A path must be provided as last argument.")
  process.exit(1)
}

const dir = path.resolve(BASE_DIR, dirpath)
if (!fs.existsSync(dir)) {
  fs.mkdirSync(dir)
  console.info(`INFO: The directory ${dir} does not exist. One is created`)
}

if (!TYPES.includes(type)) {
  console.error(`ERR: The type should be one of ${TYPES.join(", ")}.`)
  process.exit(1)
}

const documentSlug = slugify(name)
const document = {
  _id: generateID(),
  _key: `!${type}!${documentSlug}`,
  img: `${BASE_IMG_REF}/TODO`,
  name,
  system: {}
}

const dest = path.resolve(BASE_DIR, dir, `${documentSlug}.json`)

fs.writeFileSync(
  dest,
  JSON.stringify(document, undefined, 2)
)

console.log(`Document "${name}" generated in ${dest}`)
console.log("Complete the img path, then the system properties.")
@Lyokolux Lyokolux changed the title Create an item of a pack as JSON file New command: create a document of a pack as JSON file Oct 4, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant