@px-lsp/protocol 0.2.0 → 0.2.1
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/calendar.d.ts +15 -13
- package/dist/calendar.js +26 -27
- package/dist/calendarFile.d.ts +26 -0
- package/dist/calendarFile.js +109 -0
- package/dist/calendarLoc.js +7 -11
- package/dist/configDir.d.ts +17 -0
- package/dist/configDir.js +79 -0
- package/dist/protocol.d.ts +481 -0
- package/dist/protocol.js +123 -1
- package/dist/workshopMeta.d.ts +3 -5
- package/dist/workshopMeta.js +6 -11
- package/package.json +1 -1
- package/src/calendar.ts +34 -35
- package/src/calendarFile.ts +81 -0
- package/src/calendarLoc.ts +7 -14
- package/src/configDir.ts +47 -0
- package/src/protocol.ts +487 -0
- package/src/workshopMeta.ts +6 -11
package/dist/calendar.d.ts
CHANGED
|
@@ -10,12 +10,6 @@
|
|
|
10
10
|
* hover) and the extension (the Insert Date command), unit-tested in plain
|
|
11
11
|
* Node.
|
|
12
12
|
*/
|
|
13
|
-
export interface CalendarMonth {
|
|
14
|
-
/** Display name ("March", "Narvinye"). */
|
|
15
|
-
name: string;
|
|
16
|
-
/** Day count; the engine has no leap years, so one number per month. */
|
|
17
|
-
days: number;
|
|
18
|
-
}
|
|
19
13
|
export interface CalendarSetting {
|
|
20
14
|
/** Script year displayed as year 1 of the `after` era (no year zero). */
|
|
21
15
|
epoch: number;
|
|
@@ -24,12 +18,20 @@ export interface CalendarSetting {
|
|
|
24
18
|
/** Era label for script years < epoch ("BC"). Omitted = single-era
|
|
25
19
|
* calendar: years before the epoch get no display form. */
|
|
26
20
|
before?: string;
|
|
27
|
-
/**
|
|
28
|
-
*
|
|
29
|
-
|
|
21
|
+
/**
|
|
22
|
+
* The engine's twelve months under the mod's own names, first month first.
|
|
23
|
+
* Omitted = January to December. Only the NAMES are the mod's: the game has
|
|
24
|
+
* twelve months of fixed length (31 28 31 30 31 30 31 31 30 31 30 31, no
|
|
25
|
+
* leap years) and no script can change that, so a date's month and day are
|
|
26
|
+
* always the engine's and only read differently.
|
|
27
|
+
*/
|
|
28
|
+
months?: string[];
|
|
30
29
|
}
|
|
31
|
-
|
|
32
|
-
export declare
|
|
30
|
+
/** Days per engine month; what a script date's day is bounded by. */
|
|
31
|
+
export declare const ENGINE_MONTH_DAYS: number[];
|
|
32
|
+
export declare const GREGORIAN_MONTHS: string[];
|
|
33
|
+
/** The month names a date reads with: the mod's twelve, or the engine's. */
|
|
34
|
+
export declare function monthNames(cal: CalendarSetting): string[];
|
|
33
35
|
/**
|
|
34
36
|
* Validate a calendar straight out of JSON settings (any client, any hand-
|
|
35
37
|
* edited settings file). Returns a clean copy, or undefined when the value is
|
|
@@ -42,8 +44,8 @@ export declare function parseScriptDate(text: string): {
|
|
|
42
44
|
m: number;
|
|
43
45
|
d: number;
|
|
44
46
|
} | null;
|
|
45
|
-
/**
|
|
46
|
-
export declare function isValidScriptDate(
|
|
47
|
+
/** A date the engine reads: a positive year, one of its twelve months, a day that month has. */
|
|
48
|
+
export declare function isValidScriptDate(y: number, m: number, d: number): boolean;
|
|
47
49
|
/** Era-mapped year: "1000 BC". Null for pre-epoch years of a single-era calendar. */
|
|
48
50
|
export declare function displayYear(cal: CalendarSetting, y: number): string | null;
|
|
49
51
|
/**
|
package/dist/calendar.js
CHANGED
|
@@ -12,15 +12,16 @@
|
|
|
12
12
|
* Node.
|
|
13
13
|
*/
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.GREGORIAN_MONTHS = void 0;
|
|
16
|
-
exports.
|
|
15
|
+
exports.GREGORIAN_MONTHS = exports.ENGINE_MONTH_DAYS = void 0;
|
|
16
|
+
exports.monthNames = monthNames;
|
|
17
17
|
exports.sanitizeCalendar = sanitizeCalendar;
|
|
18
18
|
exports.parseScriptDate = parseScriptDate;
|
|
19
19
|
exports.isValidScriptDate = isValidScriptDate;
|
|
20
20
|
exports.displayYear = displayYear;
|
|
21
21
|
exports.displayDate = displayDate;
|
|
22
22
|
exports.convertDisplayInput = convertDisplayInput;
|
|
23
|
-
|
|
23
|
+
/** Days per engine month; what a script date's day is bounded by. */
|
|
24
|
+
exports.ENGINE_MONTH_DAYS = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
|
|
24
25
|
exports.GREGORIAN_MONTHS = [
|
|
25
26
|
"January",
|
|
26
27
|
"February",
|
|
@@ -34,8 +35,9 @@ exports.GREGORIAN_MONTHS = [
|
|
|
34
35
|
"October",
|
|
35
36
|
"November",
|
|
36
37
|
"December",
|
|
37
|
-
]
|
|
38
|
-
|
|
38
|
+
];
|
|
39
|
+
/** The month names a date reads with: the mod's twelve, or the engine's. */
|
|
40
|
+
function monthNames(cal) {
|
|
39
41
|
return cal.months ?? exports.GREGORIAN_MONTHS;
|
|
40
42
|
}
|
|
41
43
|
/**
|
|
@@ -61,21 +63,22 @@ function sanitizeCalendar(raw) {
|
|
|
61
63
|
if (cal.before && cal.before.toLowerCase() === cal.after.toLowerCase())
|
|
62
64
|
return undefined;
|
|
63
65
|
if (Array.isArray(o.months) && o.months.length > 0) {
|
|
66
|
+
// Exactly the engine's twelve. A name may still arrive as the older
|
|
67
|
+
// `{ name, days }` object; its day count never meant anything to the
|
|
68
|
+
// game and is dropped.
|
|
69
|
+
if (o.months.length !== exports.GREGORIAN_MONTHS.length)
|
|
70
|
+
return undefined;
|
|
64
71
|
const months = [];
|
|
65
72
|
const seen = new Set();
|
|
66
73
|
for (const m of o.months) {
|
|
67
|
-
|
|
68
|
-
return undefined;
|
|
69
|
-
const { name, days } = m;
|
|
74
|
+
const name = typeof m === "string" ? m : (m?.name ?? null);
|
|
70
75
|
if (typeof name !== "string" || name.trim() === "")
|
|
71
76
|
return undefined;
|
|
72
|
-
if (typeof days !== "number" || !Number.isInteger(days) || days < 1 || days > 999)
|
|
73
|
-
return undefined;
|
|
74
77
|
const key = name.trim().toLowerCase();
|
|
75
78
|
if (seen.has(key))
|
|
76
79
|
return undefined;
|
|
77
80
|
seen.add(key);
|
|
78
|
-
months.push(
|
|
81
|
+
months.push(name.trim());
|
|
79
82
|
}
|
|
80
83
|
cal.months = months;
|
|
81
84
|
}
|
|
@@ -88,10 +91,9 @@ function parseScriptDate(text) {
|
|
|
88
91
|
return null;
|
|
89
92
|
return { y: Number(match[1]), m: Number(match[2]), d: Number(match[3]) };
|
|
90
93
|
}
|
|
91
|
-
/**
|
|
92
|
-
function isValidScriptDate(
|
|
93
|
-
|
|
94
|
-
return y >= 1 && m >= 1 && m <= months.length && d >= 1 && d <= months[m - 1].days;
|
|
94
|
+
/** A date the engine reads: a positive year, one of its twelve months, a day that month has. */
|
|
95
|
+
function isValidScriptDate(y, m, d) {
|
|
96
|
+
return y >= 1 && m >= 1 && m <= exports.ENGINE_MONTH_DAYS.length && d >= 1 && d <= exports.ENGINE_MONTH_DAYS[m - 1];
|
|
95
97
|
}
|
|
96
98
|
/** Era-mapped year: "1000 BC". Null for pre-epoch years of a single-era calendar. */
|
|
97
99
|
function displayYear(cal, y) {
|
|
@@ -105,25 +107,23 @@ function displayYear(cal, y) {
|
|
|
105
107
|
* date does not fit the calendar.
|
|
106
108
|
*/
|
|
107
109
|
function displayDate(cal, y, m, d) {
|
|
108
|
-
if (!isValidScriptDate(
|
|
110
|
+
if (!isValidScriptDate(y, m, d))
|
|
109
111
|
return null;
|
|
110
112
|
const year = displayYear(cal, y);
|
|
111
113
|
if (!year)
|
|
112
114
|
return null;
|
|
113
115
|
if (m === 1 && d === 1)
|
|
114
116
|
return year;
|
|
115
|
-
return `${d} ${
|
|
117
|
+
return `${d} ${monthNames(cal)[m - 1]} ${year}`;
|
|
116
118
|
}
|
|
117
119
|
/** Case-insensitive month lookup: exact name, else unique prefix. */
|
|
118
120
|
function monthByName(cal, text) {
|
|
119
121
|
const needle = text.toLowerCase();
|
|
120
|
-
const months =
|
|
121
|
-
const exact = months.findIndex((m) => m.
|
|
122
|
+
const months = monthNames(cal);
|
|
123
|
+
const exact = months.findIndex((m) => m.toLowerCase() === needle);
|
|
122
124
|
if (exact >= 0)
|
|
123
125
|
return exact + 1;
|
|
124
|
-
const prefixed = months
|
|
125
|
-
.map((m, i) => ({ m, i }))
|
|
126
|
-
.filter(({ m }) => m.name.toLowerCase().startsWith(needle));
|
|
126
|
+
const prefixed = months.map((m, i) => ({ m, i })).filter(({ m }) => m.toLowerCase().startsWith(needle));
|
|
127
127
|
return prefixed.length === 1 ? prefixed[0].i + 1 : null;
|
|
128
128
|
}
|
|
129
129
|
/**
|
|
@@ -173,11 +173,10 @@ function convertDisplayInput(cal, input) {
|
|
|
173
173
|
const y = era === cal.after ? year + cal.epoch - 1 : cal.epoch - year;
|
|
174
174
|
if (y < 1)
|
|
175
175
|
return { ok: false, error: `${year} ${era} is before script year 1 (epoch ${cal.epoch})` };
|
|
176
|
-
if (!isValidScriptDate(
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
: { ok: false, error: `this calendar has ${months.length} months` };
|
|
176
|
+
if (!isValidScriptDate(y, m, d)) {
|
|
177
|
+
return m >= 1 && m <= exports.ENGINE_MONTH_DAYS.length
|
|
178
|
+
? { ok: false, error: `${monthNames(cal)[m - 1]} has ${exports.ENGINE_MONTH_DAYS[m - 1]} days` }
|
|
179
|
+
: { ok: false, error: `the game has ${exports.ENGINE_MONTH_DAYS.length} months` };
|
|
181
180
|
}
|
|
182
181
|
return { ok: true, script: `${y}.${m}.${d}`, display: displayDate(cal, y, m, d) };
|
|
183
182
|
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { type CalendarSetting } from "./calendar";
|
|
2
|
+
import { type ConfigDirNames } from "./configDir";
|
|
3
|
+
export declare const CALENDAR_FILE = "calendar.json";
|
|
4
|
+
export interface CalendarFile {
|
|
5
|
+
/** Where the declaration was read from (or would be written to). */
|
|
6
|
+
file: string;
|
|
7
|
+
/** The declared calendar, when the file parses and sanitizes. */
|
|
8
|
+
calendar?: CalendarSetting;
|
|
9
|
+
/** Why an existing file yields no calendar: unparsable JSON or an unusable shape. */
|
|
10
|
+
error?: string;
|
|
11
|
+
}
|
|
12
|
+
/** The path the file is read from: the mod's config dir (legacy name included). */
|
|
13
|
+
export declare function calendarFilePath(modRoot: string, names: ConfigDirNames): string;
|
|
14
|
+
/**
|
|
15
|
+
* Read `<mod>/.px-toolkit/calendar.json`. Null when the file does not exist;
|
|
16
|
+
* a `CalendarFile` without `calendar` when it exists but is not usable, so a
|
|
17
|
+
* client can say so instead of silently showing no dates.
|
|
18
|
+
*/
|
|
19
|
+
export declare function readCalendarFile(modRoot: string, names: ConfigDirNames): CalendarFile | null;
|
|
20
|
+
/**
|
|
21
|
+
* Write the declaration into the mod (renaming a legacy config dir first,
|
|
22
|
+
* like every other config-dir write). Returns the file path.
|
|
23
|
+
*/
|
|
24
|
+
export declare function writeCalendarFile(modRoot: string, names: ConfigDirNames, cal: CalendarSetting): string;
|
|
25
|
+
/** True when `fsPath` is a calendar declaration file (any config dir name). */
|
|
26
|
+
export declare function isCalendarFile(fsPath: string, names: ConfigDirNames): boolean;
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.CALENDAR_FILE = void 0;
|
|
37
|
+
exports.calendarFilePath = calendarFilePath;
|
|
38
|
+
exports.readCalendarFile = readCalendarFile;
|
|
39
|
+
exports.writeCalendarFile = writeCalendarFile;
|
|
40
|
+
exports.isCalendarFile = isCalendarFile;
|
|
41
|
+
/**
|
|
42
|
+
* The per-mod calendar declaration: `<mod>/.px-toolkit/calendar.json`, the
|
|
43
|
+
* JSON form of calendar.ts `CalendarSetting`. A display calendar is a fact
|
|
44
|
+
* about the mod, so it travels with the mod (committed, one per mod, read by
|
|
45
|
+
* every client and by the server itself) instead of living in one editor's
|
|
46
|
+
* window-scoped `px.calendar` setting. The setting stays as the fallback for
|
|
47
|
+
* a mod without the file.
|
|
48
|
+
*
|
|
49
|
+
* No `vscode` imports: unit-tested in plain Node.
|
|
50
|
+
*/
|
|
51
|
+
const fs = __importStar(require("fs"));
|
|
52
|
+
const path = __importStar(require("path"));
|
|
53
|
+
const calendar_1 = require("./calendar");
|
|
54
|
+
const configDir_1 = require("./configDir");
|
|
55
|
+
exports.CALENDAR_FILE = "calendar.json";
|
|
56
|
+
/** The path the file is read from: the mod's config dir (legacy name included). */
|
|
57
|
+
function calendarFilePath(modRoot, names) {
|
|
58
|
+
return path.join((0, configDir_1.resolveConfigDir)(modRoot, names), exports.CALENDAR_FILE);
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Read `<mod>/.px-toolkit/calendar.json`. Null when the file does not exist;
|
|
62
|
+
* a `CalendarFile` without `calendar` when it exists but is not usable, so a
|
|
63
|
+
* client can say so instead of silently showing no dates.
|
|
64
|
+
*/
|
|
65
|
+
function readCalendarFile(modRoot, names) {
|
|
66
|
+
const file = calendarFilePath(modRoot, names);
|
|
67
|
+
let text;
|
|
68
|
+
try {
|
|
69
|
+
text = fs.readFileSync(file, "utf8");
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
let raw;
|
|
75
|
+
try {
|
|
76
|
+
raw = JSON.parse(text.replace(/^\uFEFF/, ""));
|
|
77
|
+
}
|
|
78
|
+
catch (err) {
|
|
79
|
+
return { file, error: `not valid JSON (${err.message})` };
|
|
80
|
+
}
|
|
81
|
+
const calendar = (0, calendar_1.sanitizeCalendar)(raw);
|
|
82
|
+
if (!calendar) {
|
|
83
|
+
return {
|
|
84
|
+
file,
|
|
85
|
+
error: 'not a usable calendar: needs a whole-number "epoch" (1 or more), a non-empty "after" era label, ' +
|
|
86
|
+
'a "before" label different from "after" when present, and, when "months" is given, exactly twelve distinct names',
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
return { file, calendar };
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Write the declaration into the mod (renaming a legacy config dir first,
|
|
93
|
+
* like every other config-dir write). Returns the file path.
|
|
94
|
+
*/
|
|
95
|
+
function writeCalendarFile(modRoot, names, cal) {
|
|
96
|
+
const dir = (0, configDir_1.migrateConfigDir)(modRoot, names);
|
|
97
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
98
|
+
const file = path.join(dir, exports.CALENDAR_FILE);
|
|
99
|
+
fs.writeFileSync(file, JSON.stringify(cal, null, 2) + "\n", "utf8");
|
|
100
|
+
return file;
|
|
101
|
+
}
|
|
102
|
+
/** True when `fsPath` is a calendar declaration file (any config dir name). */
|
|
103
|
+
function isCalendarFile(fsPath, names) {
|
|
104
|
+
const parts = fsPath.split(/[\\/]/);
|
|
105
|
+
if (parts.length < 2 || parts[parts.length - 1].toLowerCase() !== exports.CALENDAR_FILE)
|
|
106
|
+
return false;
|
|
107
|
+
const dir = parts[parts.length - 2].toLowerCase();
|
|
108
|
+
return dir === names.configDirName.toLowerCase() || dir === names.legacyConfigDirName?.toLowerCase();
|
|
109
|
+
}
|
package/dist/calendarLoc.js
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.CAL_ERA_KEY = exports.CAL_YEAR_KEY = void 0;
|
|
4
4
|
exports.generateCalendarLoc = generateCalendarLoc;
|
|
5
|
-
const calendar_1 = require("./calendar");
|
|
6
5
|
/** Keys the generated files define; exported so tests and docs stay in sync. */
|
|
7
6
|
exports.CAL_YEAR_KEY = "PX_CAL_YEAR";
|
|
8
7
|
exports.CAL_ERA_KEY = "PX_CAL_ERA";
|
|
@@ -72,23 +71,20 @@ function generateCalendarLoc(cal, spec, lang) {
|
|
|
72
71
|
overrideLines.push(` ${key}:0 "${value}"`);
|
|
73
72
|
}
|
|
74
73
|
if (cal.months) {
|
|
75
|
-
const months =
|
|
74
|
+
const months = cal.months;
|
|
76
75
|
if (!spec.monthKeys) {
|
|
77
76
|
notes.push("This game's month-name keys are not mapped yet; custom month names were not generated.");
|
|
78
77
|
}
|
|
79
|
-
else if (months.length !== spec.monthKeys.length) {
|
|
80
|
-
notes.push(`The engine has exactly ${spec.monthKeys.length} months; your calendar declares ${months.length}, ` +
|
|
81
|
-
"so month names were not generated (the month count itself cannot be modded).");
|
|
82
|
-
}
|
|
83
78
|
else {
|
|
79
|
+
// The calendar carries the engine's twelve names (sanitizeCalendar); the
|
|
80
|
+
// spec lists the keys of the months it knows, first month first.
|
|
84
81
|
overrideLines.push(" # Engine month names (long and abbreviated forms both get the custom name).");
|
|
85
|
-
|
|
86
|
-
const
|
|
87
|
-
overrideLines.push(` ${long}:0 "${
|
|
82
|
+
spec.monthKeys.forEach(([long, short], i) => {
|
|
83
|
+
const name = months[i].replace(/"/g, '\\"');
|
|
84
|
+
overrideLines.push(` ${long}:0 "${name}"`);
|
|
88
85
|
if (short !== long)
|
|
89
|
-
overrideLines.push(` ${short}:0 "${
|
|
86
|
+
overrideLines.push(` ${short}:0 "${name}"`);
|
|
90
87
|
});
|
|
91
|
-
notes.push("Month day counts are engine-fixed (31/28/31...); custom day counts only affect the editor's display.");
|
|
92
88
|
}
|
|
93
89
|
}
|
|
94
90
|
notes.push(`Generated for '${lang}' only; other languages the mod ships need the same overrides in their replace folder.`);
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export declare const PX_CONFIG_DIR = ".px-toolkit";
|
|
2
|
+
export interface ConfigDirNames {
|
|
3
|
+
configDirName: string;
|
|
4
|
+
/** The pre-0.4.0 per-game name, still read as a fallback. */
|
|
5
|
+
legacyConfigDirName?: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* The config dir to READ from: the current name when it exists, else the
|
|
9
|
+
* legacy one when that exists, else the current name. Never touches disk.
|
|
10
|
+
*/
|
|
11
|
+
export declare function resolveConfigDir(root: string, names: ConfigDirNames): string;
|
|
12
|
+
/**
|
|
13
|
+
* The config dir to WRITE to. Renames a legacy dir to the current name first;
|
|
14
|
+
* if the rename fails (locked file, read-only parent) the legacy dir stays in
|
|
15
|
+
* use so the write still lands where reads look.
|
|
16
|
+
*/
|
|
17
|
+
export declare function migrateConfigDir(root: string, names: ConfigDirNames): string;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.PX_CONFIG_DIR = void 0;
|
|
37
|
+
exports.resolveConfigDir = resolveConfigDir;
|
|
38
|
+
exports.migrateConfigDir = migrateConfigDir;
|
|
39
|
+
/**
|
|
40
|
+
* The toolkit's per-mod config dir: `<mod>/.px-toolkit/`, holding
|
|
41
|
+
* `workshop.json`, `schema.json`, `playset.json`, the tiger baseline, the GUI
|
|
42
|
+
* preview values and the Workshop listing folder. Mods created before 0.4.0
|
|
43
|
+
* have a per-game name instead (each GameMeta's `legacyConfigDirName`);
|
|
44
|
+
* reads keep finding it, and the first write renames it.
|
|
45
|
+
*
|
|
46
|
+
* No `vscode` imports: unit-tested in plain Node.
|
|
47
|
+
*/
|
|
48
|
+
const fs = __importStar(require("fs"));
|
|
49
|
+
const path = __importStar(require("path"));
|
|
50
|
+
exports.PX_CONFIG_DIR = ".px-toolkit";
|
|
51
|
+
/**
|
|
52
|
+
* The config dir to READ from: the current name when it exists, else the
|
|
53
|
+
* legacy one when that exists, else the current name. Never touches disk.
|
|
54
|
+
*/
|
|
55
|
+
function resolveConfigDir(root, names) {
|
|
56
|
+
const current = path.join(root, names.configDirName);
|
|
57
|
+
if (!names.legacyConfigDirName || fs.existsSync(current))
|
|
58
|
+
return current;
|
|
59
|
+
const legacy = path.join(root, names.legacyConfigDirName);
|
|
60
|
+
return fs.existsSync(legacy) ? legacy : current;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* The config dir to WRITE to. Renames a legacy dir to the current name first;
|
|
64
|
+
* if the rename fails (locked file, read-only parent) the legacy dir stays in
|
|
65
|
+
* use so the write still lands where reads look.
|
|
66
|
+
*/
|
|
67
|
+
function migrateConfigDir(root, names) {
|
|
68
|
+
const current = path.join(root, names.configDirName);
|
|
69
|
+
const resolved = resolveConfigDir(root, names);
|
|
70
|
+
if (resolved === current)
|
|
71
|
+
return current;
|
|
72
|
+
try {
|
|
73
|
+
fs.renameSync(resolved, current);
|
|
74
|
+
return current;
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
return resolved;
|
|
78
|
+
}
|
|
79
|
+
}
|