Compare commits

...

40 commits
v2.4.0 ... main

Author SHA1 Message Date
c92a88f03f Add the manifest into the release during the action 2026-01-21 16:33:13 -07:00
97f6fc5844 Update version to 2.5.0 2026-01-21 16:17:09 -07:00
a3baa53bdd Merge pull request 'Localize everything that isn't already localized' (#27) from feature/localizations into main
Reviewed-on: #27
2026-01-21 23:15:41 +00:00
f65bc37dd3 Merge pull request 'Allow the Combat tracker to roll intiative using a custom formula' (#24) from feature/combat-tracker-initiative-roll into main
Reviewed-on: #24
2026-01-21 23:12:21 +00:00
9830c10b6f Make the query events use the proper import for DialogManager utils 2026-01-21 16:07:02 -07:00
1f9aee329e Localize the rest of the TAFDocumentSheetConfig 2026-01-21 16:00:26 -07:00
235f8aef39 Fully localize the PlayerSheet 2026-01-21 15:44:33 -07:00
3819db1ce4 Fully localize the Attribute Manager app 2026-01-21 15:39:23 -07:00
9f6c117c84 Fully localize the Ask app where possible 2026-01-21 15:27:12 -07:00
357af820bf Update scripts pointer 2026-01-21 15:17:55 -07:00
116eb216d0 Allow the Combat tracker to roll intiative using a custom formula 2026-01-20 23:16:45 -07:00
deedda7648 Upload the wiki upload to work with the generic asset upload script 2026-01-16 17:22:03 -07:00
fe7fb028bd Add move archive step 2026-01-16 17:13:07 -07:00
c9d8a81153 Remove duplicated list 2026-01-16 16:45:17 -07:00
0f627fee53 Add final upload step back in 2026-01-16 16:43:54 -07:00
bab175eb24 Add wiki clean/zip steps back in 2026-01-15 22:43:58 -07:00
0a35000118 Add dependency installation step back in 2026-01-15 22:42:04 -07:00
47c6bba8cb Add debug command 2026-01-15 22:40:35 -07:00
1ae598f06f Comment out most of the action for debugging purposes 2026-01-15 22:39:15 -07:00
bc5e21680e Update CD pipeline 2026-01-15 22:28:10 -07:00
6bff0bd5ac Update wiki release zipping 2026-01-15 22:24:02 -07:00
2adce05703 Update CD workflow 2026-01-15 22:16:51 -07:00
26432693e8 Use the correct ref 2026-01-15 22:07:48 -07:00
241a97eb78 Update scripts reference 2026-01-15 21:55:49 -07:00
c61d42f23e Update scripts reference 2026-01-15 21:36:26 -07:00
4c2e0e4175 Update scripts reference 2026-01-15 21:34:32 -07:00
f1834f83dc Update scripts and CD in order to include the wiki artifact in the release 2026-01-15 21:31:11 -07:00
2bbc7cdc42 Remove commented out S3 steps 2026-01-13 23:29:20 -07:00
6a3b81ec0d Add manifest env variable to all steps 2026-01-13 23:22:08 -07:00
738d579a81 Update scripts reference 2026-01-13 23:13:23 -07:00
1aaf148ce4 Make sure the checkout action pulls the submodules as well 2026-01-13 23:11:21 -07:00
5c3240ed8d Update scripts reference 2026-01-13 23:08:06 -07:00
4681e908f7 Update the version number 2026-01-13 23:01:14 -07:00
6373d92fea Update the release process to use the new scripts 2026-01-13 22:59:40 -07:00
401edf05c0 Update scripts reference 2026-01-13 22:59:12 -07:00
f0cf155ae8 Update the scripts reference 2026-01-13 22:50:13 -07:00
1b26cacc4d Update the manifest template 2026-01-13 17:46:56 -07:00
e26baae865 Update the ref for the scripts 2026-01-13 17:46:42 -07:00
3b2d886f58 Move the scripts into a submodule repo 2026-01-13 17:27:29 -07:00
23fe6d10f5 Remove scripts in favour of submodule 2026-01-13 17:07:15 -07:00
31 changed files with 279 additions and 2413 deletions

View file

@ -1,2 +1,5 @@
# The absolute path to the Foundry installation to create symlinks to # The absolute path to the Foundry installation to create symlinks to
FOUNDRY_ROOT="" FOUNDRY_ROOT=""
# The manifest file for the module/system
MANIFEST="./system.json"

View file

@ -1,11 +1,17 @@
on: [ workflow_dispatch ] on: [ workflow_dispatch ]
env:
MANIFEST: "system.json"
jobs: jobs:
create-artifacts: create-draft-release:
name: "Create artifacts" name: "Create Draft Release"
runs-on: act runs-on: act
outputs:
version: ${{steps.version.outputs.version}}
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v4 uses: actions/checkout@v4
with:
submodules: true
- name: Install dependencies - name: Install dependencies
run: npm clean-install run: npm clean-install
@ -14,7 +20,7 @@ jobs:
run: cat system.json | echo version=`jq -r ".version"` >> "$FORGEJO_OUTPUT" run: cat system.json | echo version=`jq -r ".version"` >> "$FORGEJO_OUTPUT"
- name: Assert that the tag doesn't exist - name: Assert that the tag doesn't exist
run: node scripts/tagExists.mjs run: node scripts/src/tagExists.mjs
env: env:
TAG_NAME: "v${{steps.version.outputs.version}}" TAG_NAME: "v${{steps.version.outputs.version}}"
@ -24,73 +30,53 @@ jobs:
- name: Remove compendia source - name: Remove compendia source
run: "rm -rf packs/**/_source" run: "rm -rf packs/**/_source"
- name: Compress files
run: zip -r release.zip langs module styles templates README.md assets LICENSE
- name: Upload artifacts
uses: https://data.forgejo.org/forgejo/upload-artifact@v4
with:
path: |
system.json
release.zip
scripts/*.mjs
package-lock.json
package.json
retention-days: 7
if-no-files-found: error
forgejo-release:
name: "Create Forgejo release"
runs-on: act
needs:
- create-artifacts
if: vars.RELEASE_TO_FORGEJO == 'yes'
steps:
- name: Download artifacts
uses: https://data.forgejo.org/forgejo/download-artifact@v4
with:
merge-multiple: true
- name: Install dependencies
run: npm i
- id: version
run: cat system.json | echo version=`jq -r ".version"` >> "$FORGEJO_OUTPUT"
- name: Update manifest - name: Update manifest
run: node scripts/prepareManifest.mjs run: node scripts/src/prepareManifest.mjs
env: env:
DOWNLOAD_URL: "${{forgejo.server_url}}/${{forgejo.repository}}/releases/download/v${{steps.version.outputs.version}}/release.zip" DOWNLOAD_URL: "${{forgejo.server_url}}/${{forgejo.repository}}/releases/download/v${{steps.version.outputs.version}}/release.zip"
LATEST_URL: "${{forgejo.server_url}}/${{forgejo.repository}}/releases/download/latest/system.json" LATEST_URL: "${{forgejo.server_url}}/${{forgejo.repository}}/releases/download/latest/system.json"
- name: Add manifest into release archive - name: Compress files
run: zip release.zip --update system.json run: zip -r release.zip langs module styles templates README.md assets LICENSE ${{env.MANIFEST}}
- name: Upload archive to s3 - name: Create forgejo release
run: node scripts/uploadToS3.mjs run: node scripts/src/createForgejoRelease.mjs
env:
TAG: "v${{steps.version.outputs.version}}"
FILE: "release.zip"
S3_BUCKET: "${{vars.S3_BUCKET}}"
S3_REGION: "${{vars.S3_REGION}}"
S3_KEY: "${{secrets.S3_KEY}}"
S3_SECRET: "${{secrets.S3_SECRET}}"
S3_ENDPOINT: "${{vars.S3_ENDPOINT}}"
- name: Upload manifest to s3
run: node scripts/uploadToS3.mjs
env:
TAG: "v${{steps.version.outputs.version}}"
FILE: "system.json"
S3_BUCKET: "${{vars.S3_BUCKET}}"
S3_REGION: "${{vars.S3_REGION}}"
S3_KEY: "${{secrets.S3_KEY}}"
S3_SECRET: "${{secrets.S3_SECRET}}"
S3_ENDPOINT: "${{vars.S3_ENDPOINT}}"
- name: Create draft release
run: node scripts/createForgejoRelease.mjs
env: env:
TAG: "v${{steps.version.outputs.version}}" TAG: "v${{steps.version.outputs.version}}"
CDN_URL: "${{vars.CDN_URL}}" CDN_URL: "${{vars.CDN_URL}}"
wiki-release-artifact:
name: "Add Wiki to Release"
runs-on: act
needs:
- create-draft-release
steps:
- name: Checkout main code
uses: actions/checkout@v4
with:
submodules: true
- name: "Clone wiki repo"
uses: actions/checkout@v4
with:
repository: "${{forgejo.repository}}.wiki"
ref: "main"
path: "wiki"
token: ${{forgejo.token}}
- name: "Install dependencies"
run: "pwd; npm i"
- name: "Remove development folders"
run: "rm -rf .git .vscode"
working-directory: "wiki"
- name: "Compress wiki folder"
run: "zip -r wiki.zip ."
working-directory: "wiki"
- name: "Upload wiki archive"
run: "node scripts/src/uploadReleaseAsset.mjs"
env:
ASSET: "wiki/wiki.zip"
TAG: "v${{needs.create-draft-release.outputs.version}}"

3
.gitmodules vendored Normal file
View file

@ -0,0 +1,3 @@
[submodule "scripts"]
path = scripts
url = https://git.varify.ca/Foundry/scripts.git

View file

@ -10,6 +10,10 @@
"name": "Players Can Manage Attributes", "name": "Players Can Manage Attributes",
"hint": "This allows players who have edit access to a document to be able to edit what attributes those characters have via the attribute editor" "hint": "This allows players who have edit access to a document to be able to edit what attributes those characters have via the attribute editor"
}, },
"initiativeFormula": {
"name": "Initiative Formula",
"hint": "The dice formula used for initiative, this can reference attributes on the actor. If the actor doesn't have the attribute it will be interpreted as 0."
},
"sheetDefaultHeight": { "sheetDefaultHeight": {
"name": "Default Actor Sheet Height", "name": "Default Actor Sheet Height",
"hint": "The height that all actor sheets will open at unless overwridden for that sheet specifically. This setting will not affect already opened sheets." "hint": "The height that all actor sheets will open at unless overwridden for that sheet specifically. This setting will not affect already opened sheets."
@ -36,9 +40,31 @@
"Key": "Key", "Key": "Key",
"Value": "Value", "Value": "Value",
"no-data-submitted": "No data submitted", "no-data-submitted": "No data submitted",
"data-query-notif-header": "Data Query Notification" "data-query-notif-header": "Data Query Notification",
"cancel": "Cancel",
"confirm-and-close": "Confirm and Close",
"save-and-close": "Save and Close",
"delete": "Delete",
"resizable": "Resizable",
"not-resizable": "Not Resizable"
}, },
"Apps": { "Apps": {
"Ask": {
"title": "Questions",
"invalid-input-type": "Invalid input type provided: {type}"
},
"AttributeManager": {
"title": "Attributes: {name}",
"has-max": "Has Maximum?",
"name-placeholder": "Attribute Name...",
"no-attributes": "No attributes yet",
"add-new-attribute": "Add New Attribute"
},
"PlayerSheet": {
"manage-attributes": "Manage Attributes",
"current-value": "Current value",
"max-value": "Maximum value"
},
"QueryStatus": { "QueryStatus": {
"title": "Information Request Status", "title": "Information Request Status",
"user-disconnected-tooltip": "This user is not logged in to Foundry", "user-disconnected-tooltip": "This user is not logged in to Foundry",
@ -55,7 +81,8 @@
"label": "Height" "label": "Height"
}, },
"Resizable": { "Resizable": {
"label": "Resizable" "label": "Resizable",
"placeholder": "Default ({placeholder})"
}, },
"tabs": { "tabs": {
"foundry": "Foundry", "foundry": "Foundry",

View file

@ -1,4 +1,5 @@
import { __ID__, filePath } from "../consts.mjs"; import { __ID__, filePath } from "../consts.mjs";
import { localizer } from "../utils/localizer.mjs";
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api; const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
@ -24,7 +25,7 @@ export class Ask extends HandlebarsApplicationMixin(ApplicationV2) {
width: 330, width: 330,
}, },
window: { window: {
title: `Questions`, title: `taf.Apps.Ask.title`,
resizable: true, resizable: true,
minimizable: true, minimizable: true,
contentTag: `form`, contentTag: `form`,
@ -80,7 +81,10 @@ export class Ask extends HandlebarsApplicationMixin(ApplicationV2) {
for (const input of inputs) { for (const input of inputs) {
if (!validInputTypes.includes(input.type)) { if (!validInputTypes.includes(input.type)) {
input.details = `Invalid input type provided: ${input.type}`; input.details = localizer(
`taf.Apps.Ask.invalid-input-type`,
{ type: input.type },
);
input.type = `error`; input.type = `error`;
}; };
}; };

View file

@ -1,5 +1,6 @@
import { __ID__, filePath } from "../consts.mjs"; import { __ID__, filePath } from "../consts.mjs";
import { attributeSorter } from "../utils/attributeSort.mjs"; import { attributeSorter } from "../utils/attributeSort.mjs";
import { localizer } from "../utils/localizer.mjs";
import { toID } from "../utils/toID.mjs"; import { toID } from "../utils/toID.mjs";
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api; const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
@ -52,7 +53,10 @@ export class AttributeManager extends HandlebarsApplicationMixin(ApplicationV2)
}; };
get title() { get title() {
return `Attributes: ${this.#doc.name}`; return localizer(
`taf.Apps.AttributeManager.title`,
this.#doc,
);
}; };
// #endregion Instance Data // #endregion Instance Data
@ -102,7 +106,6 @@ export class AttributeManager extends HandlebarsApplicationMixin(ApplicationV2)
attrs.push({ attrs.push({
id, id,
name: data.name, name: data.name,
displayName: data.isNew ? `New Attribute` : data.name,
sort: data.sort, sort: data.sort,
isRange: data.isRange, isRange: data.isRange,
isNew: data.isNew ?? false, isNew: data.isNew ?? false,

View file

@ -82,7 +82,7 @@ export class PlayerSheet extends HandlebarsApplicationMixin(ActorSheetV2) {
controls.push({ controls.push({
icon: `fa-solid fa-at`, icon: `fa-solid fa-at`,
label: `Manage Attributes`, label: `taf.Apps.PlayerSheet.manage-attributes`,
action: `manageAttributes`, action: `manageAttributes`,
visible: () => { visible: () => {
const isGM = game.user.isGM; const isGM = game.user.isGM;
@ -167,7 +167,6 @@ export class PlayerSheet extends HandlebarsApplicationMixin(ActorSheetV2) {
event.stopPropagation(); event.stopPropagation();
if ( event.detail > 1 ) { return } if ( event.detail > 1 ) { return }
// const docSheetConfigWidth = TAFDocumentSheetConfig.DEFAULT_OPTIONS.position.width;
new TAFDocumentSheetConfig({ new TAFDocumentSheetConfig({
document: this.document, document: this.document,
position: { position: {

View file

@ -1,5 +1,6 @@
import { __ID__, filePath } from "../consts.mjs"; import { __ID__, filePath } from "../consts.mjs";
import { getDefaultSizing } from "../utils/getSizing.mjs"; import { getDefaultSizing } from "../utils/getSizing.mjs";
import { localizer } from "../utils/localizer.mjs";
const { diffObject, expandObject, flattenObject } = foundry.utils; const { diffObject, expandObject, flattenObject } = foundry.utils;
const { DocumentSheetConfig } = foundry.applications.apps; const { DocumentSheetConfig } = foundry.applications.apps;
@ -74,7 +75,9 @@ export class TAFDocumentSheetConfig extends DocumentSheetConfig {
const defaults = getDefaultSizing(); const defaults = getDefaultSizing();
context.placeholders = { context.placeholders = {
...defaults, ...defaults,
resizable: defaults.resizable ? `Resizable` : `Not Resizable`, resizable: defaults.resizable
? localizer(`taf.misc.resizable`)
: localizer(`taf.misc.not-resizable`),
}; };
// Custom values from document itself // Custom values from document itself
@ -88,9 +91,15 @@ export class TAFDocumentSheetConfig extends DocumentSheetConfig {
// Static prep // Static prep
context.resizeOptions = [ context.resizeOptions = [
{ label: `Default (${context.placeholders.resizable})`, value: `` }, {
{ label: `Resizable`, value: `true` }, label: localizer(
{ label: `No Resizing`, value: `false` }, `taf.Apps.TAFDocumentSheetConfig.Resizable.placeholder`,
{ placeholder: context.placeholders.resizable },
),
value: ``,
},
{ label: localizer(`taf.misc.resizable`), value: `true` },
{ label: localizer(`taf.misc.not-resizable`), value: `false` },
]; ];
}; };
// #endregion Data Prep // #endregion Data Prep

View file

@ -0,0 +1,9 @@
import { __ID__ } from "../consts.mjs";
const { Combatant } = foundry.documents;
export class TAFCombatant extends Combatant {
_getInitiativeFormula() {
return game.settings.get(__ID__, `initiativeFormula`);
};
};

View file

@ -7,6 +7,7 @@ import { PlayerData } from "../data/Player.mjs";
// Documents // Documents
import { TAFActor } from "../documents/Actor.mjs"; import { TAFActor } from "../documents/Actor.mjs";
import { TAFCombatant } from "../documents/Combatant.mjs";
import { TAFItem } from "../documents/Item.mjs"; import { TAFItem } from "../documents/Item.mjs";
import { TAFTokenDocument } from "../documents/Token.mjs"; import { TAFTokenDocument } from "../documents/Token.mjs";
@ -25,6 +26,7 @@ Hooks.on(`init`, () => {
CONFIG.Token.documentClass = TAFTokenDocument; CONFIG.Token.documentClass = TAFTokenDocument;
CONFIG.Actor.documentClass = TAFActor; CONFIG.Actor.documentClass = TAFActor;
CONFIG.Combatant.documentClass = TAFCombatant;
CONFIG.Actor.dataModels.player = PlayerData; CONFIG.Actor.dataModels.player = PlayerData;

View file

@ -3,6 +3,16 @@ import { __ID__ } from "../consts.mjs";
const { NumberField, StringField } = foundry.data.fields; const { NumberField, StringField } = foundry.data.fields;
export function registerWorldSettings() { export function registerWorldSettings() {
game.settings.register(__ID__, `initiativeFormula`, {
name: `taf.settings.initiativeFormula.name`,
hint: `taf.settings.initiativeFormula.hint`,
config: true,
type: String,
default: `1d20`,
scope: `world`,
});
game.settings.register(__ID__, `canPlayersManageAttributes`, { game.settings.register(__ID__, `canPlayersManageAttributes`, {
name: `taf.settings.canPlayersManageAttributes.name`, name: `taf.settings.canPlayersManageAttributes.name`,
hint: `taf.settings.canPlayersManageAttributes.hint`, hint: `taf.settings.canPlayersManageAttributes.hint`,

View file

@ -1,4 +1,4 @@
import { DialogManager } from "../../utils/DialogManager.mjs"; import { close } from "../../utils/DialogManager.mjs";
import { localizer } from "../../utils/localizer.mjs"; import { localizer } from "../../utils/localizer.mjs";
export async function queryCancel(payload) { export async function queryCancel(payload) {
@ -15,5 +15,5 @@ export async function queryCancel(payload) {
return; return;
}; };
await DialogManager.close(id); close(id);
}; };

View file

@ -1,4 +1,4 @@
import { DialogManager } from "../../utils/DialogManager.mjs"; import { ask } from "../../utils/DialogManager.mjs";
import { localizer } from "../../utils/localizer.mjs"; import { localizer } from "../../utils/localizer.mjs";
import { respondedToQueries } from "../../utils/QueryManager.mjs"; import { respondedToQueries } from "../../utils/QueryManager.mjs";
@ -36,7 +36,7 @@ export async function queryPrompt(payload) {
if (users != null && !users.includes(game.user.id)) { return }; if (users != null && !users.includes(game.user.id)) { return };
request.id = id; request.id = id;
const result = await DialogManager.ask(request, config); const result = await ask(request, config);
if (result.state === `fronted`) { if (result.state === `fronted`) {
return; return;
} else if (result.state === `errored`) { } else if (result.state === `errored`) {

2119
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -1,18 +1,16 @@
{ {
"devDependencies": { "devDependencies": {
"@aws-sdk/client-s3": "^3.934.0",
"@eslint/js": "^9.8.0", "@eslint/js": "^9.8.0",
"@foundryvtt/foundryvtt-cli": "^1.0.3", "@foundryvtt/foundryvtt-cli": "^1.0.3",
"@stylistic/eslint-plugin": "^2.6.1", "@stylistic/eslint-plugin": "^2.6.1",
"axios": "^1.13.2",
"dotenv": "^17.2.2",
"eslint": "^9.8.0", "eslint": "^9.8.0",
"globals": "^15.9.0" "globals": "^15.9.0",
"scripts": "file:./scripts"
}, },
"scripts": { "scripts": {
"data:build": "node scripts/buildCompendia.mjs", "data:build": "node scripts/src/buildCompendia.mjs",
"data:extract": "node scripts/extractCompendia.mjs", "data:extract": "node scripts/src/extractCompendia.mjs",
"link": "node scripts/linkFoundry.mjs", "link": "node scripts/src/linkFoundry.mjs",
"lint": "eslint --fix", "lint": "eslint --fix",
"lint:nofix": "eslint" "lint:nofix": "eslint"
} }

1
scripts Submodule

@ -0,0 +1 @@
Subproject commit 06fb33b35ff446dee613afe271b6fe2ff976735a

View file

@ -1,32 +0,0 @@
import { compilePack } from "@foundryvtt/foundryvtt-cli";
import { existsSync } from "fs";
import { join } from "path";
import { readFile } from "fs/promises";
async function main() {
const system = JSON.parse(await readFile(`./system.json`, `utf-8`));
if (!system.packs || system.packs.length === 0) {
console.log(`No compendium packs defined`);
process.exit(0);
};
for (const compendium of system.packs) {
console.debug(`Packing ${compendium.label} (${compendium.name})`);
let src = join(process.cwd(), compendium.path, `_source`);
if (!existsSync(src)) {
console.warn(`${compendium.path} doesn't exist, skipping.`)
continue;
};
await compilePack(
src,
join(process.cwd(), compendium.path),
{ recursive: true },
);
console.debug(`Finished packing ${compendium.name}`);
};
console.log(`Finished packing compendia`)
};
main();

View file

@ -1,55 +0,0 @@
import axios from "axios";
const {
TAG,
FORGEJO_SERVER_URL: WEB_URL,
FORGEJO_API_URL: API,
FORGEJO_REPOSITORY: REPO,
FORGEJO_TOKEN: TOKEN,
CDN_URL,
} = process.env;
async function addReleaseAsset(releaseID, name) {
return axios.post(
`${API}/repos/${REPO}/releases/${releaseID}/assets`,
{ external_url: `${CDN_URL}/${REPO}/${TAG}/${name}`, },
{
headers: {
Authorization: `token ${TOKEN}`,
"Content-Type": `multipart/form-data`,
},
params: { name },
}
);
};
async function main() {
// Initial Release Data
const release = await axios.post(
`${API}/repos/${REPO}/releases`,
{
name: TAG,
tag_name: TAG,
draft: true,
hide_archive_links: true,
target_commitish: `main`,
body: `<!-- Manifest URL: ${WEB_URL}/${REPO}/releases/download/${TAG}/system.json -->`,
},
{
headers: { Authorization: `token ${TOKEN}` },
}
);
try {
await addReleaseAsset(release.data.id, `release.zip`);
await addReleaseAsset(release.data.id, `system.json`);
} catch (e) {
console.error(`Failed to add assets to the release`);
process.exit(1);
};
console.log(`Release created`);
};
main();

View file

@ -1,27 +0,0 @@
import { readFile } from "fs/promises";
import { join } from "path";
import { extractPack } from "@foundryvtt/foundryvtt-cli";
async function main() {
const system = JSON.parse(await readFile(`./system.json`, `utf-8`));
if (!system.packs || system.packs.length === 0) {
console.log(`No compendium packs defined`);
process.exit(0);
};
for (const compendium of system.packs) {
console.debug(`Unpacking ${compendium.label} (${compendium.name})`);
let src = join(process.cwd(), compendium.path, `_source`);
await extractPack(
join(process.cwd(), compendium.path),
src,
{ recursive: true },
);
console.debug(`Finished packing ${compendium.name}`);
};
console.log(`Finished unpacking compendia`);
};
main();

View file

@ -1,47 +0,0 @@
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);
};

View file

@ -1,4 +0,0 @@
const invalids = game.actors.invalidDocumentIds;
invalids.forEach(id => {
game.actors.getInvalid(id).delete();
});

View file

@ -1,4 +0,0 @@
const invalids = game.items.invalidDocumentIds;
invalids.forEach(id => {
game.items.getInvalid(id).delete();
});

View file

@ -1,45 +0,0 @@
/*
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 system.
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 = `system.json`;
const {
DOWNLOAD_URL,
LATEST_URL,
} = process.env;
let manifest;
try {
manifest = JSON.parse(await readFile(MANIFEST_PATH, `utf-8`));
console.log(`Manifest loaded from disk`);
} catch {
console.error(`Failed to parse manifest file.`);
process.exit(1);
};
console.log(`Updating download/manifest URLs`)
manifest.download = DOWNLOAD_URL;
manifest.manifest = LATEST_URL;
// Filter out dev-only resources
if (manifest.esmodules) {
console.log(`Removing dev-only esmodules`);
manifest.esmodules = manifest.esmodules.filter(
filepath => !filepath.startsWith(`dev/`)
);
};
// Remove dev flags
console.log(`Cleaning up flags`);
delete manifest.flags?.hotReload;
if (Object.keys(manifest.flags).length === 0) {
delete manifest.flags;
};
await writeFile(MANIFEST_PATH, JSON.stringify(manifest, undefined, `\t`));
console.log(`Manifest written back to disk`);

View file

@ -1,38 +0,0 @@
import axios from "axios";
const {
TAG_NAME,
FORGEJO_API_URL: API_URL,
FORGEJO_REPOSITORY: REPO,
FORGEJO_TOKEN: TOKEN,
} = process.env;
async function main() {
if (!TAG_NAME) {
console.log(`Tag name must not be blank`);
process.exit(1);
};
const requestURL = `${API_URL}/repos/${REPO}/tags/${TAG_NAME}`;
const response = await axios.get(
requestURL,
{
headers: { Authorization: `token ${TOKEN}` },
validateStatus: () => true,
},
);
// We actually *want* an error when the tag exists, instead of when
// it doesn't
if (response.status === 200) {
console.log(`Tag with name "${TAG_NAME}" already exists`);
process.exit(1);
};
console.log(`Tag with name "${TAG_NAME}" not found, proceeding`);
};
main();

View file

@ -1,65 +0,0 @@
import { PutObjectCommand, S3Client } from '@aws-sdk/client-s3';
import { createReadStream } from "fs";
const requiredEnvVariables = [
`TAG`, `FILE`,
`FORGEJO_REPOSITORY`,
`S3_BUCKET`, `S3_REGION`, `S3_KEY`, `S3_SECRET`, `S3_ENDPOINT`,
];
async function main() {
// Assert all of the required env variables are present
const missing = [];
for (const envVar of requiredEnvVariables) {
if (!(envVar in process.env)) {
missing.push(envVar);
};
};
if (missing.length > 0) {
console.error(`Missing the following required environment variables: ${missing.join(`, `)}`);
process.exit(1);
};
const {
TAG,
S3_ENDPOINT,
S3_REGION,
S3_KEY,
S3_SECRET,
S3_BUCKET,
FILE,
FORGEJO_REPOSITORY: REPO,
} = process.env;
const s3Client = new S3Client({
endpoint: S3_ENDPOINT,
forcePathStyle: false,
region: S3_REGION,
credentials: {
accessKeyId: S3_KEY,
secretAccessKey: S3_SECRET
},
});
const name = FILE.split(`/`).at(-1);
const params = {
Bucket: S3_BUCKET,
Key: `${REPO}/${TAG}/${name}`,
Body: createReadStream(FILE),
ACL: "public-read",
METADATA: {
"x-repo-version": TAG,
},
};
try {
const response = await s3Client.send(new PutObjectCommand(params));
console.log("Upload successful");
} catch (err) {
console.error("Upload to s3 failed");
};
};
main();

View file

@ -2,7 +2,7 @@
"id": "taf", "id": "taf",
"title": "Text-Based Actors", "title": "Text-Based Actors",
"description": "An intentionally minimalist system that enables you to play rules-light games without getting in your way!", "description": "An intentionally minimalist system that enables you to play rules-light games without getting in your way!",
"version": "2.4.0", "version": "2.5.0",
"download": "", "download": "",
"manifest": "", "manifest": "",
"url": "https://git.varify.ca/Foundry/taf", "url": "https://git.varify.ca/Foundry/taf",

View file

@ -3,11 +3,11 @@
type="button" type="button"
data-action="cancel" data-action="cancel"
> >
Cancel {{localize "taf.misc.cancel"}}
</button> </button>
<button <button
type="submit" type="submit"
> >
Confirm and Close {{localize "taf.misc.confirm-and-close"}}
</button> </button>
</div> </div>

View file

@ -15,13 +15,13 @@
type="text" type="text"
data-bind="{{ attr.id }}.name" data-bind="{{ attr.id }}.name"
value="{{ attr.name }}" value="{{ attr.name }}"
placeholder="Attribute Name..." placeholder="{{localize "taf.Apps.AttributeManager.name-placeholder"}}"
> >
{{else}} {{else}}
<span>{{ attr.name }}</span> <span>{{ attr.name }}</span>
{{/if}} {{/if}}
<label> <label>
Has Maximum? {{localize "taf.Apps.AttributeManager.has-max"}}
<input <input
type="checkbox" type="checkbox"
data-bind="{{ attr.id }}.isRange" data-bind="{{ attr.id }}.isRange"
@ -32,10 +32,12 @@
type="button" type="button"
data-action="removeAttribute" data-action="removeAttribute"
> >
Delete {{localize "taf.misc.delete"}}
</button> </button>
</div> </div>
{{else}} {{else}}
<p>No attributes yet</p> <p>
{{localize "taf.Apps.AttributeManager.no-attributes"}}
</p>
{{/each}} {{/each}}
</div> </div>

View file

@ -3,11 +3,11 @@
type="button" type="button"
data-action="addNew" data-action="addNew"
> >
Add New Attribute {{localize "taf.Apps.AttributeManager.add-new-attribute"}}
</button> </button>
<button <button
type="submit" type="submit"
> >
Save and Close {{localize "taf.misc.save-and-close"}}
</button> </button>
</div> </div>

View file

@ -11,7 +11,7 @@
class="attr-range__value" class="attr-range__value"
name="{{attr.path}}.value" name="{{attr.path}}.value"
value="{{attr.value}}" value="{{attr.value}}"
aria-label="Current value" aria-label="{{localize "taf.Apps.PlayerSheet.current-value"}}"
data-tooltip="@{{ attr.id }}{{#if attr.isRange}}.value{{/if}}" data-tooltip="@{{ attr.id }}{{#if attr.isRange}}.value{{/if}}"
> >
{{#if attr.isRange}} {{#if attr.isRange}}
@ -21,7 +21,7 @@
class="attr-range__max" class="attr-range__max"
name="{{attr.path}}.max" name="{{attr.path}}.max"
value="{{attr.max}}" value="{{attr.max}}"
aria-label="Maximum value" aria-label="{{localize "taf.Apps.PlayerSheet.max-value"}}"
data-tooltip="@{{ attr.id }}.max" data-tooltip="@{{ attr.id }}.max"
> >
{{/if}} {{/if}}

View file

@ -12,6 +12,6 @@
name="name" name="name"
class="large" class="large"
value="{{actor.name}}" value="{{actor.name}}"
placeholder="{{ localize 'Name' }}" placeholder="{{ localize "Name" }}"
/> />
</header> </header>