Initialize project files
This commit is contained in:
parent
22a4cc1611
commit
643b2e0c88
16 changed files with 1833 additions and 0 deletions
2
.env.template
Normal file
2
.env.template
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
# The absolute path to the Foundry installation to create symlinks to
|
||||
FOUNDRY_ROOT=""
|
||||
51
.github/workflows/draft-release.yaml
vendored
Normal file
51
.github/workflows/draft-release.yaml
vendored
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
name: Create Draft Release
|
||||
on: [workflow_dispatch]
|
||||
jobs:
|
||||
everything:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
# Checkout the repository
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
# Install node and NPM
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: "19"
|
||||
|
||||
# Install required packages
|
||||
- run: npm install
|
||||
|
||||
- name: Reading the module.json for the version
|
||||
id: "version"
|
||||
run: cat module.json | echo version=`jq -r ".version"` >> "$GITHUB_OUTPUT"
|
||||
|
||||
# Check that tag doesn't exist
|
||||
- uses: mukunku/tag-exists-action@v1.5.0
|
||||
id: check-tag
|
||||
with:
|
||||
tag: "v${{ steps.version.outputs.version }}"
|
||||
|
||||
- name: "Ensure that the tag doesn't exist"
|
||||
if: ${{ steps.check-tag.outputs.exists == 'true' }}
|
||||
run: exit 1
|
||||
|
||||
- name: Update the manifest with the relevant properties
|
||||
id: manifest-update
|
||||
uses: microsoft/variable-substitution@v1
|
||||
with:
|
||||
files: "module.json"
|
||||
env:
|
||||
download: "https://github.com/${{ github.repository }}/releases/download/v${{ steps.version.outputs.version }}/release.zip"
|
||||
|
||||
- name: Create the zip
|
||||
run: zip -r release.zip module.json packs module langs assets templates README.md
|
||||
|
||||
- name: Create the draft release
|
||||
uses: ncipollo/release-action@v1
|
||||
with:
|
||||
tag: "v${{ steps.version.outputs.version }}"
|
||||
commit: ${{ github.ref }}
|
||||
draft: true
|
||||
body: <img aria-hidden="true" src="https://img.shields.io/github/downloads/${{ github.repository }}/v${{ steps.version.outputs.version }}/release.zip?style=flat-square&color=%2300aa00">
|
||||
generateReleaseNotes: true
|
||||
artifacts: "release.zip,module.json"
|
||||
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
node_modules/
|
||||
.env
|
||||
/foundry
|
||||
18
.vscode/foundry.html-data.json
vendored
Normal file
18
.vscode/foundry.html-data.json
vendored
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"version": 1.1,
|
||||
"globalAttributes": [
|
||||
{ "name": "data-tooltip", "description": "The content for the tooltip to display" },
|
||||
{ "name": "data-tooltip-direction", "description": "The direction that the tooltip renders in, in relation to the element that has the tooltip", "valueSet": "tooltip-direction" }
|
||||
],
|
||||
"valueSets": [
|
||||
{
|
||||
"name": "tooltip-direction",
|
||||
"values": [
|
||||
{ "name": "UP", "description": "Put the tooltip above the element" },
|
||||
{ "name": "LEFT", "description": "Put the tooltip to the left of the element" },
|
||||
{ "name": "RIGHT", "description": "Put the tooltip to the right of element" },
|
||||
{ "name": "DOWN", "description": "Put the tooltip below the element" }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
16
.vscode/settings.json
vendored
Normal file
16
.vscode/settings.json
vendored
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"files.exclude": {
|
||||
"**/node_modules": true,
|
||||
"foundry": true
|
||||
},
|
||||
"search.exclude": {
|
||||
"foundry": true
|
||||
},
|
||||
"html.customData": [
|
||||
"./.vscode/foundry.html-data.json"
|
||||
],
|
||||
"workbench.editorAssociations": {
|
||||
"*.svg": "default",
|
||||
},
|
||||
"git.branchProtection": []
|
||||
}
|
||||
92
eslint.config.mjs
Normal file
92
eslint.config.mjs
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
import globals from "globals";
|
||||
import pluginJs from "@eslint/js";
|
||||
import stylistic from "@stylistic/eslint-plugin";
|
||||
|
||||
export default [
|
||||
// Tell eslint to ignore files that I don't mind being formatted slightly differently
|
||||
{ ignores: [ `scripts/`, `foundry/` ] },
|
||||
{
|
||||
languageOptions: {
|
||||
globals: globals.browser,
|
||||
},
|
||||
},
|
||||
pluginJs.configs.recommended,
|
||||
// MARK: Foundry Globals
|
||||
{
|
||||
languageOptions: {
|
||||
globals: {
|
||||
CONFIG: `writable`,
|
||||
CONST: `readonly`,
|
||||
game: `readonly`,
|
||||
Handlebars: `readonly`,
|
||||
Hooks: `readonly`,
|
||||
ui: `readonly`,
|
||||
Actor: `readonly`,
|
||||
Item: `readonly`,
|
||||
foundry: `readonly`,
|
||||
ChatMessage: `readonly`,
|
||||
ActiveEffect: `readonly`,
|
||||
Dialog: `readonly`,
|
||||
renderTemplate: `readonly`,
|
||||
TextEditor: `readonly`,
|
||||
fromUuid: `readonly`,
|
||||
Combat: `readonly`,
|
||||
Combatant: `readonly`,
|
||||
canvas: `readonly`,
|
||||
Token: `readonly`,
|
||||
Tour: `readonly`,
|
||||
},
|
||||
},
|
||||
},
|
||||
// MARK: Project Specific
|
||||
{
|
||||
plugins: {
|
||||
"@stylistic": stylistic,
|
||||
},
|
||||
languageOptions: {
|
||||
globals: {},
|
||||
},
|
||||
rules: {
|
||||
"curly": `error`,
|
||||
"func-names": [`warn`, `as-needed`],
|
||||
"grouped-accessor-pairs": `error`,
|
||||
"no-alert": `error`,
|
||||
"no-empty": [`error`, { allowEmptyCatch: true }],
|
||||
"no-implied-eval": `error`,
|
||||
"no-invalid-this": `error`,
|
||||
"no-lonely-if": `error`,
|
||||
"no-unneeded-ternary": `error`,
|
||||
"no-nested-ternary": `error`,
|
||||
"no-var": `error`,
|
||||
"no-unused-vars": [
|
||||
`error`,
|
||||
{
|
||||
"vars": `local`,
|
||||
"args": `after-used`,
|
||||
"varsIgnorePattern": `^_`,
|
||||
"argsIgnorePattern": `^_`,
|
||||
},
|
||||
],
|
||||
"sort-imports": [`warn`, { "ignoreCase": true, "allowSeparatedGroups": true }],
|
||||
"@stylistic/semi": [`warn`, `always`, { "omitLastInOneLineBlock": true }],
|
||||
"@stylistic/no-trailing-spaces": `warn`,
|
||||
"@stylistic/space-before-blocks": [`warn`, `always`],
|
||||
"@stylistic/space-infix-ops": `warn`,
|
||||
"@stylistic/eol-last": `warn`,
|
||||
"@stylistic/operator-linebreak": [`warn`, `before`],
|
||||
"@stylistic/indent": [`warn`, `tab`],
|
||||
"@stylistic/brace-style": [`warn`, `stroustrup`, { "allowSingleLine": true }],
|
||||
"@stylistic/quotes": [`warn`, `backtick`, { "avoidEscape": true }],
|
||||
"@stylistic/comma-dangle": [`warn`, { arrays: `always-multiline`, objects: `always-multiline`, imports: `always-multiline`, exports: `always-multiline`, functions: `always-multiline` }],
|
||||
"@stylistic/comma-style": [`warn`, `last`],
|
||||
"@stylistic/dot-location": [`error`, `property`],
|
||||
"@stylistic/no-confusing-arrow": `error`,
|
||||
"@stylistic/no-whitespace-before-property": `error`,
|
||||
"@stylistic/nonblock-statement-body-position": [
|
||||
`error`,
|
||||
`beside`,
|
||||
{ "overrides": { "while": `below` } },
|
||||
],
|
||||
},
|
||||
},
|
||||
];
|
||||
3
langs/en-ca.json
Normal file
3
langs/en-ca.json
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"OFT": {}
|
||||
}
|
||||
39
module.json
Normal file
39
module.json
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
{
|
||||
"id": "oft",
|
||||
"title": "Oliver's Foundry Tweaks",
|
||||
"version": "0.0.0",
|
||||
"authors": [
|
||||
{ "name": "Oliver" }
|
||||
],
|
||||
"download": "",
|
||||
"manifest": "",
|
||||
"url": "",
|
||||
"compatibility": {
|
||||
"minimum": 13,
|
||||
"verified": 13,
|
||||
"maximum": 13
|
||||
},
|
||||
"esmodules": [
|
||||
"module/oft.mjs"
|
||||
],
|
||||
"styles": [
|
||||
{
|
||||
"src": "styles/main.css",
|
||||
"layer": "modules.oft"
|
||||
}
|
||||
],
|
||||
"languages": [
|
||||
{
|
||||
"lang": "en",
|
||||
"name": "English (Canadian)",
|
||||
"path": "langs/en-ca.json"
|
||||
}
|
||||
],
|
||||
"flags": {
|
||||
"inDev": true,
|
||||
"hotReload": {
|
||||
"extensions": ["css", "hbs", "mjs", "svg", "json"],
|
||||
"paths": ["module", "langs", "styles", "assets"]
|
||||
}
|
||||
}
|
||||
}
|
||||
5
module/consts.mjs
Normal file
5
module/consts.mjs
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
export const __ID = `otf`;
|
||||
|
||||
export function inDev() {
|
||||
return game.modules.get(__ID).flags.inDev;
|
||||
};
|
||||
5
module/hooks/ready.mjs
Normal file
5
module/hooks/ready.mjs
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
import { __ID } from "../consts.mjs";
|
||||
|
||||
Hooks.on(`ready`, () => {
|
||||
console.log(`${__ID} | Ready`);
|
||||
});
|
||||
2
module/oft.mjs
Normal file
2
module/oft.mjs
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
// Hooks
|
||||
import "./hooks/ready.mjs";
|
||||
15
package.json
Normal file
15
package.json
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.8.0",
|
||||
"@foundryvtt/foundryvtt-cli": "^1.0.3",
|
||||
"@stylistic/eslint-plugin": "^2.6.1",
|
||||
"dotenv": "^17.2.2",
|
||||
"eslint": "^9.8.0",
|
||||
"globals": "^15.9.0"
|
||||
},
|
||||
"scripts": {
|
||||
"link": "node scripts/linkFoundry.mjs",
|
||||
"lint": "eslint --fix",
|
||||
"lint:nofix": "eslint"
|
||||
}
|
||||
}
|
||||
1500
pnpm-lock.yaml
generated
Normal file
1500
pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load diff
47
scripts/linkFoundry.mjs
Normal file
47
scripts/linkFoundry.mjs
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
import { existsSync } from "fs";
|
||||
import { symlink, unlink } from "fs/promises";
|
||||
import { join } from "path";
|
||||
import { config } from "dotenv";
|
||||
|
||||
config({ quiet: true });
|
||||
|
||||
const root = process.env.FOUNDRY_ROOT;
|
||||
|
||||
// Early exit
|
||||
if (!root) {
|
||||
console.error(`Must provide a FOUNDRY_ROOT environment variable`);
|
||||
process.exit(1);
|
||||
};
|
||||
|
||||
// Assert Foundry exists
|
||||
if (!existsSync(root)) {
|
||||
console.error(`Foundry root not found.`);
|
||||
process.exit(1);
|
||||
};
|
||||
|
||||
// Removing existing symlink
|
||||
if (existsSync(`foundry`)) {
|
||||
console.log(`Attempting to unlink foundry instance`);
|
||||
try {
|
||||
await unlink(`foundry`);
|
||||
} catch {
|
||||
console.error(`Failed to unlink foundry folder.`);
|
||||
process.exit(1);
|
||||
};
|
||||
};
|
||||
|
||||
// Account for if the root is pointing at an Electron install
|
||||
let targetRoot = root;
|
||||
if (existsSync(join(root, `resources`, `app`))) {
|
||||
console.log(`Switching to use the "${root}/resources/app" directory`);
|
||||
targetRoot = join(root, `resources`, `app`);
|
||||
};
|
||||
|
||||
// Create symlink
|
||||
console.log(`Linking foundry source into folder`);
|
||||
try {
|
||||
await symlink(targetRoot, `foundry`);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
process.exit(1);
|
||||
};
|
||||
35
scripts/prepareManifest.mjs
Normal file
35
scripts/prepareManifest.mjs
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
The intent of this script is to do all of the modifications of the manifest file
|
||||
that we need to do in order to release the package. This can include removing
|
||||
dev-only fields/attributes that end users will never, and should never, care
|
||||
about nor need.
|
||||
*/
|
||||
import { readFile, writeFile } from "fs/promises";
|
||||
|
||||
const MANIFEST_PATH = `module.json`;
|
||||
|
||||
let manifest;
|
||||
try {
|
||||
manifest = JSON.parse(await readFile(MANIFEST_PATH, `utf-8`));
|
||||
} catch {
|
||||
console.error(`Failed to parse manifest file.`);
|
||||
process.exit(1);
|
||||
};
|
||||
|
||||
|
||||
// Filter out dev-only resources
|
||||
if (manifest.esmodules) {
|
||||
manifest.esmodules = manifest.esmodules.filter(
|
||||
filepath => !filepath.startsWith(`dev/`)
|
||||
);
|
||||
};
|
||||
|
||||
// Remove dev flags
|
||||
delete manifest.flags?.hotReload;
|
||||
delete manifest.flags?.inDev;
|
||||
|
||||
if (Object.keys(manifest.flags).length === 0) {
|
||||
delete manifest.flags;
|
||||
};
|
||||
|
||||
await writeFile(MANIFEST_PATH, JSON.stringify(manifest, undefined, `\t`));
|
||||
0
styles/main.css
Normal file
0
styles/main.css
Normal file
Loading…
Add table
Add a link
Reference in a new issue