create-lt-adventure 0.1.0 → 0.1.4

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 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.0",
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/MrVauxs/create-lt-adventure"
16
- },
17
- "homepage": "https://github.com/MrVauxs/create-lt-adventure#readme",
18
- "bugs": {
19
- "url": "https://github.com/MrVauxs/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
- "devDependencies": {
52
- "@clack/prompts": "^1.0.0-alpha.9",
53
- "@foundryvtt/foundryvtt-cli": "^1.0.0",
54
- "@types/adm-zip": "^0.5.7",
55
- "@types/node": "^20.19.39",
56
- "adm-zip": "^0.5.16",
57
- "kolorist": "^1.8.0",
58
- "typescript": "^5"
59
- },
60
- "peerDependencies": {
61
- "typescript": "^5"
62
- },
63
- "engines": {
64
- "node": ">=18.0.0"
65
- }
66
- }
1
+ {
2
+ "name": "create-lt-adventure",
3
+ "version": "0.1.4",
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
+ }
@@ -1,7 +1,7 @@
1
1
  import type { Plugin, UserConfig } from "vite";
2
2
  import fs from "node:fs";
3
3
  import path from "node:path";
4
- import vttSync from "foundryvtt-sync";
4
+ import vttSync from "foundryvtt-sync/vite";
5
5
  import postcssPresetEnv from "postcss-preset-env";
6
6
  import PostCSSReplace from "postcss-replace";
7
7
  import { defineConfig } from "vite";
@@ -114,13 +114,13 @@ export default defineConfig(({ mode: _mode }) => {
114
114
  apply: 'serve',
115
115
  configureServer(server) {
116
116
  server.middlewares.use((req, res, next) => {
117
- const cssPath = `/${PACKAGE_ID}/dist/${moduleJSON.id}.css`;
118
- if (req.url === cssPath) {
119
- res.setHeader('Content-Type', 'text/css');
120
- res.end('');
121
- return;
122
- }
123
- next();
117
+ const cssPath = `/${PACKAGE_ID}/dist/${moduleJSON.id}.css`;
118
+ if (req.url === cssPath) {
119
+ res.setHeader('Content-Type', 'text/css');
120
+ res.end('');
121
+ return;
122
+ }
123
+ next();
124
124
  });
125
125
  },
126
126
  },