create-lt-adventure 0.1.0 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +85 -85
- package/addons/github-workflow/addon.json +5 -5
- package/addons/github-workflow/main.yml +96 -96
- package/addons/github-workflow/setup.mjs +115 -115
- package/addons/sf2e-pf2e-redirects/addon.json +5 -5
- package/addons/sf2e-pf2e-redirects/setup.mjs +119 -119
- package/dist/bin.js +19 -19
- package/package.json +68 -66
package/README.md
CHANGED
|
@@ -1,85 +1,85 @@
|
|
|
1
|
-
# create-lt-adventure
|
|
2
|
-
|
|
3
|
-
A CLI scaffolding tool for creating Foundry VTT modules.
|
|
4
|
-
|
|
5
|
-
## Installation
|
|
6
|
-
|
|
7
|
-
### Global Installation (for end users)
|
|
8
|
-
|
|
9
|
-
Once published to npm, you can run the script via Bun:
|
|
10
|
-
|
|
11
|
-
```bash
|
|
12
|
-
bunx create-lt-adventure
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
Updating the package:
|
|
16
|
-
|
|
17
|
-
```bash
|
|
18
|
-
create-lt-adventure
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
Update the package using
|
|
22
|
-
|
|
23
|
-
```bash
|
|
24
|
-
bun update create-lt-adventure -g --latest
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
### Development Installation
|
|
28
|
-
|
|
29
|
-
For development purposes:
|
|
30
|
-
|
|
31
|
-
```bash
|
|
32
|
-
git clone https://github.com/Loot-Foundry/create-lt-adventure
|
|
33
|
-
cd create-lt-adventure
|
|
34
|
-
bun install
|
|
35
|
-
bun run dev
|
|
36
|
-
```
|
|
37
|
-
### Development
|
|
38
|
-
|
|
39
|
-
```bash
|
|
40
|
-
# Install dependencies
|
|
41
|
-
bun install
|
|
42
|
-
|
|
43
|
-
# Run in development mode (requires Bun)
|
|
44
|
-
bun run dev
|
|
45
|
-
|
|
46
|
-
# Watch for TypeScript changes
|
|
47
|
-
bun run build:watch
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
## Scripts
|
|
51
|
-
|
|
52
|
-
- `bun run build` - Compile TypeScript to JavaScript
|
|
53
|
-
- `bun run build:watch` - Watch TypeScript files and rebuild on changes
|
|
54
|
-
- `bun run dev` - Run the CLI in development mode (requires Bun)
|
|
55
|
-
- `bun run prepublishOnly` - Automatically run before publishing
|
|
56
|
-
|
|
57
|
-
## System Support
|
|
58
|
-
|
|
59
|
-
Currently supports:
|
|
60
|
-
- **dnd5e** - Dungeons & Dragons 5th Edition
|
|
61
|
-
- **pf2e** - Pathfinder 2nd Edition
|
|
62
|
-
|
|
63
|
-
Additional systems can be added in `src/options.ts`.
|
|
64
|
-
|
|
65
|
-
## Resources
|
|
66
|
-
|
|
67
|
-
### Foundry VTT Documentation
|
|
68
|
-
- [dnd5e System Wiki](https://github.com/foundryvtt/dnd5e/wiki)
|
|
69
|
-
- [dnd5e Module Registration](https://github.com/foundryvtt/dnd5e/wiki/Module-Registration)
|
|
70
|
-
- [PF2e Wiki](https://github.com/foundryvtt/pf2e/wiki)
|
|
71
|
-
|
|
72
|
-
### Module Development
|
|
73
|
-
- [Foundry VTT Module Development](https://foundryvtt.com/article/modules/)
|
|
74
|
-
|
|
75
|
-
## License
|
|
76
|
-
|
|
77
|
-
MIT
|
|
78
|
-
|
|
79
|
-
## Contributing
|
|
80
|
-
|
|
81
|
-
Contributions are welcome! Please feel free to submit pull requests.
|
|
82
|
-
|
|
83
|
-
## Issues
|
|
84
|
-
|
|
85
|
-
Found a bug? Please open an issue on [GitHub](https://github.com/Loot-Foundry/create-lt-adventure/issues).
|
|
1
|
+
# create-lt-adventure
|
|
2
|
+
|
|
3
|
+
A CLI scaffolding tool for creating Foundry VTT modules.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
### Global Installation (for end users)
|
|
8
|
+
|
|
9
|
+
Once published to npm, you can run the script via Bun:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
bunx create-lt-adventure
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Updating the package:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
create-lt-adventure
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Update the package using
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
bun update create-lt-adventure -g --latest
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### Development Installation
|
|
28
|
+
|
|
29
|
+
For development purposes:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
git clone https://github.com/Loot-Foundry/create-lt-adventure
|
|
33
|
+
cd create-lt-adventure
|
|
34
|
+
bun install
|
|
35
|
+
bun run dev
|
|
36
|
+
```
|
|
37
|
+
### Development
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
# Install dependencies
|
|
41
|
+
bun install
|
|
42
|
+
|
|
43
|
+
# Run in development mode (requires Bun)
|
|
44
|
+
bun run dev
|
|
45
|
+
|
|
46
|
+
# Watch for TypeScript changes
|
|
47
|
+
bun run build:watch
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Scripts
|
|
51
|
+
|
|
52
|
+
- `bun run build` - Compile TypeScript to JavaScript
|
|
53
|
+
- `bun run build:watch` - Watch TypeScript files and rebuild on changes
|
|
54
|
+
- `bun run dev` - Run the CLI in development mode (requires Bun)
|
|
55
|
+
- `bun run prepublishOnly` - Automatically run before publishing
|
|
56
|
+
|
|
57
|
+
## System Support
|
|
58
|
+
|
|
59
|
+
Currently supports:
|
|
60
|
+
- **dnd5e** - Dungeons & Dragons 5th Edition
|
|
61
|
+
- **pf2e** - Pathfinder 2nd Edition
|
|
62
|
+
|
|
63
|
+
Additional systems can be added in `src/options.ts`.
|
|
64
|
+
|
|
65
|
+
## Resources
|
|
66
|
+
|
|
67
|
+
### Foundry VTT Documentation
|
|
68
|
+
- [dnd5e System Wiki](https://github.com/foundryvtt/dnd5e/wiki)
|
|
69
|
+
- [dnd5e Module Registration](https://github.com/foundryvtt/dnd5e/wiki/Module-Registration)
|
|
70
|
+
- [PF2e Wiki](https://github.com/foundryvtt/pf2e/wiki)
|
|
71
|
+
|
|
72
|
+
### Module Development
|
|
73
|
+
- [Foundry VTT Module Development](https://foundryvtt.com/article/modules/)
|
|
74
|
+
|
|
75
|
+
## License
|
|
76
|
+
|
|
77
|
+
MIT
|
|
78
|
+
|
|
79
|
+
## Contributing
|
|
80
|
+
|
|
81
|
+
Contributions are welcome! Please feel free to submit pull requests.
|
|
82
|
+
|
|
83
|
+
## Issues
|
|
84
|
+
|
|
85
|
+
Found a bug? Please open an issue on [GitHub](https://github.com/Loot-Foundry/create-lt-adventure/issues).
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "Github Workflow",
|
|
3
|
-
"description": "Adds support for automated releases via Github workflows",
|
|
4
|
-
"default": true
|
|
5
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "Github Workflow",
|
|
3
|
+
"description": "Adds support for automated releases via Github workflows",
|
|
4
|
+
"default": true
|
|
5
|
+
}
|
|
@@ -1,96 +1,96 @@
|
|
|
1
|
-
name: Release Creation
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
release:
|
|
5
|
-
types: [published]
|
|
6
|
-
|
|
7
|
-
jobs:
|
|
8
|
-
build:
|
|
9
|
-
runs-on: ubuntu-latest
|
|
10
|
-
steps:
|
|
11
|
-
- uses: actions/checkout@v4
|
|
12
|
-
- uses: oven-sh/setup-bun@v2
|
|
13
|
-
|
|
14
|
-
- name: Extract version from tag without the v
|
|
15
|
-
id: get-version
|
|
16
|
-
run: echo "v=${GITHUB_REF_NAME#v}" >> "$GITHUB_OUTPUT"
|
|
17
|
-
|
|
18
|
-
- name: Substitute Manifest and Download Links For Versioned Ones
|
|
19
|
-
id: sub_manifest_link_version
|
|
20
|
-
uses: microsoft/variable-substitution@v1
|
|
21
|
-
with:
|
|
22
|
-
files: module.json
|
|
23
|
-
env:
|
|
24
|
-
flags.canUpload: false
|
|
25
|
-
version: ${{ steps.get-version.outputs.v }}
|
|
26
|
-
|
|
27
|
-
- name: Install packages
|
|
28
|
-
run: bun i --frozen-lockfile
|
|
29
|
-
|
|
30
|
-
- name: Build distribution
|
|
31
|
-
run: bun run build
|
|
32
|
-
|
|
33
|
-
# Create a zip file with all files required by the module to add to the release.
|
|
34
|
-
- name: Bundle into ZIP file
|
|
35
|
-
run: zip -r ./module.zip module.json assets/ dist/ packs/ lang/
|
|
36
|
-
|
|
37
|
-
# Create a release for this specific version.
|
|
38
|
-
- name: Update Release with Files
|
|
39
|
-
id: create_version_release
|
|
40
|
-
uses: ncipollo/release-action@v1
|
|
41
|
-
with:
|
|
42
|
-
allowUpdates: true # Set this to false if you want to prevent updating existing releases.
|
|
43
|
-
name: ${{ github.event.release.name }}
|
|
44
|
-
tag: ${{ github.event.release.tag_name }}
|
|
45
|
-
body: ${{ github.event.release.body }}
|
|
46
|
-
artifacts: "./module.json, ./module.zip"
|
|
47
|
-
omitDraftDuringUpdate: true
|
|
48
|
-
omitPrereleaseDuringUpdate: true
|
|
49
|
-
|
|
50
|
-
# https://stackoverflow.com/questions/61919141/read-json-file-in-github-actions
|
|
51
|
-
- id: set_var
|
|
52
|
-
run: echo "PACKAGE_JSON=$(jq -c . < module.json)" >> "$GITHUB_OUTPUT"
|
|
53
|
-
|
|
54
|
-
- name: Get Module ID
|
|
55
|
-
id: module_id
|
|
56
|
-
run: echo "module_id=${{ fromJson(steps.set_var.outputs.PACKAGE_JSON).id }}" >> "$GITHUB_OUTPUT"
|
|
57
|
-
|
|
58
|
-
- name: Get FTP Path
|
|
59
|
-
id: ftp
|
|
60
|
-
run: echo "ftp=${{ fromJson(steps.set_var.outputs.PACKAGE_JSON).flags.ftpPath || format('NEW/{0}', steps.module_id.outputs.module_id) }}" >> "$GITHUB_OUTPUT"
|
|
61
|
-
|
|
62
|
-
- name: Get Module Title
|
|
63
|
-
id: title
|
|
64
|
-
run: echo "title=${{fromJson(steps.set_var.outputs.PACKAGE_JSON).title}}" >> "$GITHUB_OUTPUT"
|
|
65
|
-
|
|
66
|
-
- name: Put Files into FTP Folder
|
|
67
|
-
env:
|
|
68
|
-
FTP_PASSWORD: ${{ secrets.FTP_PASSWORD }}
|
|
69
|
-
if: ${{ env.FTP_PASSWORD != '' }}
|
|
70
|
-
run: |
|
|
71
|
-
ls
|
|
72
|
-
mkdir _ftp
|
|
73
|
-
cp module.json _ftp/
|
|
74
|
-
cp module.zip _ftp/
|
|
75
|
-
mkdir _ftp/${{steps.module_id.outputs.module_id}}
|
|
76
|
-
cp module.json _ftp/${{steps.module_id.outputs.module_id}}/
|
|
77
|
-
|
|
78
|
-
- name: Upload FTP
|
|
79
|
-
uses: sebastianpopp/ftp-action@releases/v2
|
|
80
|
-
env:
|
|
81
|
-
FTP_PASSWORD: ${{ secrets.FTP_PASSWORD }}
|
|
82
|
-
if: ${{ env.FTP_PASSWORD != '' }}
|
|
83
|
-
with:
|
|
84
|
-
host: ${{ secrets.FTP_SERVER }}
|
|
85
|
-
user: ${{ secrets.FTP_USERNAME }}
|
|
86
|
-
password: ${{ env.FTP_PASSWORD }}
|
|
87
|
-
localDir: _ftp
|
|
88
|
-
remoteDir: ${{steps.ftp.outputs.ftp}}
|
|
89
|
-
|
|
90
|
-
- name: Send Discord Ping
|
|
91
|
-
uses: Ilshidur/action-discord@0.3.2
|
|
92
|
-
env:
|
|
93
|
-
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
|
|
94
|
-
if: ${{ env.DISCORD_WEBHOOK != '' && !github.event.release.prerelease }}
|
|
95
|
-
with:
|
|
96
|
-
args: "${{steps.title.outputs.title}} has been updated to version `${{github.event.release.tag_name}}`!"
|
|
1
|
+
name: Release Creation
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
build:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
steps:
|
|
11
|
+
- uses: actions/checkout@v4
|
|
12
|
+
- uses: oven-sh/setup-bun@v2
|
|
13
|
+
|
|
14
|
+
- name: Extract version from tag without the v
|
|
15
|
+
id: get-version
|
|
16
|
+
run: echo "v=${GITHUB_REF_NAME#v}" >> "$GITHUB_OUTPUT"
|
|
17
|
+
|
|
18
|
+
- name: Substitute Manifest and Download Links For Versioned Ones
|
|
19
|
+
id: sub_manifest_link_version
|
|
20
|
+
uses: microsoft/variable-substitution@v1
|
|
21
|
+
with:
|
|
22
|
+
files: module.json
|
|
23
|
+
env:
|
|
24
|
+
flags.canUpload: false
|
|
25
|
+
version: ${{ steps.get-version.outputs.v }}
|
|
26
|
+
|
|
27
|
+
- name: Install packages
|
|
28
|
+
run: bun i --frozen-lockfile
|
|
29
|
+
|
|
30
|
+
- name: Build distribution
|
|
31
|
+
run: bun run build
|
|
32
|
+
|
|
33
|
+
# Create a zip file with all files required by the module to add to the release.
|
|
34
|
+
- name: Bundle into ZIP file
|
|
35
|
+
run: zip -r ./module.zip module.json assets/ dist/ packs/ lang/
|
|
36
|
+
|
|
37
|
+
# Create a release for this specific version.
|
|
38
|
+
- name: Update Release with Files
|
|
39
|
+
id: create_version_release
|
|
40
|
+
uses: ncipollo/release-action@v1
|
|
41
|
+
with:
|
|
42
|
+
allowUpdates: true # Set this to false if you want to prevent updating existing releases.
|
|
43
|
+
name: ${{ github.event.release.name }}
|
|
44
|
+
tag: ${{ github.event.release.tag_name }}
|
|
45
|
+
body: ${{ github.event.release.body }}
|
|
46
|
+
artifacts: "./module.json, ./module.zip"
|
|
47
|
+
omitDraftDuringUpdate: true
|
|
48
|
+
omitPrereleaseDuringUpdate: true
|
|
49
|
+
|
|
50
|
+
# https://stackoverflow.com/questions/61919141/read-json-file-in-github-actions
|
|
51
|
+
- id: set_var
|
|
52
|
+
run: echo "PACKAGE_JSON=$(jq -c . < module.json)" >> "$GITHUB_OUTPUT"
|
|
53
|
+
|
|
54
|
+
- name: Get Module ID
|
|
55
|
+
id: module_id
|
|
56
|
+
run: echo "module_id=${{ fromJson(steps.set_var.outputs.PACKAGE_JSON).id }}" >> "$GITHUB_OUTPUT"
|
|
57
|
+
|
|
58
|
+
- name: Get FTP Path
|
|
59
|
+
id: ftp
|
|
60
|
+
run: echo "ftp=${{ fromJson(steps.set_var.outputs.PACKAGE_JSON).flags.ftpPath || format('NEW/{0}', steps.module_id.outputs.module_id) }}" >> "$GITHUB_OUTPUT"
|
|
61
|
+
|
|
62
|
+
- name: Get Module Title
|
|
63
|
+
id: title
|
|
64
|
+
run: echo "title=${{fromJson(steps.set_var.outputs.PACKAGE_JSON).title}}" >> "$GITHUB_OUTPUT"
|
|
65
|
+
|
|
66
|
+
- name: Put Files into FTP Folder
|
|
67
|
+
env:
|
|
68
|
+
FTP_PASSWORD: ${{ secrets.FTP_PASSWORD }}
|
|
69
|
+
if: ${{ env.FTP_PASSWORD != '' }}
|
|
70
|
+
run: |
|
|
71
|
+
ls
|
|
72
|
+
mkdir _ftp
|
|
73
|
+
cp module.json _ftp/
|
|
74
|
+
cp module.zip _ftp/
|
|
75
|
+
mkdir _ftp/${{steps.module_id.outputs.module_id}}
|
|
76
|
+
cp module.json _ftp/${{steps.module_id.outputs.module_id}}/
|
|
77
|
+
|
|
78
|
+
- name: Upload FTP
|
|
79
|
+
uses: sebastianpopp/ftp-action@releases/v2
|
|
80
|
+
env:
|
|
81
|
+
FTP_PASSWORD: ${{ secrets.FTP_PASSWORD }}
|
|
82
|
+
if: ${{ env.FTP_PASSWORD != '' }}
|
|
83
|
+
with:
|
|
84
|
+
host: ${{ secrets.FTP_SERVER }}
|
|
85
|
+
user: ${{ secrets.FTP_USERNAME }}
|
|
86
|
+
password: ${{ env.FTP_PASSWORD }}
|
|
87
|
+
localDir: _ftp
|
|
88
|
+
remoteDir: ${{steps.ftp.outputs.ftp}}
|
|
89
|
+
|
|
90
|
+
- name: Send Discord Ping
|
|
91
|
+
uses: Ilshidur/action-discord@0.3.2
|
|
92
|
+
env:
|
|
93
|
+
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
|
|
94
|
+
if: ${{ env.DISCORD_WEBHOOK != '' && !github.event.release.prerelease }}
|
|
95
|
+
with:
|
|
96
|
+
args: "${{steps.title.outputs.title}} has been updated to version `${{github.event.release.tag_name}}`!"
|
|
@@ -1,115 +1,115 @@
|
|
|
1
|
-
// Creates a .github/workflows/main.yml file.
|
|
2
|
-
// Additional options include:
|
|
3
|
-
// - Support for prereleases (requires a seperate branch)
|
|
4
|
-
// - Supports for uploading via FTP to external servers
|
|
5
|
-
// - Discord webhook notifications
|
|
6
|
-
|
|
7
|
-
import * as p from "@clack/prompts";
|
|
8
|
-
import { cyan } from "kolorist";
|
|
9
|
-
import { mkdir, readFile, writeFile } from "fs/promises";
|
|
10
|
-
import { dirname } from "path";
|
|
11
|
-
import { fileURLToPath } from "url";
|
|
12
|
-
|
|
13
|
-
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
14
|
-
|
|
15
|
-
const data = await p.group(
|
|
16
|
-
{
|
|
17
|
-
features: () =>
|
|
18
|
-
p.multiselect({
|
|
19
|
-
message: "Additional features?",
|
|
20
|
-
initialValues: ["ftp", "discord"],
|
|
21
|
-
required: false,
|
|
22
|
-
options: [
|
|
23
|
-
// { label: "Prereleases", value: "prereleases" },
|
|
24
|
-
{ label: "Uploading via FTP", value: "ftp" },
|
|
25
|
-
{ label: "Discord webhook on updates", value: "discord" },
|
|
26
|
-
],
|
|
27
|
-
}),
|
|
28
|
-
},
|
|
29
|
-
{ onCancel: () => process.exit(0) },
|
|
30
|
-
);
|
|
31
|
-
|
|
32
|
-
// Grab main.yml template
|
|
33
|
-
const mainYmlTemplate = await readFile(`${__dirname}/main.yml`, "utf8");
|
|
34
|
-
|
|
35
|
-
// Get the module directory from environment variable
|
|
36
|
-
const moduleDir = process.env.MODULE_DIR || process.cwd();
|
|
37
|
-
|
|
38
|
-
let mainYml = mainYmlTemplate;
|
|
39
|
-
|
|
40
|
-
// I should probably just make this a JSON and convert it to accursed YAML at the end step...
|
|
41
|
-
if (data.features.includes("discord") || data.features.includes("ftp")) {
|
|
42
|
-
mainYml += `
|
|
43
|
-
# https://stackoverflow.com/questions/61919141/read-json-file-in-github-actions
|
|
44
|
-
- id: set_var
|
|
45
|
-
run: echo "PACKAGE_JSON=$(jq -c . < module.json)" >> $GITHUB_OUTPUT
|
|
46
|
-
|
|
47
|
-
- name: Get FTP Path
|
|
48
|
-
id: ftp
|
|
49
|
-
run: echo "ftp=\${{fromJson(steps.set_var.outputs.PACKAGE_JSON).flags.ftpPath}}" >> $GITHUB_OUTPUT
|
|
50
|
-
|
|
51
|
-
- name: Get Module ID
|
|
52
|
-
id: module_id
|
|
53
|
-
run: echo "module_id=\${{fromJson(steps.set_var.outputs.PACKAGE_JSON).id}}" >> $GITHUB_OUTPUT
|
|
54
|
-
|
|
55
|
-
- name: Get Module Title
|
|
56
|
-
id: title
|
|
57
|
-
run: echo "title=\${{fromJson(steps.set_var.outputs.PACKAGE_JSON).title}}" >> $GITHUB_OUTPUT
|
|
58
|
-
`;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
if (data.features.includes("ftp")) {
|
|
62
|
-
mainYml += `
|
|
63
|
-
- name: Put Files into FTP Folder
|
|
64
|
-
env:
|
|
65
|
-
FTP_PASSWORD: \${{ secrets.FTP_PASSWORD }}
|
|
66
|
-
if: \${{ env.FTP_PASSWORD != '' }}
|
|
67
|
-
run: |
|
|
68
|
-
ls
|
|
69
|
-
mkdir _ftp
|
|
70
|
-
cp module.json _ftp/
|
|
71
|
-
cp module.zip _ftp/
|
|
72
|
-
mkdir _ftp/\${{steps.module_id.outputs.module_id}}
|
|
73
|
-
cp module.json _ftp/\${{steps.module_id.outputs.module_id}}/
|
|
74
|
-
|
|
75
|
-
- name: Upload FTP
|
|
76
|
-
uses: sebastianpopp/ftp-action@releases/v2
|
|
77
|
-
env:
|
|
78
|
-
FTP_PASSWORD: \${{ secrets.FTP_PASSWORD }}
|
|
79
|
-
if: \${{ env.FTP_PASSWORD != '' }}
|
|
80
|
-
with:
|
|
81
|
-
host: \${{ secrets.FTP_SERVER }}
|
|
82
|
-
user: \${{ secrets.FTP_USERNAME }}
|
|
83
|
-
password: \${{ env.FTP_PASSWORD }}
|
|
84
|
-
localDir: _ftp
|
|
85
|
-
remoteDir: \${{steps.ftp.outputs.ftp}}
|
|
86
|
-
`;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
if (data.features.includes("discord")) {
|
|
90
|
-
mainYml += `
|
|
91
|
-
- name: Send Discord Ping
|
|
92
|
-
uses: Ilshidur/action-discord@0.3.2
|
|
93
|
-
env:
|
|
94
|
-
DISCORD_WEBHOOK: \${{ secrets.DISCORD_WEBHOOK }}
|
|
95
|
-
if: \${{ env.DISCORD_WEBHOOK != '' && !github.event.release.prerelease }}
|
|
96
|
-
with:
|
|
97
|
-
args: "\${{steps.title.outputs.title}} has been updated to version \`\${{github.event.release.tag_name}}\`!"
|
|
98
|
-
`;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
// Create main.yml file
|
|
102
|
-
const workflowDir = `${moduleDir}/.github/workflows`;
|
|
103
|
-
await mkdir(workflowDir, { recursive: true });
|
|
104
|
-
await writeFile(`${workflowDir}/main.yml`, mainYml);
|
|
105
|
-
|
|
106
|
-
let note = "✅ Installed!";
|
|
107
|
-
note += "\nThe Github workflow is triggered by making a new release. To make a new release go to your repository's Releases page which can be found in the sidebar on the right and press \"Draft a new release.\" Fill in the version number and you're done!"
|
|
108
|
-
|
|
109
|
-
if (data.features.includes("discord"))
|
|
110
|
-
note +=
|
|
111
|
-
"\n - For the Discord integration, make sure to create a DISCORD_WEBHOOK secret with the webhook url.";
|
|
112
|
-
if (data.features.includes("ftp"))
|
|
113
|
-
note += `\n - For the FTP integration, make sure to include the FTP_SERVER, FTP_USERNAME, and FTP_PASSWORD secrets.\n\tThe module JSON also can include a flag stating its subdirectory on the FTP server under ${cyan("flags.ftpPath")}.`;
|
|
114
|
-
|
|
115
|
-
p.note(note, "Github Workflow");
|
|
1
|
+
// Creates a .github/workflows/main.yml file.
|
|
2
|
+
// Additional options include:
|
|
3
|
+
// - Support for prereleases (requires a seperate branch)
|
|
4
|
+
// - Supports for uploading via FTP to external servers
|
|
5
|
+
// - Discord webhook notifications
|
|
6
|
+
|
|
7
|
+
import * as p from "@clack/prompts";
|
|
8
|
+
import { cyan } from "kolorist";
|
|
9
|
+
import { mkdir, readFile, writeFile } from "fs/promises";
|
|
10
|
+
import { dirname } from "path";
|
|
11
|
+
import { fileURLToPath } from "url";
|
|
12
|
+
|
|
13
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
14
|
+
|
|
15
|
+
const data = await p.group(
|
|
16
|
+
{
|
|
17
|
+
features: () =>
|
|
18
|
+
p.multiselect({
|
|
19
|
+
message: "Additional features?",
|
|
20
|
+
initialValues: ["ftp", "discord"],
|
|
21
|
+
required: false,
|
|
22
|
+
options: [
|
|
23
|
+
// { label: "Prereleases", value: "prereleases" },
|
|
24
|
+
{ label: "Uploading via FTP", value: "ftp" },
|
|
25
|
+
{ label: "Discord webhook on updates", value: "discord" },
|
|
26
|
+
],
|
|
27
|
+
}),
|
|
28
|
+
},
|
|
29
|
+
{ onCancel: () => process.exit(0) },
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
// Grab main.yml template
|
|
33
|
+
const mainYmlTemplate = await readFile(`${__dirname}/main.yml`, "utf8");
|
|
34
|
+
|
|
35
|
+
// Get the module directory from environment variable
|
|
36
|
+
const moduleDir = process.env.MODULE_DIR || process.cwd();
|
|
37
|
+
|
|
38
|
+
let mainYml = mainYmlTemplate;
|
|
39
|
+
|
|
40
|
+
// I should probably just make this a JSON and convert it to accursed YAML at the end step...
|
|
41
|
+
if (data.features.includes("discord") || data.features.includes("ftp")) {
|
|
42
|
+
mainYml += `
|
|
43
|
+
# https://stackoverflow.com/questions/61919141/read-json-file-in-github-actions
|
|
44
|
+
- id: set_var
|
|
45
|
+
run: echo "PACKAGE_JSON=$(jq -c . < module.json)" >> $GITHUB_OUTPUT
|
|
46
|
+
|
|
47
|
+
- name: Get FTP Path
|
|
48
|
+
id: ftp
|
|
49
|
+
run: echo "ftp=\${{fromJson(steps.set_var.outputs.PACKAGE_JSON).flags.ftpPath}}" >> $GITHUB_OUTPUT
|
|
50
|
+
|
|
51
|
+
- name: Get Module ID
|
|
52
|
+
id: module_id
|
|
53
|
+
run: echo "module_id=\${{fromJson(steps.set_var.outputs.PACKAGE_JSON).id}}" >> $GITHUB_OUTPUT
|
|
54
|
+
|
|
55
|
+
- name: Get Module Title
|
|
56
|
+
id: title
|
|
57
|
+
run: echo "title=\${{fromJson(steps.set_var.outputs.PACKAGE_JSON).title}}" >> $GITHUB_OUTPUT
|
|
58
|
+
`;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (data.features.includes("ftp")) {
|
|
62
|
+
mainYml += `
|
|
63
|
+
- name: Put Files into FTP Folder
|
|
64
|
+
env:
|
|
65
|
+
FTP_PASSWORD: \${{ secrets.FTP_PASSWORD }}
|
|
66
|
+
if: \${{ env.FTP_PASSWORD != '' }}
|
|
67
|
+
run: |
|
|
68
|
+
ls
|
|
69
|
+
mkdir _ftp
|
|
70
|
+
cp module.json _ftp/
|
|
71
|
+
cp module.zip _ftp/
|
|
72
|
+
mkdir _ftp/\${{steps.module_id.outputs.module_id}}
|
|
73
|
+
cp module.json _ftp/\${{steps.module_id.outputs.module_id}}/
|
|
74
|
+
|
|
75
|
+
- name: Upload FTP
|
|
76
|
+
uses: sebastianpopp/ftp-action@releases/v2
|
|
77
|
+
env:
|
|
78
|
+
FTP_PASSWORD: \${{ secrets.FTP_PASSWORD }}
|
|
79
|
+
if: \${{ env.FTP_PASSWORD != '' }}
|
|
80
|
+
with:
|
|
81
|
+
host: \${{ secrets.FTP_SERVER }}
|
|
82
|
+
user: \${{ secrets.FTP_USERNAME }}
|
|
83
|
+
password: \${{ env.FTP_PASSWORD }}
|
|
84
|
+
localDir: _ftp
|
|
85
|
+
remoteDir: \${{steps.ftp.outputs.ftp}}
|
|
86
|
+
`;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (data.features.includes("discord")) {
|
|
90
|
+
mainYml += `
|
|
91
|
+
- name: Send Discord Ping
|
|
92
|
+
uses: Ilshidur/action-discord@0.3.2
|
|
93
|
+
env:
|
|
94
|
+
DISCORD_WEBHOOK: \${{ secrets.DISCORD_WEBHOOK }}
|
|
95
|
+
if: \${{ env.DISCORD_WEBHOOK != '' && !github.event.release.prerelease }}
|
|
96
|
+
with:
|
|
97
|
+
args: "\${{steps.title.outputs.title}} has been updated to version \`\${{github.event.release.tag_name}}\`!"
|
|
98
|
+
`;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Create main.yml file
|
|
102
|
+
const workflowDir = `${moduleDir}/.github/workflows`;
|
|
103
|
+
await mkdir(workflowDir, { recursive: true });
|
|
104
|
+
await writeFile(`${workflowDir}/main.yml`, mainYml);
|
|
105
|
+
|
|
106
|
+
let note = "✅ Installed!";
|
|
107
|
+
note += "\nThe Github workflow is triggered by making a new release. To make a new release go to your repository's Releases page which can be found in the sidebar on the right and press \"Draft a new release.\" Fill in the version number and you're done!"
|
|
108
|
+
|
|
109
|
+
if (data.features.includes("discord"))
|
|
110
|
+
note +=
|
|
111
|
+
"\n - For the Discord integration, make sure to create a DISCORD_WEBHOOK secret with the webhook url.";
|
|
112
|
+
if (data.features.includes("ftp"))
|
|
113
|
+
note += `\n - For the FTP integration, make sure to include the FTP_SERVER, FTP_USERNAME, and FTP_PASSWORD secrets.\n\tThe module JSON also can include a flag stating its subdirectory on the FTP server under ${cyan("flags.ftpPath")}.`;
|
|
114
|
+
|
|
115
|
+
p.note(note, "Github Workflow");
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "SF2e <=> PF2e UUID Redirects",
|
|
3
|
-
"description": "Adds UUID redirects for modules that support both SF2e and PF2e. Skipped if module doesn't support both systems.",
|
|
4
|
-
"default": false
|
|
5
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "SF2e <=> PF2e UUID Redirects",
|
|
3
|
+
"description": "Adds UUID redirects for modules that support both SF2e and PF2e. Skipped if module doesn't support both systems.",
|
|
4
|
+
"default": false
|
|
5
|
+
}
|
|
@@ -1,119 +1,119 @@
|
|
|
1
|
-
// Creates a uuid-redirects.js file that redirects sf2e compendium UUIDs to pf2e equivalents.
|
|
2
|
-
// This addon only activates when both sf2e and pf2e systems are selected.
|
|
3
|
-
|
|
4
|
-
import * as p from "@clack/prompts";
|
|
5
|
-
import { cyan } from "kolorist";
|
|
6
|
-
import { readFile, writeFile, mkdir } from "fs/promises";
|
|
7
|
-
import { existsSync } from "fs";
|
|
8
|
-
import { dirname, join } from "path";
|
|
9
|
-
import { fileURLToPath } from "url";
|
|
10
|
-
|
|
11
|
-
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
12
|
-
|
|
13
|
-
// Get the module directory from environment variable
|
|
14
|
-
const moduleDir = process.env.MODULE_DIR || process.cwd();
|
|
15
|
-
|
|
16
|
-
// Read the module.json to get module ID and packs
|
|
17
|
-
const moduleJsonPath = join(moduleDir, "module.json");
|
|
18
|
-
if (!existsSync(moduleJsonPath)) {
|
|
19
|
-
p.log.warn("⚠️ module.json not found, skipping SF2e to PF2e UUID redirects");
|
|
20
|
-
process.exit(0);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
const moduleJson = JSON.parse(await readFile(moduleJsonPath, "utf8"));
|
|
24
|
-
const moduleId = moduleJson.id;
|
|
25
|
-
const systems = (moduleJson.relationships?.systems || []).map(s => s.id);
|
|
26
|
-
const packs = moduleJson.packs || [];
|
|
27
|
-
|
|
28
|
-
// Check if both sf2e and pf2e are selected
|
|
29
|
-
if (!systems.includes("sf2e") || !systems.includes("pf2e")) {
|
|
30
|
-
p.note("⏭️ Skipped - both sf2e and pf2e systems must be selected", "SF2e to PF2e UUID Redirects");
|
|
31
|
-
process.exit(0);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// Find base pack names (e.g., "items", "actors") that have both sf2e and pf2e variants
|
|
35
|
-
const sf2ePackNames = packs.filter(p => p.system === "sf2e").map(p => p.name.replace("sf2e-", ""));
|
|
36
|
-
const pf2ePackNames = packs.filter(p => p.system === "pf2e").map(p => p.name.replace("pf2e-", ""));
|
|
37
|
-
const commonPackNames = sf2ePackNames.filter(name => pf2ePackNames.includes(name));
|
|
38
|
-
|
|
39
|
-
if (commonPackNames.length === 0) {
|
|
40
|
-
p.note("⏭️ Skipped - no common packs found between sf2e and pf2e", "SF2e to PF2e UUID Redirects");
|
|
41
|
-
process.exit(0);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// Build the UUID_REDIRECTS object
|
|
45
|
-
const redirects = {};
|
|
46
|
-
for (const packName of commonPackNames) {
|
|
47
|
-
redirects[`Compendium.${moduleId}.sf2e-${packName}`] = `Compendium.${moduleId}.pf2e-${packName}`;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
// Generate the uuid-redirects.js content
|
|
51
|
-
const redirectsContent = `// Auto-generated by create-fvtt-module - sf2e-pf2e-redirects addon
|
|
52
|
-
// Redirects sf2e compendium UUIDs to their pf2e equivalents
|
|
53
|
-
|
|
54
|
-
const UUID_REDIRECTS = {
|
|
55
|
-
${Object.entries(redirects).map(([from, to]) => ` "${from}": "${to}"`).join(",\n")}
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
for (const [from, to] of Object.entries(UUID_REDIRECTS)) {
|
|
59
|
-
CONFIG.compendium.uuidRedirects[from] = to;
|
|
60
|
-
}
|
|
61
|
-
`;
|
|
62
|
-
|
|
63
|
-
// Check if src directory exists
|
|
64
|
-
const srcDir = join(moduleDir, "src");
|
|
65
|
-
const srcExists = existsSync(srcDir);
|
|
66
|
-
|
|
67
|
-
// Check for index files
|
|
68
|
-
const indexTs = join(srcDir, "index.ts");
|
|
69
|
-
const indexJs = join(srcDir, "index.js");
|
|
70
|
-
const indexTsExists = existsSync(indexTs);
|
|
71
|
-
const indexJsExists = existsSync(indexJs);
|
|
72
|
-
|
|
73
|
-
if (srcExists) {
|
|
74
|
-
// Determine file extension based on existing index files
|
|
75
|
-
const useTypeScript = indexTsExists;
|
|
76
|
-
const redirectFileName = useTypeScript ? "uuid-redirects.ts" : "uuid-redirects.js";
|
|
77
|
-
const importFileName = useTypeScript ? "uuid-redirects.js" : "uuid-redirects.js"; // Always import as .js (TS compilers handle this)
|
|
78
|
-
const redirectsPath = join(srcDir, redirectFileName);
|
|
79
|
-
|
|
80
|
-
await writeFile(redirectsPath, redirectsContent);
|
|
81
|
-
p.log.success(`Created ${cyan("src/" + redirectFileName)}`);
|
|
82
|
-
|
|
83
|
-
// Try to import into index.ts or index.js
|
|
84
|
-
const importStatement = `import "./${importFileName}";`;
|
|
85
|
-
|
|
86
|
-
if (indexTsExists) {
|
|
87
|
-
const indexContent = await readFile(indexTs, "utf8");
|
|
88
|
-
// Check if import already exists
|
|
89
|
-
if (!indexContent.includes("uuid-redirects")) {
|
|
90
|
-
const newIndexContent = `${importStatement}\n${indexContent}`;
|
|
91
|
-
await writeFile(indexTs, newIndexContent);
|
|
92
|
-
p.log.success(`Imported ${redirectFileName} into ${cyan("src/index.ts")}`);
|
|
93
|
-
} else {
|
|
94
|
-
p.log.info(`Import already exists in ${cyan("src/index.ts")}`);
|
|
95
|
-
}
|
|
96
|
-
} else if (indexJsExists) {
|
|
97
|
-
const indexContent = await readFile(indexJs, "utf8");
|
|
98
|
-
if (!indexContent.includes("uuid-redirects")) {
|
|
99
|
-
const newIndexContent = `${importStatement}\n${indexContent}`;
|
|
100
|
-
await writeFile(indexJs, newIndexContent);
|
|
101
|
-
p.log.success(`Imported ${redirectFileName} into ${cyan("src/index.js")}`);
|
|
102
|
-
} else {
|
|
103
|
-
p.log.info(`Import already exists in ${cyan("src/index.js")}`);
|
|
104
|
-
}
|
|
105
|
-
} else {
|
|
106
|
-
p.log.warn(`⚠️ No index.ts or index.js found in src/. Please manually add ${cyan(importStatement)} to your main entry file.`);
|
|
107
|
-
}
|
|
108
|
-
} else {
|
|
109
|
-
// No src directory - write to module root and warn
|
|
110
|
-
const redirectsPath = join(moduleDir, "uuid-redirects.js");
|
|
111
|
-
await writeFile(redirectsPath, redirectsContent);
|
|
112
|
-
p.log.warn(`⚠️ No src/ directory found. Created ${cyan("uuid-redirects.js")} in module root.`);
|
|
113
|
-
p.log.warn(`⚠️ Please manually add ${cyan('import "./uuid-redirects.js";')} to your module's main entry point.`);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
let note = "✅ Installed!";
|
|
117
|
-
note += `\n${commonPackNames.length} pack(s) configured for sf2e → pf2e redirect: ${cyan(commonPackNames.join(", "))}`;
|
|
118
|
-
|
|
119
|
-
p.note(note, "SF2e to PF2e UUID Redirects");
|
|
1
|
+
// Creates a uuid-redirects.js file that redirects sf2e compendium UUIDs to pf2e equivalents.
|
|
2
|
+
// This addon only activates when both sf2e and pf2e systems are selected.
|
|
3
|
+
|
|
4
|
+
import * as p from "@clack/prompts";
|
|
5
|
+
import { cyan } from "kolorist";
|
|
6
|
+
import { readFile, writeFile, mkdir } from "fs/promises";
|
|
7
|
+
import { existsSync } from "fs";
|
|
8
|
+
import { dirname, join } from "path";
|
|
9
|
+
import { fileURLToPath } from "url";
|
|
10
|
+
|
|
11
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
12
|
+
|
|
13
|
+
// Get the module directory from environment variable
|
|
14
|
+
const moduleDir = process.env.MODULE_DIR || process.cwd();
|
|
15
|
+
|
|
16
|
+
// Read the module.json to get module ID and packs
|
|
17
|
+
const moduleJsonPath = join(moduleDir, "module.json");
|
|
18
|
+
if (!existsSync(moduleJsonPath)) {
|
|
19
|
+
p.log.warn("⚠️ module.json not found, skipping SF2e to PF2e UUID redirects");
|
|
20
|
+
process.exit(0);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const moduleJson = JSON.parse(await readFile(moduleJsonPath, "utf8"));
|
|
24
|
+
const moduleId = moduleJson.id;
|
|
25
|
+
const systems = (moduleJson.relationships?.systems || []).map(s => s.id);
|
|
26
|
+
const packs = moduleJson.packs || [];
|
|
27
|
+
|
|
28
|
+
// Check if both sf2e and pf2e are selected
|
|
29
|
+
if (!systems.includes("sf2e") || !systems.includes("pf2e")) {
|
|
30
|
+
p.note("⏭️ Skipped - both sf2e and pf2e systems must be selected", "SF2e to PF2e UUID Redirects");
|
|
31
|
+
process.exit(0);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Find base pack names (e.g., "items", "actors") that have both sf2e and pf2e variants
|
|
35
|
+
const sf2ePackNames = packs.filter(p => p.system === "sf2e").map(p => p.name.replace("sf2e-", ""));
|
|
36
|
+
const pf2ePackNames = packs.filter(p => p.system === "pf2e").map(p => p.name.replace("pf2e-", ""));
|
|
37
|
+
const commonPackNames = sf2ePackNames.filter(name => pf2ePackNames.includes(name));
|
|
38
|
+
|
|
39
|
+
if (commonPackNames.length === 0) {
|
|
40
|
+
p.note("⏭️ Skipped - no common packs found between sf2e and pf2e", "SF2e to PF2e UUID Redirects");
|
|
41
|
+
process.exit(0);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Build the UUID_REDIRECTS object
|
|
45
|
+
const redirects = {};
|
|
46
|
+
for (const packName of commonPackNames) {
|
|
47
|
+
redirects[`Compendium.${moduleId}.sf2e-${packName}`] = `Compendium.${moduleId}.pf2e-${packName}`;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Generate the uuid-redirects.js content
|
|
51
|
+
const redirectsContent = `// Auto-generated by create-fvtt-module - sf2e-pf2e-redirects addon
|
|
52
|
+
// Redirects sf2e compendium UUIDs to their pf2e equivalents
|
|
53
|
+
|
|
54
|
+
const UUID_REDIRECTS = {
|
|
55
|
+
${Object.entries(redirects).map(([from, to]) => ` "${from}": "${to}"`).join(",\n")}
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
for (const [from, to] of Object.entries(UUID_REDIRECTS)) {
|
|
59
|
+
CONFIG.compendium.uuidRedirects[from] = to;
|
|
60
|
+
}
|
|
61
|
+
`;
|
|
62
|
+
|
|
63
|
+
// Check if src directory exists
|
|
64
|
+
const srcDir = join(moduleDir, "src");
|
|
65
|
+
const srcExists = existsSync(srcDir);
|
|
66
|
+
|
|
67
|
+
// Check for index files
|
|
68
|
+
const indexTs = join(srcDir, "index.ts");
|
|
69
|
+
const indexJs = join(srcDir, "index.js");
|
|
70
|
+
const indexTsExists = existsSync(indexTs);
|
|
71
|
+
const indexJsExists = existsSync(indexJs);
|
|
72
|
+
|
|
73
|
+
if (srcExists) {
|
|
74
|
+
// Determine file extension based on existing index files
|
|
75
|
+
const useTypeScript = indexTsExists;
|
|
76
|
+
const redirectFileName = useTypeScript ? "uuid-redirects.ts" : "uuid-redirects.js";
|
|
77
|
+
const importFileName = useTypeScript ? "uuid-redirects.js" : "uuid-redirects.js"; // Always import as .js (TS compilers handle this)
|
|
78
|
+
const redirectsPath = join(srcDir, redirectFileName);
|
|
79
|
+
|
|
80
|
+
await writeFile(redirectsPath, redirectsContent);
|
|
81
|
+
p.log.success(`Created ${cyan("src/" + redirectFileName)}`);
|
|
82
|
+
|
|
83
|
+
// Try to import into index.ts or index.js
|
|
84
|
+
const importStatement = `import "./${importFileName}";`;
|
|
85
|
+
|
|
86
|
+
if (indexTsExists) {
|
|
87
|
+
const indexContent = await readFile(indexTs, "utf8");
|
|
88
|
+
// Check if import already exists
|
|
89
|
+
if (!indexContent.includes("uuid-redirects")) {
|
|
90
|
+
const newIndexContent = `${importStatement}\n${indexContent}`;
|
|
91
|
+
await writeFile(indexTs, newIndexContent);
|
|
92
|
+
p.log.success(`Imported ${redirectFileName} into ${cyan("src/index.ts")}`);
|
|
93
|
+
} else {
|
|
94
|
+
p.log.info(`Import already exists in ${cyan("src/index.ts")}`);
|
|
95
|
+
}
|
|
96
|
+
} else if (indexJsExists) {
|
|
97
|
+
const indexContent = await readFile(indexJs, "utf8");
|
|
98
|
+
if (!indexContent.includes("uuid-redirects")) {
|
|
99
|
+
const newIndexContent = `${importStatement}\n${indexContent}`;
|
|
100
|
+
await writeFile(indexJs, newIndexContent);
|
|
101
|
+
p.log.success(`Imported ${redirectFileName} into ${cyan("src/index.js")}`);
|
|
102
|
+
} else {
|
|
103
|
+
p.log.info(`Import already exists in ${cyan("src/index.js")}`);
|
|
104
|
+
}
|
|
105
|
+
} else {
|
|
106
|
+
p.log.warn(`⚠️ No index.ts or index.js found in src/. Please manually add ${cyan(importStatement)} to your main entry file.`);
|
|
107
|
+
}
|
|
108
|
+
} else {
|
|
109
|
+
// No src directory - write to module root and warn
|
|
110
|
+
const redirectsPath = join(moduleDir, "uuid-redirects.js");
|
|
111
|
+
await writeFile(redirectsPath, redirectsContent);
|
|
112
|
+
p.log.warn(`⚠️ No src/ directory found. Created ${cyan("uuid-redirects.js")} in module root.`);
|
|
113
|
+
p.log.warn(`⚠️ Please manually add ${cyan('import "./uuid-redirects.js";')} to your module's main entry point.`);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
let note = "✅ Installed!";
|
|
117
|
+
note += `\n${commonPackNames.length} pack(s) configured for sf2e → pf2e redirect: ${cyan(commonPackNames.join(", "))}`;
|
|
118
|
+
|
|
119
|
+
p.note(note, "SF2e to PF2e UUID Redirects");
|
package/dist/bin.js
CHANGED
|
@@ -25,25 +25,25 @@ const { values: flags, positionals } = parseArgs({
|
|
|
25
25
|
allowPositionals: true,
|
|
26
26
|
});
|
|
27
27
|
if (flags.help) {
|
|
28
|
-
console.log(`Usage: create-fvtt-module [title] [options]
|
|
29
|
-
|
|
30
|
-
Scaffold a new Foundry VTT module.
|
|
31
|
-
|
|
32
|
-
Arguments:
|
|
33
|
-
title Module title (optional, prompted if not provided)
|
|
34
|
-
|
|
35
|
-
Options:
|
|
36
|
-
--help, -h Show this help message
|
|
37
|
-
--version, -v Show version number
|
|
38
|
-
--auto-id Auto-generate module ID from title
|
|
39
|
-
--template <name> Specify template to use (e.g., vite, basic)
|
|
40
|
-
--migrate-from <path> Migrate compendium packs from an existing module (filepath or URL to module.json)
|
|
41
|
-
|
|
42
|
-
Examples:
|
|
43
|
-
create-fvtt-module "My Module" --auto-id
|
|
44
|
-
create-fvtt-module --template vite
|
|
45
|
-
create-fvtt-module "My Module" --auto-id --template vite
|
|
46
|
-
create-fvtt-module "My Module" --migrate-from ./existing-module/module.json
|
|
28
|
+
console.log(`Usage: create-fvtt-module [title] [options]
|
|
29
|
+
|
|
30
|
+
Scaffold a new Foundry VTT module.
|
|
31
|
+
|
|
32
|
+
Arguments:
|
|
33
|
+
title Module title (optional, prompted if not provided)
|
|
34
|
+
|
|
35
|
+
Options:
|
|
36
|
+
--help, -h Show this help message
|
|
37
|
+
--version, -v Show version number
|
|
38
|
+
--auto-id Auto-generate module ID from title
|
|
39
|
+
--template <name> Specify template to use (e.g., vite, basic)
|
|
40
|
+
--migrate-from <path> Migrate compendium packs from an existing module (filepath or URL to module.json)
|
|
41
|
+
|
|
42
|
+
Examples:
|
|
43
|
+
create-fvtt-module "My Module" --auto-id
|
|
44
|
+
create-fvtt-module --template vite
|
|
45
|
+
create-fvtt-module "My Module" --auto-id --template vite
|
|
46
|
+
create-fvtt-module "My Module" --migrate-from ./existing-module/module.json
|
|
47
47
|
create-fvtt-module "My Module" --migrate-from https://example.com/module.json`);
|
|
48
48
|
process.exit(0);
|
|
49
49
|
}
|
package/package.json
CHANGED
|
@@ -1,66 +1,68 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "create-lt-adventure",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "A CLI tool to scaffold Foundry VTT modules",
|
|
5
|
-
"keywords": [
|
|
6
|
-
"foundry-vtt",
|
|
7
|
-
"module",
|
|
8
|
-
"scaffold",
|
|
9
|
-
"cli"
|
|
10
|
-
],
|
|
11
|
-
"license": "MIT",
|
|
12
|
-
"author": "mrvauxs",
|
|
13
|
-
"repository": {
|
|
14
|
-
"type": "git",
|
|
15
|
-
"url": "https://github.com/
|
|
16
|
-
},
|
|
17
|
-
"homepage": "https://github.com/
|
|
18
|
-
"bugs": {
|
|
19
|
-
"url": "https://github.com/
|
|
20
|
-
},
|
|
21
|
-
"type": "module",
|
|
22
|
-
"main": "./dist/index.js",
|
|
23
|
-
"exports": {
|
|
24
|
-
".": {
|
|
25
|
-
"import": "./dist/index.js",
|
|
26
|
-
"types": "./dist/index.d.ts"
|
|
27
|
-
},
|
|
28
|
-
"./bin": {
|
|
29
|
-
"import": "./dist/bin.js",
|
|
30
|
-
"types": "./dist/bin.d.ts"
|
|
31
|
-
}
|
|
32
|
-
},
|
|
33
|
-
"bin": {
|
|
34
|
-
"create-lt-adventure": "./dist/bin.js"
|
|
35
|
-
},
|
|
36
|
-
"files": [
|
|
37
|
-
"dist/",
|
|
38
|
-
"templates/",
|
|
39
|
-
"addons/",
|
|
40
|
-
"LICENSE",
|
|
41
|
-
"README.md"
|
|
42
|
-
],
|
|
43
|
-
"scripts": {
|
|
44
|
-
"create": "bun src/bin.ts",
|
|
45
|
-
"build": "tsc",
|
|
46
|
-
"build:watch": "tsc --watch",
|
|
47
|
-
"prepublishOnly": "npm run build",
|
|
48
|
-
"prepack": "npm run build",
|
|
49
|
-
"dev": "bun src/bin.ts \"My New Module\" --auto-id"
|
|
50
|
-
},
|
|
51
|
-
"
|
|
52
|
-
"
|
|
53
|
-
"
|
|
54
|
-
"@
|
|
55
|
-
"@
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
"
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "create-lt-adventure",
|
|
3
|
+
"version": "0.1.3",
|
|
4
|
+
"description": "A CLI tool to scaffold Foundry VTT modules",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"foundry-vtt",
|
|
7
|
+
"module",
|
|
8
|
+
"scaffold",
|
|
9
|
+
"cli"
|
|
10
|
+
],
|
|
11
|
+
"license": "MIT",
|
|
12
|
+
"author": "mrvauxs",
|
|
13
|
+
"repository": {
|
|
14
|
+
"type": "git",
|
|
15
|
+
"url": "https://github.com/Loot-Foundry/create-lt-adventure"
|
|
16
|
+
},
|
|
17
|
+
"homepage": "https://github.com/Loot-Foundry/create-lt-adventure#readme",
|
|
18
|
+
"bugs": {
|
|
19
|
+
"url": "https://github.com/Loot-Foundry/create-lt-adventure/issues"
|
|
20
|
+
},
|
|
21
|
+
"type": "module",
|
|
22
|
+
"main": "./dist/index.js",
|
|
23
|
+
"exports": {
|
|
24
|
+
".": {
|
|
25
|
+
"import": "./dist/index.js",
|
|
26
|
+
"types": "./dist/index.d.ts"
|
|
27
|
+
},
|
|
28
|
+
"./bin": {
|
|
29
|
+
"import": "./dist/bin.js",
|
|
30
|
+
"types": "./dist/bin.d.ts"
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"bin": {
|
|
34
|
+
"create-lt-adventure": "./dist/bin.js"
|
|
35
|
+
},
|
|
36
|
+
"files": [
|
|
37
|
+
"dist/",
|
|
38
|
+
"templates/",
|
|
39
|
+
"addons/",
|
|
40
|
+
"LICENSE",
|
|
41
|
+
"README.md"
|
|
42
|
+
],
|
|
43
|
+
"scripts": {
|
|
44
|
+
"create": "bun src/bin.ts",
|
|
45
|
+
"build": "tsc",
|
|
46
|
+
"build:watch": "tsc --watch",
|
|
47
|
+
"prepublishOnly": "npm run build",
|
|
48
|
+
"prepack": "npm run build",
|
|
49
|
+
"dev": "bun src/bin.ts \"My New Module\" --auto-id"
|
|
50
|
+
},
|
|
51
|
+
"dependencies": {
|
|
52
|
+
"kolorist": "^1.8.0",
|
|
53
|
+
"adm-zip": "^0.5.16",
|
|
54
|
+
"@foundryvtt/foundryvtt-cli": "^1.0.0",
|
|
55
|
+
"@clack/prompts": "^1.0.0-alpha.9"
|
|
56
|
+
},
|
|
57
|
+
"devDependencies": {
|
|
58
|
+
"@types/adm-zip": "^0.5.7",
|
|
59
|
+
"@types/node": "^20.19.39",
|
|
60
|
+
"typescript": "^5"
|
|
61
|
+
},
|
|
62
|
+
"peerDependencies": {
|
|
63
|
+
"typescript": "^5"
|
|
64
|
+
},
|
|
65
|
+
"engines": {
|
|
66
|
+
"node": ">=18.0.0"
|
|
67
|
+
}
|
|
68
|
+
}
|