@heroiclands/package-build 0.4.0 → 0.5.0
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/CHANGELOG.md +29 -0
- package/index.mjs +0 -3
- package/lang.mjs +2 -2
- package/package.json +1 -6
- package/types/index.d.mts +0 -1
- package/text.mjs +0 -74
- package/types/text.d.mts +0 -51
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,34 @@
|
|
|
1
1
|
# @heroiclands/package-build
|
|
2
2
|
|
|
3
|
+
## 0.5.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 905254d: **`text.mjs` is deleted; the one implementation lives with the diagnostics
|
|
8
|
+
contract it serves.**
|
|
9
|
+
|
|
10
|
+
`locateInText` and `positionOf` computed which line and column a substring sits
|
|
11
|
+
on. `@heroiclands/content-build` computes the same thing in
|
|
12
|
+
`engine/diagnostics.mjs` as `positionOfLiteral`, and has said so in a comment
|
|
13
|
+
for some time:
|
|
14
|
+
|
|
15
|
+
> That is a duplicate worth naming: unlike the diagnostic _format_ or a
|
|
16
|
+
> validation _rule_, "which line and column is this substring on" has exactly
|
|
17
|
+
> one correct answer and cannot drift into disagreement. The tidier arrangement
|
|
18
|
+
> is for that package to re-export this one — the dependency runs that way — and
|
|
19
|
+
> it should, next time either is touched.
|
|
20
|
+
|
|
21
|
+
This is that time. Rather than re-export, the module is removed outright: the
|
|
22
|
+
`./text` subpath was a library surface with one internal caller (`lang.mjs`) and
|
|
23
|
+
one external one, and this package's job is a command line, not a text-utility
|
|
24
|
+
grab bag.
|
|
25
|
+
|
|
26
|
+
**Breaking for anyone importing `@heroiclands/package-build/text`.** Import
|
|
27
|
+
`positionOfLiteral` from `@heroiclands/content-build/engine/diagnostics`
|
|
28
|
+
instead; it is the same arithmetic, and returns `{}` rather than `undefined`
|
|
29
|
+
when the literal is absent — the shape the diagnostics contract already spreads.
|
|
30
|
+
`locateInText` had no callers anywhere and is simply gone.
|
|
31
|
+
|
|
3
32
|
## 0.4.0
|
|
4
33
|
|
|
5
34
|
### Minor Changes
|
package/index.mjs
CHANGED
|
@@ -56,6 +56,3 @@ export * as deploy from "./deploy.mjs";
|
|
|
56
56
|
|
|
57
57
|
/** Localization files: what a shippable `lang/*.json` must satisfy. */
|
|
58
58
|
export * as lang from "./lang.mjs";
|
|
59
|
-
|
|
60
|
-
/** Locating a literal inside an arbitrary text file, for positioned findings. */
|
|
61
|
-
export * as text from "./text.mjs";
|
package/lang.mjs
CHANGED
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
* @module
|
|
46
46
|
*/
|
|
47
47
|
|
|
48
|
-
import {
|
|
48
|
+
import { positionOfLiteral } from "@heroiclands/content-build/engine/diagnostics";
|
|
49
49
|
|
|
50
50
|
/**
|
|
51
51
|
* A single finding, in the fields the shared diagnostic format takes.
|
|
@@ -140,7 +140,7 @@ export function validateLangSource(raw) {
|
|
|
140
140
|
* @param {string} key - The localization key.
|
|
141
141
|
* @returns {{line?: number, column?: number}} Spreadable position fields.
|
|
142
142
|
*/
|
|
143
|
-
const at = (key) =>
|
|
143
|
+
const at = (key) => positionOfLiteral(raw, `"${key}"`);
|
|
144
144
|
|
|
145
145
|
for (const [key, value] of Object.entries(json)) {
|
|
146
146
|
if (typeof value !== "string") continue;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@heroiclands/package-build",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Shared toolchain for building and shipping a HeroicLands Foundry VTT package \u2014 manifest, localization, staging, bundle, release and deployment.",
|
|
5
5
|
"license": "GPL-3.0-or-later",
|
|
6
6
|
"type": "module",
|
|
@@ -35,10 +35,6 @@
|
|
|
35
35
|
"types": "./types/stage.d.mts",
|
|
36
36
|
"import": "./stage.mjs"
|
|
37
37
|
},
|
|
38
|
-
"./text": {
|
|
39
|
-
"types": "./types/text.d.mts",
|
|
40
|
-
"import": "./text.mjs"
|
|
41
|
-
},
|
|
42
38
|
"./package.json": "./package.json",
|
|
43
39
|
"./config": {
|
|
44
40
|
"types": "./types/config.d.mts",
|
|
@@ -53,7 +49,6 @@
|
|
|
53
49
|
"manifest.mjs",
|
|
54
50
|
"release.mjs",
|
|
55
51
|
"stage.mjs",
|
|
56
|
-
"text.mjs",
|
|
57
52
|
"types",
|
|
58
53
|
"CHANGELOG.md",
|
|
59
54
|
"README.md",
|
package/types/index.d.mts
CHANGED
package/text.mjs
DELETED
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* This file is part of the Song of Heroic Lands (SoHL) system for Foundry VTT.
|
|
3
|
-
* Copyright (c) 2024-2026 Tom Rodriguez ("Toasty") — <toasty@heroiclands.org>
|
|
4
|
-
*
|
|
5
|
-
* This work is licensed under the GNU General Public License v3.0 (GPLv3).
|
|
6
|
-
* You may copy, modify, and distribute it under the terms of that license.
|
|
7
|
-
*
|
|
8
|
-
* For full terms, see the LICENSE.md file in the project root or visit:
|
|
9
|
-
* https://www.gnu.org/licenses/gpl-3.0.html
|
|
10
|
-
*
|
|
11
|
-
* SPDX-License-Identifier: GPL-3.0-or-later
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Locating a literal inside an arbitrary text file.
|
|
16
|
-
*
|
|
17
|
-
* A build check reports a **finding**, and a finding is only actionable if it
|
|
18
|
-
* says where it is (#1668). Most findings are *about* a string the check
|
|
19
|
-
* matched — a key, a marker, a caption — so its position is one string search
|
|
20
|
-
* away, and making that search is the difference between a finding that can be
|
|
21
|
-
* opened and one that has to be hunted for.
|
|
22
|
-
*
|
|
23
|
-
* `@heroiclands/content-build` owns the diagnostic **format**, and its
|
|
24
|
-
* `positionInBody` maps an offset within a parsed content note back to its
|
|
25
|
-
* file. That is a different job: the checks here read localization files,
|
|
26
|
-
* manifests, source and bundles — none of which are notes. So this module
|
|
27
|
-
* carries the generic operation, and nothing carries it twice.
|
|
28
|
-
*
|
|
29
|
-
* Plain ESM with no filesystem access, so it is unit-testable.
|
|
30
|
-
*
|
|
31
|
-
* @module
|
|
32
|
-
*/
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Where a literal sits in a text.
|
|
36
|
-
*
|
|
37
|
-
* @param {string} text - The file's contents.
|
|
38
|
-
* @param {string} needle - The literal to locate.
|
|
39
|
-
* @param {number} [occurrence] - Which occurrence, 1-based. Repeats of the same
|
|
40
|
-
* literal are otherwise indistinguishable, which is the symptom the
|
|
41
|
-
* diagnostic format exists to remove.
|
|
42
|
-
* @returns {{line: number, column: number}|undefined} 1-based position, or
|
|
43
|
-
* `undefined` when the literal is not there. A caller that gets `undefined`
|
|
44
|
-
* reports the file alone rather than a position that is not the problem.
|
|
45
|
-
*/
|
|
46
|
-
export function locateInText(text, needle, occurrence = 1) {
|
|
47
|
-
if (typeof text !== "string" || !needle) return undefined;
|
|
48
|
-
let at = -1;
|
|
49
|
-
for (let n = 0; n < occurrence; n++) {
|
|
50
|
-
at = text.indexOf(needle, at + 1);
|
|
51
|
-
if (at === -1) return undefined;
|
|
52
|
-
}
|
|
53
|
-
const before = text.slice(0, at);
|
|
54
|
-
return {
|
|
55
|
-
line: before.split("\n").length,
|
|
56
|
-
column: at - before.lastIndexOf("\n"),
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Where a literal sits, as spreadable diagnostic fields.
|
|
62
|
-
*
|
|
63
|
-
* Keeps the drop-rather-than-guess rule in one place: an unfound literal
|
|
64
|
-
* contributes no position at all, rather than `undefined` fields that read as a
|
|
65
|
-
* bug or a `1:1` that sends the reader to the top of the file.
|
|
66
|
-
*
|
|
67
|
-
* @param {string} text - The file's contents.
|
|
68
|
-
* @param {string} needle - The literal to locate.
|
|
69
|
-
* @param {number} [occurrence] - Which occurrence, 1-based.
|
|
70
|
-
* @returns {{line?: number, column?: number}} Spreadable position fields.
|
|
71
|
-
*/
|
|
72
|
-
export function positionOf(text, needle, occurrence = 1) {
|
|
73
|
-
return locateInText(text, needle, occurrence) ?? {};
|
|
74
|
-
}
|
package/types/text.d.mts
DELETED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Locating a literal inside an arbitrary text file.
|
|
3
|
-
*
|
|
4
|
-
* A build check reports a **finding**, and a finding is only actionable if it
|
|
5
|
-
* says where it is (#1668). Most findings are *about* a string the check
|
|
6
|
-
* matched — a key, a marker, a caption — so its position is one string search
|
|
7
|
-
* away, and making that search is the difference between a finding that can be
|
|
8
|
-
* opened and one that has to be hunted for.
|
|
9
|
-
*
|
|
10
|
-
* `@heroiclands/content-build` owns the diagnostic **format**, and its
|
|
11
|
-
* `positionInBody` maps an offset within a parsed content note back to its
|
|
12
|
-
* file. That is a different job: the checks here read localization files,
|
|
13
|
-
* manifests, source and bundles — none of which are notes. So this module
|
|
14
|
-
* carries the generic operation, and nothing carries it twice.
|
|
15
|
-
*
|
|
16
|
-
* Plain ESM with no filesystem access, so it is unit-testable.
|
|
17
|
-
*
|
|
18
|
-
* @module
|
|
19
|
-
*/
|
|
20
|
-
/**
|
|
21
|
-
* Where a literal sits in a text.
|
|
22
|
-
*
|
|
23
|
-
* @param {string} text - The file's contents.
|
|
24
|
-
* @param {string} needle - The literal to locate.
|
|
25
|
-
* @param {number} [occurrence] - Which occurrence, 1-based. Repeats of the same
|
|
26
|
-
* literal are otherwise indistinguishable, which is the symptom the
|
|
27
|
-
* diagnostic format exists to remove.
|
|
28
|
-
* @returns {{line: number, column: number}|undefined} 1-based position, or
|
|
29
|
-
* `undefined` when the literal is not there. A caller that gets `undefined`
|
|
30
|
-
* reports the file alone rather than a position that is not the problem.
|
|
31
|
-
*/
|
|
32
|
-
export function locateInText(text: string, needle: string, occurrence?: number): {
|
|
33
|
-
line: number;
|
|
34
|
-
column: number;
|
|
35
|
-
} | undefined;
|
|
36
|
-
/**
|
|
37
|
-
* Where a literal sits, as spreadable diagnostic fields.
|
|
38
|
-
*
|
|
39
|
-
* Keeps the drop-rather-than-guess rule in one place: an unfound literal
|
|
40
|
-
* contributes no position at all, rather than `undefined` fields that read as a
|
|
41
|
-
* bug or a `1:1` that sends the reader to the top of the file.
|
|
42
|
-
*
|
|
43
|
-
* @param {string} text - The file's contents.
|
|
44
|
-
* @param {string} needle - The literal to locate.
|
|
45
|
-
* @param {number} [occurrence] - Which occurrence, 1-based.
|
|
46
|
-
* @returns {{line?: number, column?: number}} Spreadable position fields.
|
|
47
|
-
*/
|
|
48
|
-
export function positionOf(text: string, needle: string, occurrence?: number): {
|
|
49
|
-
line?: number;
|
|
50
|
-
column?: number;
|
|
51
|
-
};
|