@opys/curseforge 0.1.2

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/dist/index.cjs ADDED
@@ -0,0 +1,110 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
+ let _opys_dev = require("@opys/dev");
3
+ let _opys_core = require("@opys/core");
4
+
5
+ //#region lib/template.ts
6
+ const CURSEFORGE_API = "https://api.curseforge.com/v1";
7
+ const FILES_BATCH_SIZE = 200;
8
+ /** Fallback CDN URL used when CurseForge omits `downloadUrl`. */
9
+ function forgeCdnUrl(fileId, fileName) {
10
+ return `https://edge.forgecdn.net/files/${Math.floor(fileId / 1e3)}/${fileId % 1e3}/${encodeURIComponent(fileName)}`;
11
+ }
12
+ function pickSha1(file) {
13
+ return file.hashes.find((h) => h.algo === 1)?.value;
14
+ }
15
+ /**
16
+ * Coerce a `CurseForgeFileRef` into a numeric file ID. Numbers pass through;
17
+ * strings must contain a `/files/<digits>` segment (the standard CurseForge
18
+ * file URL shape).
19
+ */
20
+ function parseFileRef(ref) {
21
+ if (typeof ref === "number") return ref;
22
+ const match = ref.match(/\/files\/(\d+)/);
23
+ if (!match) throw new Error(`CurseForge file ref "${ref}" does not contain "/files/<id>" — expected a numeric ID or a CurseForge file URL.`);
24
+ return Number(match[1]);
25
+ }
26
+ async function fetchFiles(token, fileIds) {
27
+ const out = [];
28
+ for (let i = 0; i < fileIds.length; i += FILES_BATCH_SIZE) {
29
+ const batch = fileIds.slice(i, i + FILES_BATCH_SIZE);
30
+ const res = await (0, _opys_core.fetchWithRetry)(`${CURSEFORGE_API}/mods/files`, {
31
+ method: "POST",
32
+ headers: {
33
+ "x-api-key": token,
34
+ accept: "application/json",
35
+ "content-type": "application/json"
36
+ },
37
+ body: JSON.stringify({ fileIds: batch })
38
+ });
39
+ if (!res.ok) throw new Error(`CurseForge API ${res.status}: ${res.statusText} (POST /mods/files)`);
40
+ const json = await res.json();
41
+ out.push(...json.data);
42
+ }
43
+ return out;
44
+ }
45
+ /**
46
+ * Resolve CurseForge file refs into opys `Artifact`s sharing one install
47
+ * path. Call multiple times for different destinations (mods,
48
+ * resourcepacks, shaderpacks, …) and drop each result straight into your
49
+ * manifest's `artifacts` list.
50
+ *
51
+ * ```ts
52
+ * const mods = await resolveCurseforge(
53
+ * {
54
+ * path: (info) => '${game_directory}/mods/' + info.filename,
55
+ * token: process.env.CURSEFORGE_API_KEY,
56
+ * },
57
+ * [
58
+ * 6307712,
59
+ * 'https://www.curseforge.com/minecraft/mc-mods/botania/files/2283837',
60
+ * ],
61
+ * );
62
+ * // mods: Artifact[]
63
+ * ```
64
+ */
65
+ async function resolveCurseforge(options, files) {
66
+ const ids = files.map(parseFileRef);
67
+ const meta = await fetchFiles(options.token, ids);
68
+ const byId = new Map(meta.map((m) => [m.id, m]));
69
+ const artifacts = [];
70
+ for (const fileId of ids) {
71
+ const file = byId.get(fileId);
72
+ if (!file) throw new Error(`CurseForge API did not return metadata for file ${fileId}`);
73
+ const path = options.path({
74
+ filename: file.fileName,
75
+ fileId: file.id,
76
+ projectId: file.modId,
77
+ size: file.fileLength
78
+ });
79
+ const url = file.downloadUrl ?? forgeCdnUrl(file.id, file.fileName);
80
+ const sha1 = pickSha1(file);
81
+ const integrity = sha1 ? { sha1 } : void 0;
82
+ artifacts.push({
83
+ path,
84
+ source: (0, _opys_core.sourceUrl)(url),
85
+ size: file.fileLength,
86
+ rules: [],
87
+ integrity
88
+ });
89
+ }
90
+ return artifacts;
91
+ }
92
+
93
+ //#endregion
94
+ //#region lib/plugin.ts
95
+ /** Mod files resolved from the CurseForge API. */
96
+ function curseforge(options) {
97
+ return (0, _opys_dev.definePlugin)({
98
+ name: "curseforge",
99
+ async build(ctx) {
100
+ const { files, ...rest } = options;
101
+ const artifacts = await resolveCurseforge(rest, files);
102
+ ctx.log("curseforge", `${artifacts.length} file(s)`);
103
+ return { artifacts };
104
+ }
105
+ });
106
+ }
107
+
108
+ //#endregion
109
+ exports.curseforge = curseforge;
110
+ exports.resolveCurseforge = resolveCurseforge;
@@ -0,0 +1,71 @@
1
+ import { OpysPlugin } from "@opys/dev";
2
+ import { Artifact } from "@opys/core";
3
+
4
+ //#region lib/template.d.ts
5
+ /** Info passed to the `path` callback. */
6
+ interface CurseForgeFileInfo {
7
+ /** Original filename as published on CurseForge, e.g. `jei-1.20.1-forge-15.21.1.5.jar`. */
8
+ filename: string;
9
+ /** CurseForge file ID. */
10
+ fileId: number;
11
+ /** CurseForge project (mod) ID. */
12
+ projectId: number;
13
+ /** File size in bytes. */
14
+ size: number;
15
+ }
16
+ type CurseForgePath = (info: CurseForgeFileInfo) => string;
17
+ /**
18
+ * A CurseForge file reference. Either a numeric file ID, or the file's
19
+ * CurseForge URL (`https://www.curseforge.com/<...>/files/<id>`) — the
20
+ * trailing numeric segment is parsed out so configs can paste links
21
+ * verbatim.
22
+ */
23
+ type CurseForgeFileRef = number | string;
24
+ interface CurseForgeOptions {
25
+ /**
26
+ * Install path callback, invoked once per file. May return a string
27
+ * containing opys install-time vars like `${root}` or
28
+ * `${game_directory}` — they get interpolated at install time.
29
+ */
30
+ path: CurseForgePath;
31
+ /**
32
+ * CurseForge API key (https://console.curseforge.com/#/api-keys).
33
+ * Consumed only at build time — the artifact URLs are public CDN
34
+ * links, so end users running `opys launch` against a built manifest
35
+ * do not need a key.
36
+ */
37
+ token: string;
38
+ }
39
+ /**
40
+ * Resolve CurseForge file refs into opys `Artifact`s sharing one install
41
+ * path. Call multiple times for different destinations (mods,
42
+ * resourcepacks, shaderpacks, …) and drop each result straight into your
43
+ * manifest's `artifacts` list.
44
+ *
45
+ * ```ts
46
+ * const mods = await resolveCurseforge(
47
+ * {
48
+ * path: (info) => '${game_directory}/mods/' + info.filename,
49
+ * token: process.env.CURSEFORGE_API_KEY,
50
+ * },
51
+ * [
52
+ * 6307712,
53
+ * 'https://www.curseforge.com/minecraft/mc-mods/botania/files/2283837',
54
+ * ],
55
+ * );
56
+ * // mods: Artifact[]
57
+ * ```
58
+ */
59
+ declare function resolveCurseforge(options: CurseForgeOptions, files: CurseForgeFileRef[]): Promise<Artifact[]>;
60
+ //#endregion
61
+ //#region lib/plugin.d.ts
62
+ /** Options for the {@link curseforge} plugin. */
63
+ interface CurseforgePluginOptions extends CurseForgeOptions {
64
+ /** CurseForge file references — numeric IDs or `/files/<id>` URLs. */
65
+ files: CurseForgeFileRef[];
66
+ }
67
+ /** Mod files resolved from the CurseForge API. */
68
+ declare function curseforge(options: CurseforgePluginOptions): OpysPlugin;
69
+ //#endregion
70
+ export { type CurseForgeFileInfo, type CurseForgeFileRef, type CurseForgeOptions, type CurseForgePath, type CurseforgePluginOptions, curseforge, resolveCurseforge };
71
+ //# sourceMappingURL=index.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../lib/template.ts","../lib/plugin.ts"],"mappings":";;;;;UAiBiB,kBAAA;;EAEf,QAAA;EAFiC;EAIjC,MAAA;EAJiC;EAMjC,SAAA;EAFA;EAIA,IAAA;AAAA;AAAA,KAGU,cAAA,IAAkB,IAAA,EAAM,kBAAA;;AAApC;;;;;KAQY,iBAAA;AAAA,UAEK,iBAAA;;;;AAAjB;;EAME,IAAA,EAAM,cAAA;EAAc;;;;;;EAOpB,KAAA;AAAA;;;;;;;;;;;;;;;;;;;AC3CF;;iBDqHsB,iBAAA,CACpB,OAAA,EAAS,iBAAA,EACT,KAAA,EAAO,iBAAA,KACN,OAAA,CAAQ,QAAA;;;;UCxHM,uBAAA,SAAgC,iBAAA;EDShC;ECPf,KAAA,EAAO,iBAAA;AAAA;;iBAIO,UAAA,CAAW,OAAA,EAAS,uBAAA,GAA0B,UAAA"}
@@ -0,0 +1,71 @@
1
+ import { OpysPlugin } from "@opys/dev";
2
+ import { Artifact } from "@opys/core";
3
+
4
+ //#region lib/template.d.ts
5
+ /** Info passed to the `path` callback. */
6
+ interface CurseForgeFileInfo {
7
+ /** Original filename as published on CurseForge, e.g. `jei-1.20.1-forge-15.21.1.5.jar`. */
8
+ filename: string;
9
+ /** CurseForge file ID. */
10
+ fileId: number;
11
+ /** CurseForge project (mod) ID. */
12
+ projectId: number;
13
+ /** File size in bytes. */
14
+ size: number;
15
+ }
16
+ type CurseForgePath = (info: CurseForgeFileInfo) => string;
17
+ /**
18
+ * A CurseForge file reference. Either a numeric file ID, or the file's
19
+ * CurseForge URL (`https://www.curseforge.com/<...>/files/<id>`) — the
20
+ * trailing numeric segment is parsed out so configs can paste links
21
+ * verbatim.
22
+ */
23
+ type CurseForgeFileRef = number | string;
24
+ interface CurseForgeOptions {
25
+ /**
26
+ * Install path callback, invoked once per file. May return a string
27
+ * containing opys install-time vars like `${root}` or
28
+ * `${game_directory}` — they get interpolated at install time.
29
+ */
30
+ path: CurseForgePath;
31
+ /**
32
+ * CurseForge API key (https://console.curseforge.com/#/api-keys).
33
+ * Consumed only at build time — the artifact URLs are public CDN
34
+ * links, so end users running `opys launch` against a built manifest
35
+ * do not need a key.
36
+ */
37
+ token: string;
38
+ }
39
+ /**
40
+ * Resolve CurseForge file refs into opys `Artifact`s sharing one install
41
+ * path. Call multiple times for different destinations (mods,
42
+ * resourcepacks, shaderpacks, …) and drop each result straight into your
43
+ * manifest's `artifacts` list.
44
+ *
45
+ * ```ts
46
+ * const mods = await resolveCurseforge(
47
+ * {
48
+ * path: (info) => '${game_directory}/mods/' + info.filename,
49
+ * token: process.env.CURSEFORGE_API_KEY,
50
+ * },
51
+ * [
52
+ * 6307712,
53
+ * 'https://www.curseforge.com/minecraft/mc-mods/botania/files/2283837',
54
+ * ],
55
+ * );
56
+ * // mods: Artifact[]
57
+ * ```
58
+ */
59
+ declare function resolveCurseforge(options: CurseForgeOptions, files: CurseForgeFileRef[]): Promise<Artifact[]>;
60
+ //#endregion
61
+ //#region lib/plugin.d.ts
62
+ /** Options for the {@link curseforge} plugin. */
63
+ interface CurseforgePluginOptions extends CurseForgeOptions {
64
+ /** CurseForge file references — numeric IDs or `/files/<id>` URLs. */
65
+ files: CurseForgeFileRef[];
66
+ }
67
+ /** Mod files resolved from the CurseForge API. */
68
+ declare function curseforge(options: CurseforgePluginOptions): OpysPlugin;
69
+ //#endregion
70
+ export { type CurseForgeFileInfo, type CurseForgeFileRef, type CurseForgeOptions, type CurseForgePath, type CurseforgePluginOptions, curseforge, resolveCurseforge };
71
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../lib/template.ts","../lib/plugin.ts"],"mappings":";;;;;UAiBiB,kBAAA;;EAEf,QAAA;EAFiC;EAIjC,MAAA;EAJiC;EAMjC,SAAA;EAFA;EAIA,IAAA;AAAA;AAAA,KAGU,cAAA,IAAkB,IAAA,EAAM,kBAAA;;AAApC;;;;;KAQY,iBAAA;AAAA,UAEK,iBAAA;;;;AAAjB;;EAME,IAAA,EAAM,cAAA;EAAc;;;;;;EAOpB,KAAA;AAAA;;;;;;;;;;;;;;;;;;;AC3CF;;iBDqHsB,iBAAA,CACpB,OAAA,EAAS,iBAAA,EACT,KAAA,EAAO,iBAAA,KACN,OAAA,CAAQ,QAAA;;;;UCxHM,uBAAA,SAAgC,iBAAA;EDShC;ECPf,KAAA,EAAO,iBAAA;AAAA;;iBAIO,UAAA,CAAW,OAAA,EAAS,uBAAA,GAA0B,UAAA"}
package/dist/index.mjs ADDED
@@ -0,0 +1,109 @@
1
+ import { definePlugin } from "@opys/dev";
2
+ import { fetchWithRetry, sourceUrl } from "@opys/core";
3
+
4
+ //#region lib/template.ts
5
+ const CURSEFORGE_API = "https://api.curseforge.com/v1";
6
+ const FILES_BATCH_SIZE = 200;
7
+ /** Fallback CDN URL used when CurseForge omits `downloadUrl`. */
8
+ function forgeCdnUrl(fileId, fileName) {
9
+ return `https://edge.forgecdn.net/files/${Math.floor(fileId / 1e3)}/${fileId % 1e3}/${encodeURIComponent(fileName)}`;
10
+ }
11
+ function pickSha1(file) {
12
+ return file.hashes.find((h) => h.algo === 1)?.value;
13
+ }
14
+ /**
15
+ * Coerce a `CurseForgeFileRef` into a numeric file ID. Numbers pass through;
16
+ * strings must contain a `/files/<digits>` segment (the standard CurseForge
17
+ * file URL shape).
18
+ */
19
+ function parseFileRef(ref) {
20
+ if (typeof ref === "number") return ref;
21
+ const match = ref.match(/\/files\/(\d+)/);
22
+ if (!match) throw new Error(`CurseForge file ref "${ref}" does not contain "/files/<id>" — expected a numeric ID or a CurseForge file URL.`);
23
+ return Number(match[1]);
24
+ }
25
+ async function fetchFiles(token, fileIds) {
26
+ const out = [];
27
+ for (let i = 0; i < fileIds.length; i += FILES_BATCH_SIZE) {
28
+ const batch = fileIds.slice(i, i + FILES_BATCH_SIZE);
29
+ const res = await fetchWithRetry(`${CURSEFORGE_API}/mods/files`, {
30
+ method: "POST",
31
+ headers: {
32
+ "x-api-key": token,
33
+ accept: "application/json",
34
+ "content-type": "application/json"
35
+ },
36
+ body: JSON.stringify({ fileIds: batch })
37
+ });
38
+ if (!res.ok) throw new Error(`CurseForge API ${res.status}: ${res.statusText} (POST /mods/files)`);
39
+ const json = await res.json();
40
+ out.push(...json.data);
41
+ }
42
+ return out;
43
+ }
44
+ /**
45
+ * Resolve CurseForge file refs into opys `Artifact`s sharing one install
46
+ * path. Call multiple times for different destinations (mods,
47
+ * resourcepacks, shaderpacks, …) and drop each result straight into your
48
+ * manifest's `artifacts` list.
49
+ *
50
+ * ```ts
51
+ * const mods = await resolveCurseforge(
52
+ * {
53
+ * path: (info) => '${game_directory}/mods/' + info.filename,
54
+ * token: process.env.CURSEFORGE_API_KEY,
55
+ * },
56
+ * [
57
+ * 6307712,
58
+ * 'https://www.curseforge.com/minecraft/mc-mods/botania/files/2283837',
59
+ * ],
60
+ * );
61
+ * // mods: Artifact[]
62
+ * ```
63
+ */
64
+ async function resolveCurseforge(options, files) {
65
+ const ids = files.map(parseFileRef);
66
+ const meta = await fetchFiles(options.token, ids);
67
+ const byId = new Map(meta.map((m) => [m.id, m]));
68
+ const artifacts = [];
69
+ for (const fileId of ids) {
70
+ const file = byId.get(fileId);
71
+ if (!file) throw new Error(`CurseForge API did not return metadata for file ${fileId}`);
72
+ const path = options.path({
73
+ filename: file.fileName,
74
+ fileId: file.id,
75
+ projectId: file.modId,
76
+ size: file.fileLength
77
+ });
78
+ const url = file.downloadUrl ?? forgeCdnUrl(file.id, file.fileName);
79
+ const sha1 = pickSha1(file);
80
+ const integrity = sha1 ? { sha1 } : void 0;
81
+ artifacts.push({
82
+ path,
83
+ source: sourceUrl(url),
84
+ size: file.fileLength,
85
+ rules: [],
86
+ integrity
87
+ });
88
+ }
89
+ return artifacts;
90
+ }
91
+
92
+ //#endregion
93
+ //#region lib/plugin.ts
94
+ /** Mod files resolved from the CurseForge API. */
95
+ function curseforge(options) {
96
+ return definePlugin({
97
+ name: "curseforge",
98
+ async build(ctx) {
99
+ const { files, ...rest } = options;
100
+ const artifacts = await resolveCurseforge(rest, files);
101
+ ctx.log("curseforge", `${artifacts.length} file(s)`);
102
+ return { artifacts };
103
+ }
104
+ });
105
+ }
106
+
107
+ //#endregion
108
+ export { curseforge, resolveCurseforge };
109
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../lib/template.ts","../lib/plugin.ts"],"sourcesContent":["import type { Artifact, HashEntry } from '@opys/core';\nimport { sourceUrl, fetchWithRetry } from '@opys/core';\n\nconst CURSEFORGE_API = 'https://api.curseforge.com/v1';\nconst FILES_BATCH_SIZE = 200;\n\n/** CurseForge file metadata returned by the v1 API. */\ninterface CFFile {\n id: number;\n modId: number;\n fileName: string;\n fileLength: number;\n hashes: { value: string; algo: number }[];\n downloadUrl: string | null;\n}\n\n/** Info passed to the `path` callback. */\nexport interface CurseForgeFileInfo {\n /** Original filename as published on CurseForge, e.g. `jei-1.20.1-forge-15.21.1.5.jar`. */\n filename: string;\n /** CurseForge file ID. */\n fileId: number;\n /** CurseForge project (mod) ID. */\n projectId: number;\n /** File size in bytes. */\n size: number;\n}\n\nexport type CurseForgePath = (info: CurseForgeFileInfo) => string;\n\n/**\n * A CurseForge file reference. Either a numeric file ID, or the file's\n * CurseForge URL (`https://www.curseforge.com/<...>/files/<id>`) — the\n * trailing numeric segment is parsed out so configs can paste links\n * verbatim.\n */\nexport type CurseForgeFileRef = number | string;\n\nexport interface CurseForgeOptions {\n /**\n * Install path callback, invoked once per file. May return a string\n * containing opys install-time vars like `${root}` or\n * `${game_directory}` — they get interpolated at install time.\n */\n path: CurseForgePath;\n /**\n * CurseForge API key (https://console.curseforge.com/#/api-keys).\n * Consumed only at build time — the artifact URLs are public CDN\n * links, so end users running `opys launch` against a built manifest\n * do not need a key.\n */\n token: string;\n}\n\n/** Fallback CDN URL used when CurseForge omits `downloadUrl`. */\nfunction forgeCdnUrl(fileId: number, fileName: string): string {\n const head = Math.floor(fileId / 1000);\n const tail = fileId % 1000;\n return `https://edge.forgecdn.net/files/${head}/${tail}/${encodeURIComponent(fileName)}`;\n}\n\nfunction pickSha1(file: CFFile): string | undefined {\n return file.hashes.find((h) => h.algo === 1)?.value;\n}\n\n/**\n * Coerce a `CurseForgeFileRef` into a numeric file ID. Numbers pass through;\n * strings must contain a `/files/<digits>` segment (the standard CurseForge\n * file URL shape).\n */\nfunction parseFileRef(ref: CurseForgeFileRef): number {\n if (typeof ref === 'number') return ref;\n const match = ref.match(/\\/files\\/(\\d+)/);\n if (!match) {\n throw new Error(\n `CurseForge file ref \"${ref}\" does not contain \"/files/<id>\" — expected a numeric ID or a CurseForge file URL.`,\n );\n }\n return Number(match[1]);\n}\n\nasync function fetchFiles(token: string, fileIds: number[]): Promise<CFFile[]> {\n const out: CFFile[] = [];\n for (let i = 0; i < fileIds.length; i += FILES_BATCH_SIZE) {\n const batch = fileIds.slice(i, i + FILES_BATCH_SIZE);\n const res = await fetchWithRetry(`${CURSEFORGE_API}/mods/files`, {\n method: 'POST',\n headers: {\n 'x-api-key': token,\n accept: 'application/json',\n 'content-type': 'application/json',\n },\n body: JSON.stringify({ fileIds: batch }),\n });\n if (!res.ok) {\n throw new Error(\n `CurseForge API ${res.status}: ${res.statusText} (POST /mods/files)`,\n );\n }\n const json = (await res.json()) as { data: CFFile[] };\n out.push(...json.data);\n }\n return out;\n}\n\n/**\n * Resolve CurseForge file refs into opys `Artifact`s sharing one install\n * path. Call multiple times for different destinations (mods,\n * resourcepacks, shaderpacks, …) and drop each result straight into your\n * manifest's `artifacts` list.\n *\n * ```ts\n * const mods = await resolveCurseforge(\n * {\n * path: (info) => '${game_directory}/mods/' + info.filename,\n * token: process.env.CURSEFORGE_API_KEY,\n * },\n * [\n * 6307712,\n * 'https://www.curseforge.com/minecraft/mc-mods/botania/files/2283837',\n * ],\n * );\n * // mods: Artifact[]\n * ```\n */\nexport async function resolveCurseforge(\n options: CurseForgeOptions,\n files: CurseForgeFileRef[],\n): Promise<Artifact[]> {\n const ids = files.map(parseFileRef);\n const meta = await fetchFiles(options.token, ids);\n const byId = new Map(meta.map((m) => [m.id, m]));\n\n const artifacts: Artifact[] = [];\n for (const fileId of ids) {\n const file = byId.get(fileId);\n if (!file) {\n throw new Error(\n `CurseForge API did not return metadata for file ${fileId}`,\n );\n }\n\n const path = options.path({\n filename: file.fileName,\n fileId: file.id,\n projectId: file.modId,\n size: file.fileLength,\n });\n\n const url = file.downloadUrl ?? forgeCdnUrl(file.id, file.fileName);\n const sha1 = pickSha1(file);\n const integrity: HashEntry | undefined = sha1 ? { sha1 } : undefined;\n\n artifacts.push({\n path,\n source: sourceUrl(url),\n size: file.fileLength,\n rules: [],\n integrity,\n });\n }\n\n return artifacts;\n}\n","import { definePlugin, type OpysPlugin } from '@opys/dev';\nimport {\n resolveCurseforge,\n type CurseForgeOptions,\n type CurseForgeFileRef,\n} from './template';\n\n/** Options for the {@link curseforge} plugin. */\nexport interface CurseforgePluginOptions extends CurseForgeOptions {\n /** CurseForge file references — numeric IDs or `/files/<id>` URLs. */\n files: CurseForgeFileRef[];\n}\n\n/** Mod files resolved from the CurseForge API. */\nexport function curseforge(options: CurseforgePluginOptions): OpysPlugin {\n return definePlugin({\n name: 'curseforge',\n async build(ctx) {\n const { files, ...rest } = options;\n const artifacts = await resolveCurseforge(rest, files);\n ctx.log('curseforge', `${artifacts.length} file(s)`);\n return { artifacts };\n },\n });\n}\n"],"mappings":";;;;AAGA,MAAM,iBAAiB;AACvB,MAAM,mBAAmB;;AAmDzB,SAAS,YAAY,QAAgB,UAA0B;AAG7D,QAAO,mCAFM,KAAK,MAAM,SAAS,IAAK,CAES,GADlC,SAAS,IACiC,GAAG,mBAAmB,SAAS;;AAGxF,SAAS,SAAS,MAAkC;AAClD,QAAO,KAAK,OAAO,MAAM,MAAM,EAAE,SAAS,EAAE,EAAE;;;;;;;AAQhD,SAAS,aAAa,KAAgC;AACpD,KAAI,OAAO,QAAQ,SAAU,QAAO;CACpC,MAAM,QAAQ,IAAI,MAAM,iBAAiB;AACzC,KAAI,CAAC,MACH,OAAM,IAAI,MACR,wBAAwB,IAAI,oFAC7B;AAEH,QAAO,OAAO,MAAM,GAAG;;AAGzB,eAAe,WAAW,OAAe,SAAsC;CAC7E,MAAM,MAAgB,EAAE;AACxB,MAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK,kBAAkB;EACzD,MAAM,QAAQ,QAAQ,MAAM,GAAG,IAAI,iBAAiB;EACpD,MAAM,MAAM,MAAM,eAAe,GAAG,eAAe,cAAc;GAC/D,QAAQ;GACR,SAAS;IACP,aAAa;IACb,QAAQ;IACR,gBAAgB;IACjB;GACD,MAAM,KAAK,UAAU,EAAE,SAAS,OAAO,CAAC;GACzC,CAAC;AACF,MAAI,CAAC,IAAI,GACP,OAAM,IAAI,MACR,kBAAkB,IAAI,OAAO,IAAI,IAAI,WAAW,qBACjD;EAEH,MAAM,OAAQ,MAAM,IAAI,MAAM;AAC9B,MAAI,KAAK,GAAG,KAAK,KAAK;;AAExB,QAAO;;;;;;;;;;;;;;;;;;;;;;AAuBT,eAAsB,kBACpB,SACA,OACqB;CACrB,MAAM,MAAM,MAAM,IAAI,aAAa;CACnC,MAAM,OAAO,MAAM,WAAW,QAAQ,OAAO,IAAI;CACjD,MAAM,OAAO,IAAI,IAAI,KAAK,KAAK,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;CAEhD,MAAM,YAAwB,EAAE;AAChC,MAAK,MAAM,UAAU,KAAK;EACxB,MAAM,OAAO,KAAK,IAAI,OAAO;AAC7B,MAAI,CAAC,KACH,OAAM,IAAI,MACR,mDAAmD,SACpD;EAGH,MAAM,OAAO,QAAQ,KAAK;GACxB,UAAU,KAAK;GACf,QAAQ,KAAK;GACb,WAAW,KAAK;GAChB,MAAM,KAAK;GACZ,CAAC;EAEF,MAAM,MAAM,KAAK,eAAe,YAAY,KAAK,IAAI,KAAK,SAAS;EACnE,MAAM,OAAO,SAAS,KAAK;EAC3B,MAAM,YAAmC,OAAO,EAAE,MAAM,GAAG;AAE3D,YAAU,KAAK;GACb;GACA,QAAQ,UAAU,IAAI;GACtB,MAAM,KAAK;GACX,OAAO,EAAE;GACT;GACD,CAAC;;AAGJ,QAAO;;;;;;ACpJT,SAAgB,WAAW,SAA8C;AACvE,QAAO,aAAa;EAClB,MAAM;EACN,MAAM,MAAM,KAAK;GACf,MAAM,EAAE,OAAO,GAAG,SAAS;GAC3B,MAAM,YAAY,MAAM,kBAAkB,MAAM,MAAM;AACtD,OAAI,IAAI,cAAc,GAAG,UAAU,OAAO,UAAU;AACpD,UAAO,EAAE,WAAW;;EAEvB,CAAC"}
package/package.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "@opys/curseforge",
3
+ "version": "0.1.2",
4
+ "type": "module",
5
+ "main": "./dist/index.js",
6
+ "exports": {
7
+ ".": {
8
+ "import": "./dist/index.mjs",
9
+ "require": "./dist/index.cjs"
10
+ }
11
+ },
12
+ "scripts": {
13
+ "build": "tsdown lib/index.ts --format esm,cjs --dts --clean",
14
+ "typecheck": "tsc --noEmit -p tsconfig.json",
15
+ "test": "vitest run tests/unit --passWithNoTests"
16
+ },
17
+ "dependencies": {
18
+ "@opys/core": "^0.1.2",
19
+ "@opys/dev": "^0.1.2"
20
+ },
21
+ "devDependencies": {
22
+ "tsdown": "*",
23
+ "vitest": "*"
24
+ },
25
+ "files": [
26
+ "dist"
27
+ ],
28
+ "engines": {
29
+ "node": ">=20"
30
+ },
31
+ "repository": {
32
+ "type": "git",
33
+ "url": "git+https://github.com/harmoniya-net/opys.git",
34
+ "directory": "packages/curseforge"
35
+ }
36
+ }