prosebook 0.0.1 → 0.2.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/LICENSE +21 -0
- package/README.md +604 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +508 -0
- package/dist/cli.js.map +1 -0
- package/dist/config-D--RITk2.js +1208 -0
- package/dist/config-D--RITk2.js.map +1 -0
- package/dist/config-_4HfnJQu.d.ts +517 -0
- package/dist/config-_4HfnJQu.d.ts.map +1 -0
- package/dist/config.d.ts +2 -0
- package/dist/config.js +1 -0
- package/dist/copy-DXnzXsJa.d.ts +162 -0
- package/dist/copy-DXnzXsJa.d.ts.map +1 -0
- package/dist/helpers-BPuPGjQP.js +61 -0
- package/dist/helpers-BPuPGjQP.js.map +1 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +188 -0
- package/dist/index.js.map +1 -0
- package/dist/inspector.d.ts +37 -0
- package/dist/inspector.d.ts.map +1 -0
- package/dist/inspector.js +572 -0
- package/dist/inspector.js.map +1 -0
- package/dist/react/index.d.ts +37 -0
- package/dist/react/index.d.ts.map +1 -0
- package/dist/react/index.js +86 -0
- package/dist/react/index.js.map +1 -0
- package/dist/sarif-CI8HOokm.js +1033 -0
- package/dist/sarif-CI8HOokm.js.map +1 -0
- package/dist/scan-Ch2BfIUD.js +2561 -0
- package/dist/scan-Ch2BfIUD.js.map +1 -0
- package/dist/tools.d.ts +377 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +4 -0
- package/dist/vite.d.ts +24 -0
- package/dist/vite.d.ts.map +1 -0
- package/dist/vite.js +264 -0
- package/dist/vite.js.map +1 -0
- package/package.json +148 -15
- package/src/cli.ts +528 -0
- package/src/index.ts +31 -0
- package/src/inspector-dialog.ts +450 -0
- package/src/inspector.ts +228 -0
- package/src/react/index.tsx +112 -0
- package/src/runtime/copy.ts +221 -0
- package/src/runtime/helpers.ts +66 -0
- package/src/runtime/locale.ts +49 -0
- package/src/runtime/types.ts +106 -0
- package/src/tools/catalog.ts +449 -0
- package/src/tools/compile.ts +121 -0
- package/src/tools/config.ts +211 -0
- package/src/tools/diff.ts +84 -0
- package/src/tools/entry.ts +325 -0
- package/src/tools/extract.ts +694 -0
- package/src/tools/generate.ts +257 -0
- package/src/tools/icu.ts +211 -0
- package/src/tools/index.ts +91 -0
- package/src/tools/lint.ts +865 -0
- package/src/tools/lock.ts +95 -0
- package/src/tools/mf1.ts +246 -0
- package/src/tools/mf2.ts +752 -0
- package/src/tools/migrate.ts +138 -0
- package/src/tools/presets.ts +159 -0
- package/src/tools/pseudo.ts +40 -0
- package/src/tools/sarif.ts +80 -0
- package/src/tools/scan.ts +303 -0
- package/src/tools/syntax.ts +24 -0
- package/src/tools/types.ts +137 -0
- package/src/vite.ts +296 -0
- package/index.js +0 -1
package/dist/vite.js
ADDED
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
import { A as entryLocation, C as editEntry, E as localeExpression, O as CatalogError, T as compileLocale, c as unseenReads, i as keyRefs, r as isReferenced, t as READERS, u as generate, w as readEntry } from "./scan-Ch2BfIUD.js";
|
|
2
|
+
import { r as loadConfig } from "./config-D--RITk2.js";
|
|
3
|
+
import { relative, resolve } from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
// src/vite.ts
|
|
6
|
+
/**
|
|
7
|
+
* `prosebook/vite`: the catalog as part of the build.
|
|
8
|
+
*
|
|
9
|
+
* Generates on start and again whenever a catalog or translation file changes, so dev never runs on
|
|
10
|
+
* stale modules and a broken entry shows in the error overlay. A build ships only the messages the
|
|
11
|
+
* code names: each locale module is swapped for its messages less the keys no module references
|
|
12
|
+
* (see `tools/scan.ts` for how a reference is found, and why it errs towards keeping).
|
|
13
|
+
*
|
|
14
|
+
* In dev an edit doesn't reload the page: each generated locale module accepts its own update and
|
|
15
|
+
* hands the new messages to every copy (`HotHook`), which re-renders in the locale and state it was in.
|
|
16
|
+
* The index accepts its own too, since its doc comments change with the source text, and reloads the
|
|
17
|
+
* page only when a locale was added or removed. The page also gets the inspector (`inspector.ts`), and
|
|
18
|
+
* the server opens the entry it asks for through Vite's own `/__open-in-editor`, so the editor is
|
|
19
|
+
* whichever Vite already launches.
|
|
20
|
+
*/
|
|
21
|
+
const PLACEHOLDER = /__PROSEBOOK_LOCALE_(\d+)__/g;
|
|
22
|
+
const SCRIPT = /\.[cm]?[jt]sx?$/;
|
|
23
|
+
const DEV_ID = "\0prosebook/dev";
|
|
24
|
+
const hotLocale = (locale) => `
|
|
25
|
+
if (import.meta.hot) {
|
|
26
|
+
import.meta.hot.accept((next) => {
|
|
27
|
+
const hot = globalThis.__PROSEBOOK_HOT__;
|
|
28
|
+
if (next === undefined || hot === undefined) return import.meta.hot.invalidate();
|
|
29
|
+
for (const update of hot) update(${JSON.stringify(locale)}, next.default);
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
`;
|
|
33
|
+
const HOT_INDEX = `
|
|
34
|
+
if (import.meta.hot) {
|
|
35
|
+
import.meta.hot.accept((next) => {
|
|
36
|
+
if (next === undefined || next.catalog.locales.join() !== catalog.locales.join()) import.meta.hot.invalidate();
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
`;
|
|
40
|
+
const normalize = (path) => resolve(path).replaceAll("\\", "/");
|
|
41
|
+
const inspectorPath = normalize(fileURLToPath(new URL(`./inspector${import.meta.url.endsWith(".ts") ? ".ts" : ".js"}`, import.meta.url)));
|
|
42
|
+
const ownDir = normalize(fileURLToPath(new URL(".", import.meta.url)));
|
|
43
|
+
function prosebook(options = {}) {
|
|
44
|
+
let config;
|
|
45
|
+
let generated;
|
|
46
|
+
let building = false;
|
|
47
|
+
let base = "/";
|
|
48
|
+
let viteRoot = "";
|
|
49
|
+
let refs = {
|
|
50
|
+
exact: /* @__PURE__ */ new Set(),
|
|
51
|
+
prefixes: /* @__PURE__ */ new Set()
|
|
52
|
+
};
|
|
53
|
+
const reads = /* @__PURE__ */ new Map();
|
|
54
|
+
const prune = options.prune ?? "strict";
|
|
55
|
+
const placeholders = [];
|
|
56
|
+
const shipped = {
|
|
57
|
+
total: 0,
|
|
58
|
+
kept: 0
|
|
59
|
+
};
|
|
60
|
+
const describe = (e) => e instanceof CatalogError ? e.message : e instanceof Error ? e.stack ?? e.message : String(e);
|
|
61
|
+
const localeOf = (id) => {
|
|
62
|
+
const path = normalize(id.split("?", 1)[0]);
|
|
63
|
+
const out = normalize(config.out);
|
|
64
|
+
if (!path.startsWith(`${out}/`)) return void 0;
|
|
65
|
+
const name = path.slice(out.length + 1).replace(/\.[jt]s$/, "");
|
|
66
|
+
return generated?.entries.has(name) === true ? name : void 0;
|
|
67
|
+
};
|
|
68
|
+
const isIndex = (id) => {
|
|
69
|
+
const path = normalize(id.split("?", 1)[0]);
|
|
70
|
+
const out = normalize(config.out);
|
|
71
|
+
return path === `${out}/index.ts` || path === `${out}/index.js`;
|
|
72
|
+
};
|
|
73
|
+
const kept = (key) => isReferenced(key, refs) || (options.keep ?? []).some((k) => k.endsWith(".*") ? key.startsWith(k.slice(0, -1)) : k === key);
|
|
74
|
+
return {
|
|
75
|
+
name: "prosebook",
|
|
76
|
+
async configResolved(resolved) {
|
|
77
|
+
building = resolved.command === "build";
|
|
78
|
+
base = resolved.base;
|
|
79
|
+
viteRoot = resolved.root;
|
|
80
|
+
config = await loadConfig(options.root === void 0 ? resolved.root : resolve(resolved.root, options.root), options.config);
|
|
81
|
+
},
|
|
82
|
+
transformIndexHtml() {
|
|
83
|
+
if (building) return [];
|
|
84
|
+
return [{
|
|
85
|
+
tag: "script",
|
|
86
|
+
attrs: {
|
|
87
|
+
type: "module",
|
|
88
|
+
src: `${base}@id/__x00__prosebook/dev`
|
|
89
|
+
},
|
|
90
|
+
injectTo: "head-prepend"
|
|
91
|
+
}];
|
|
92
|
+
},
|
|
93
|
+
resolveId(id) {
|
|
94
|
+
return id === DEV_ID ? id : null;
|
|
95
|
+
},
|
|
96
|
+
buildStart() {
|
|
97
|
+
try {
|
|
98
|
+
generated = generate(config);
|
|
99
|
+
} catch (e) {
|
|
100
|
+
this.error(describe(e));
|
|
101
|
+
}
|
|
102
|
+
refs = {
|
|
103
|
+
exact: /* @__PURE__ */ new Set(),
|
|
104
|
+
prefixes: /* @__PURE__ */ new Set()
|
|
105
|
+
};
|
|
106
|
+
reads.clear();
|
|
107
|
+
placeholders.length = 0;
|
|
108
|
+
shipped.total = shipped.kept = 0;
|
|
109
|
+
},
|
|
110
|
+
configureServer(server) {
|
|
111
|
+
const dirs = [normalize(config.catalog), normalize(config.locales)];
|
|
112
|
+
server.watcher.add(dirs);
|
|
113
|
+
const onChange = (file) => {
|
|
114
|
+
const path = normalize(file);
|
|
115
|
+
if (!path.endsWith(".yaml") || !dirs.some((d) => path.startsWith(`${d}/`))) return;
|
|
116
|
+
try {
|
|
117
|
+
generated = generate(config);
|
|
118
|
+
server.config.logger.info(`prosebook: regenerated from ${relative(config.root, path).replaceAll("\\", "/")}`, { timestamp: true });
|
|
119
|
+
} catch (e) {
|
|
120
|
+
server.config.logger.error(describe(e), { timestamp: true });
|
|
121
|
+
server.ws.send({
|
|
122
|
+
type: "error",
|
|
123
|
+
err: {
|
|
124
|
+
message: describe(e),
|
|
125
|
+
stack: "",
|
|
126
|
+
plugin: "prosebook"
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
server.watcher.on("change", onChange);
|
|
132
|
+
server.watcher.on("add", onChange);
|
|
133
|
+
server.watcher.on("unlink", onChange);
|
|
134
|
+
if (options.inspect === false) return;
|
|
135
|
+
server.middlewares.use((req, res, next) => {
|
|
136
|
+
const url = new URL(req.url ?? "/", "http://localhost");
|
|
137
|
+
if (url.pathname !== `${base}__prosebook/open`) return next();
|
|
138
|
+
const key = url.searchParams.get("key") ?? "";
|
|
139
|
+
const message = generated?.catalog.messages.find((m) => m.key === key);
|
|
140
|
+
if (message === void 0) {
|
|
141
|
+
res.statusCode = 404;
|
|
142
|
+
res.end(`no entry for "${key}" in the catalog: has it been renamed since the page loaded?`);
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
const locale = url.searchParams.has("catalog") ? void 0 : url.searchParams.get("locale") ?? void 0;
|
|
146
|
+
const { file, line, column } = entryLocation(config, message, locale);
|
|
147
|
+
req.url = `${base}__open-in-editor?file=${encodeURIComponent(`${file}:${line}:${column}`)}`;
|
|
148
|
+
next();
|
|
149
|
+
});
|
|
150
|
+
server.middlewares.use((req, res, next) => {
|
|
151
|
+
const url = new URL(req.url ?? "/", "http://localhost");
|
|
152
|
+
if (url.pathname !== `${base}__prosebook/entry`) return next();
|
|
153
|
+
const reply = (status, body) => {
|
|
154
|
+
res.statusCode = status;
|
|
155
|
+
res.setHeader("Content-Type", "application/json");
|
|
156
|
+
res.end(JSON.stringify(body));
|
|
157
|
+
};
|
|
158
|
+
const fail = (e) => reply(e instanceof CatalogError ? 409 : 400, { problems: e instanceof CatalogError ? e.problems : [{
|
|
159
|
+
severity: "error",
|
|
160
|
+
message: e instanceof Error ? e.message : String(e)
|
|
161
|
+
}] });
|
|
162
|
+
if (req.method === "GET") {
|
|
163
|
+
try {
|
|
164
|
+
reply(200, readEntry(config, url.searchParams.get("key") ?? ""));
|
|
165
|
+
} catch (e) {
|
|
166
|
+
fail(e);
|
|
167
|
+
}
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
const origin = req.headers.origin;
|
|
171
|
+
const sameOrigin = origin === void 0 || new URL(origin).host === req.headers.host;
|
|
172
|
+
if (req.method !== "POST" || !sameOrigin || req.headers["content-type"]?.startsWith("application/json") !== true) {
|
|
173
|
+
reply(403, { problems: [{
|
|
174
|
+
severity: "error",
|
|
175
|
+
message: "edits come from the page, as JSON"
|
|
176
|
+
}] });
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
let body = "";
|
|
180
|
+
req.setEncoding("utf8");
|
|
181
|
+
req.on("data", (chunk) => body += chunk);
|
|
182
|
+
req.on("end", () => {
|
|
183
|
+
try {
|
|
184
|
+
const { key, edit, write } = JSON.parse(body);
|
|
185
|
+
const result = editEntry(config, key, edit, write === true);
|
|
186
|
+
reply(result.problems.length > 0 ? 422 : 200, result);
|
|
187
|
+
} catch (e) {
|
|
188
|
+
fail(e);
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
});
|
|
192
|
+
},
|
|
193
|
+
load(id) {
|
|
194
|
+
if (id === DEV_ID) {
|
|
195
|
+
const hot = "globalThis.__PROSEBOOK_HOT__ ??= new Set();\n";
|
|
196
|
+
if (options.inspect === false) return hot;
|
|
197
|
+
return `import { install } from ${JSON.stringify(inspectorPath)};\n${hot}install(${JSON.stringify({ base })});\n`;
|
|
198
|
+
}
|
|
199
|
+
if (!building || prune === false || generated === void 0) return null;
|
|
200
|
+
const locale = localeOf(id);
|
|
201
|
+
if (locale === void 0) return null;
|
|
202
|
+
placeholders.push(locale);
|
|
203
|
+
return `export default __PROSEBOOK_LOCALE_${placeholders.length - 1}__;\n`;
|
|
204
|
+
},
|
|
205
|
+
transform: {
|
|
206
|
+
order: "pre",
|
|
207
|
+
handler(code, id) {
|
|
208
|
+
if (!building) {
|
|
209
|
+
const locale = localeOf(id);
|
|
210
|
+
if (locale !== void 0) return {
|
|
211
|
+
code: code + hotLocale(locale),
|
|
212
|
+
map: null
|
|
213
|
+
};
|
|
214
|
+
return isIndex(id) ? {
|
|
215
|
+
code: code + HOT_INDEX,
|
|
216
|
+
map: null
|
|
217
|
+
} : null;
|
|
218
|
+
}
|
|
219
|
+
if (prune === false || id.includes("/node_modules/") || id.startsWith("\0")) return null;
|
|
220
|
+
if (localeOf(id) !== void 0 || isIndex(id)) return null;
|
|
221
|
+
keyRefs(code, refs);
|
|
222
|
+
const path = id.split("?", 1)[0];
|
|
223
|
+
if (prune === "strict" && SCRIPT.test(path) && !normalize(path).startsWith(`${ownDir}/`)) reads.set(id, unseenReads(path, code));
|
|
224
|
+
return null;
|
|
225
|
+
}
|
|
226
|
+
},
|
|
227
|
+
buildEnd(error) {
|
|
228
|
+
if (error !== void 0 || prune !== "strict") return;
|
|
229
|
+
const live = new Set(this.getModuleIds());
|
|
230
|
+
const all = [...reads].filter(([id]) => live.has(id)).map(([, r]) => r);
|
|
231
|
+
const readers = /* @__PURE__ */ new Set([...READERS, ...all.flatMap((r) => [...r.aliases])]);
|
|
232
|
+
const unseen = all.flatMap((r) => r.unseen).filter((u) => u.name === "Text" || readers.has(u.name));
|
|
233
|
+
if (unseen.length === 0) return;
|
|
234
|
+
const at = (file) => relative(viteRoot, file).replaceAll("\\", "/");
|
|
235
|
+
this.error([
|
|
236
|
+
`${unseen.length} read(s) whose key the build can't see, so their messages would be pruned and the key shown instead:`,
|
|
237
|
+
...unseen.map((u) => ` ${at(u.file)}:${u.line}:${u.column} ${u.code}`),
|
|
238
|
+
"Write each key at the read, as a literal or `area.${id}`; or, where every key it reads is written elsewhere or listed in `keep`, mark the line `prosebook-ignore`. `prune: \"loose\"` turns this check off."
|
|
239
|
+
].join("\n"));
|
|
240
|
+
},
|
|
241
|
+
renderChunk(code) {
|
|
242
|
+
if (!code.includes("__PROSEBOOK_LOCALE_") || generated === void 0) return null;
|
|
243
|
+
const entries = generated.entries;
|
|
244
|
+
return {
|
|
245
|
+
code: code.replace(PLACEHOLDER, (_match, index) => {
|
|
246
|
+
const locale = placeholders[Number(index)];
|
|
247
|
+
const list = entries.get(locale) ?? [];
|
|
248
|
+
const compiled = compileLocale(list, kept);
|
|
249
|
+
shipped.total += list.length;
|
|
250
|
+
shipped.kept += compiled.rows.length;
|
|
251
|
+
return localeExpression(compiled);
|
|
252
|
+
}),
|
|
253
|
+
map: null
|
|
254
|
+
};
|
|
255
|
+
},
|
|
256
|
+
generateBundle() {
|
|
257
|
+
if (shipped.total === 0) return;
|
|
258
|
+
this.info(`shipped ${shipped.kept} of ${shipped.total} messages across ${placeholders.length} locale(s); pruned ${shipped.total - shipped.kept} no code names`);
|
|
259
|
+
}
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
export { prosebook as default, prosebook };
|
|
263
|
+
|
|
264
|
+
//# sourceMappingURL=vite.js.map
|
package/dist/vite.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vite.js","names":[],"sources":["../src/vite.ts"],"sourcesContent":["/**\n * `prosebook/vite`: the catalog as part of the build.\n *\n * Generates on start and again whenever a catalog or translation file changes, so dev never runs on\n * stale modules and a broken entry shows in the error overlay. A build ships only the messages the\n * code names: each locale module is swapped for its messages less the keys no module references\n * (see `tools/scan.ts` for how a reference is found, and why it errs towards keeping).\n *\n * In dev an edit doesn't reload the page: each generated locale module accepts its own update and\n * hands the new messages to every copy (`HotHook`), which re-renders in the locale and state it was in.\n * The index accepts its own too, since its doc comments change with the source text, and reloads the\n * page only when a locale was added or removed. The page also gets the inspector (`inspector.ts`), and\n * the server opens the entry it asks for through Vite's own `/__open-in-editor`, so the editor is\n * whichever Vite already launches.\n */\nimport { relative, resolve } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nimport type { Plugin } from 'vite';\n\nimport { CatalogError, entryLocation } from './tools/catalog.ts';\nimport { compileLocale, localeExpression } from './tools/compile.ts';\nimport { loadConfig, type ProsebookConfig, type ResolvedConfig } from './tools/config.ts';\nimport { editEntry, readEntry, type EntryEdit } from './tools/entry.ts';\nimport { generate, type Generated } from './tools/generate.ts';\nimport { isReferenced, keyRefs, READERS, unseenReads, type KeyRefs, type Reads } from './tools/scan.ts';\n\nexport interface ProsebookPluginOptions {\n /** The config, inline. Without it, `prosebook.config.*` at `root` is read. */\n config?: ProsebookConfig;\n /**\n * The folder the config's paths resolve from, and where its file is found: the Vite root when\n * unset. Apps that share one catalog name its folder, so each build generates the same files.\n */\n root?: string;\n /**\n * Ship only the messages the code names. `strict`, the default, also fails the build on a read\n * whose key it can't see, such as `t(item.key)`, which would show the key where its message was\n * pruned. `loose` prunes without that check; `false` ships every message.\n */\n prune?: 'strict' | 'loose' | false;\n /** Keys a build always keeps, exactly or as `prefix.*`: for keys built at runtime from data. */\n keep?: string[];\n /** In dev, Alt-click a string on the page to open its entry in the editor. On by default. */\n inspect?: boolean;\n}\n\nconst PLACEHOLDER = /__PROSEBOOK_LOCALE_(\\d+)__/g;\nconst SCRIPT = /\\.[cm]?[jt]sx?$/;\nconst DEV_ID = '\\0prosebook/dev';\n\nconst hotLocale = (locale: string) => `\nif (import.meta.hot) {\n import.meta.hot.accept((next) => {\n const hot = globalThis.__PROSEBOOK_HOT__;\n if (next === undefined || hot === undefined) return import.meta.hot.invalidate();\n for (const update of hot) update(${JSON.stringify(locale)}, next.default);\n });\n}\n`;\n\nconst HOT_INDEX = `\nif (import.meta.hot) {\n import.meta.hot.accept((next) => {\n if (next === undefined || next.catalog.locales.join() !== catalog.locales.join()) import.meta.hot.invalidate();\n });\n}\n`;\n\nconst normalize = (path: string) => resolve(path).replaceAll('\\\\', '/');\n\n// Beside this module: the source when run from source, the built file in dist.\nconst inspectorPath = normalize(fileURLToPath(new URL(`./inspector${import.meta.url.endsWith('.ts') ? '.ts' : '.js'}`, import.meta.url)));\n// prosebook's own modules, which read keys handed to them: `<Text>` calls `rich(props.id)`.\nconst ownDir = normalize(fileURLToPath(new URL('.', import.meta.url)));\n\nexport function prosebook(options: ProsebookPluginOptions = {}): Plugin {\n let config: ResolvedConfig;\n let generated: Generated | undefined;\n let building = false;\n let base = '/';\n let viteRoot = '';\n let refs: KeyRefs = { exact: new Set(), prefixes: new Set() };\n const reads = new Map<string, Reads>();\n const prune = options.prune ?? 'strict';\n const placeholders: string[] = [];\n const shipped = { total: 0, kept: 0 };\n\n const describe = (e: unknown) => (e instanceof CatalogError ? e.message : e instanceof Error ? (e.stack ?? e.message) : String(e));\n\n const localeOf = (id: string): string | undefined => {\n const path = normalize(id.split('?', 1)[0]!);\n const out = normalize(config.out);\n if (!path.startsWith(`${out}/`)) return undefined;\n const name = path.slice(out.length + 1).replace(/\\.[jt]s$/, '');\n return generated?.entries.has(name) === true ? name : undefined;\n };\n\n const isIndex = (id: string) => {\n const path = normalize(id.split('?', 1)[0]!);\n const out = normalize(config.out);\n return path === `${out}/index.ts` || path === `${out}/index.js`;\n };\n\n const kept = (key: string) =>\n isReferenced(key, refs) || (options.keep ?? []).some((k) => (k.endsWith('.*') ? key.startsWith(k.slice(0, -1)) : k === key));\n\n return {\n name: 'prosebook',\n\n async configResolved(resolved) {\n building = resolved.command === 'build';\n base = resolved.base;\n viteRoot = resolved.root;\n config = await loadConfig(options.root === undefined ? resolved.root : resolve(resolved.root, options.root), options.config);\n },\n\n // First in <head>, so the hot hooks are there before any copy is created.\n transformIndexHtml() {\n if (building) return [];\n return [{ tag: 'script', attrs: { type: 'module', src: `${base}@id/__x00__prosebook/dev` }, injectTo: 'head-prepend' }];\n },\n\n resolveId(id) {\n return id === DEV_ID ? id : null;\n },\n\n buildStart() {\n try {\n generated = generate(config);\n } catch (e) {\n this.error(describe(e));\n }\n refs = { exact: new Set(), prefixes: new Set() };\n reads.clear();\n placeholders.length = 0;\n shipped.total = shipped.kept = 0;\n },\n\n configureServer(server) {\n const dirs = [normalize(config.catalog), normalize(config.locales)];\n server.watcher.add(dirs);\n const onChange = (file: string) => {\n const path = normalize(file);\n if (!path.endsWith('.yaml') || !dirs.some((d) => path.startsWith(`${d}/`))) return;\n try {\n generated = generate(config);\n server.config.logger.info(`prosebook: regenerated from ${relative(config.root, path).replaceAll('\\\\', '/')}`, {\n timestamp: true,\n });\n } catch (e) {\n server.config.logger.error(describe(e), { timestamp: true });\n server.ws.send({ type: 'error', err: { message: describe(e), stack: '', plugin: 'prosebook' } });\n }\n };\n server.watcher.on('change', onChange);\n server.watcher.on('add', onChange);\n server.watcher.on('unlink', onChange);\n if (options.inspect === false) return;\n\n // `?key=cart.items&locale=de`: the translation's entry, or the catalog's with `catalog` or when\n // the locale has none. Handed on to Vite's `/__open-in-editor`, which comes later in the stack.\n server.middlewares.use((req, res, next) => {\n const url = new URL(req.url ?? '/', 'http://localhost');\n if (url.pathname !== `${base}__prosebook/open`) return next();\n const key = url.searchParams.get('key') ?? '';\n const message = generated?.catalog.messages.find((m) => m.key === key);\n if (message === undefined) {\n res.statusCode = 404;\n res.end(`no entry for \"${key}\" in the catalog: has it been renamed since the page loaded?`);\n return;\n }\n const locale = url.searchParams.has('catalog') ? undefined : (url.searchParams.get('locale') ?? undefined);\n const { file, line, column } = entryLocation(config, message, locale);\n req.url = `${base}__open-in-editor?file=${encodeURIComponent(`${file}:${line}:${column}`)}`;\n next();\n });\n\n // The inspector's dialog: GET `?key=…` reads an entry in every locale, POST `{ key, edit, write }`\n // applies an edit (`tools/entry.ts`). A POST writes files, so only the page itself may send one:\n // same origin, and JSON, which a form on another site can't send without asking first.\n server.middlewares.use((req, res, next) => {\n const url = new URL(req.url ?? '/', 'http://localhost');\n if (url.pathname !== `${base}__prosebook/entry`) return next();\n const reply = (status: number, body: unknown) => {\n res.statusCode = status;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify(body));\n };\n const fail = (e: unknown) =>\n reply(e instanceof CatalogError ? 409 : 400, {\n problems: e instanceof CatalogError ? e.problems : [{ severity: 'error', message: e instanceof Error ? e.message : String(e) }],\n });\n if (req.method === 'GET') {\n try {\n reply(200, readEntry(config, url.searchParams.get('key') ?? ''));\n } catch (e) {\n fail(e);\n }\n return;\n }\n const origin = req.headers.origin;\n const sameOrigin = origin === undefined || new URL(origin).host === req.headers.host;\n if (req.method !== 'POST' || !sameOrigin || req.headers['content-type']?.startsWith('application/json') !== true) {\n reply(403, { problems: [{ severity: 'error', message: 'edits come from the page, as JSON' }] });\n return;\n }\n let body = '';\n req.setEncoding('utf8');\n req.on('data', (chunk: string) => (body += chunk));\n req.on('end', () => {\n try {\n const { key, edit, write } = JSON.parse(body) as { key: string; edit: EntryEdit; write?: boolean };\n const result = editEntry(config, key, edit, write === true);\n reply(result.problems.length > 0 ? 422 : 200, result);\n } catch (e) {\n fail(e);\n }\n });\n });\n },\n\n load(id) {\n if (id === DEV_ID) {\n const hot = 'globalThis.__PROSEBOOK_HOT__ ??= new Set();\\n';\n if (options.inspect === false) return hot;\n return `import { install } from ${JSON.stringify(inspectorPath)};\\n${hot}install(${JSON.stringify({ base })});\\n`;\n }\n if (!building || prune === false || generated === undefined) return null;\n const locale = localeOf(id);\n if (locale === undefined) return null;\n placeholders.push(locale);\n return `export default __PROSEBOOK_LOCALE_${placeholders.length - 1}__;\\n`;\n },\n\n // Before other plugins, so a read is found in the source as written: `<Text id>` still JSX, and\n // the line it is reported at, and its `prosebook-ignore`, where the author wrote them.\n transform: {\n order: 'pre',\n handler(code, id) {\n if (!building) {\n const locale = localeOf(id);\n if (locale !== undefined) return { code: code + hotLocale(locale), map: null };\n return isIndex(id) ? { code: code + HOT_INDEX, map: null } : null;\n }\n if (prune === false || id.includes('/node_modules/') || id.startsWith('\\0')) return null;\n // The index's `Messages` type names every key, and is read here before its types are stripped.\n if (localeOf(id) !== undefined || isIndex(id)) return null;\n keyRefs(code, refs);\n const path = id.split('?', 1)[0]!;\n if (prune === 'strict' && SCRIPT.test(path) && !normalize(path).startsWith(`${ownDir}/`)) reads.set(id, unseenReads(path, code));\n return null;\n },\n },\n\n buildEnd(error) {\n if (error !== undefined || prune !== 'strict') return;\n const live = new Set(this.getModuleIds());\n const all = [...reads].filter(([id]) => live.has(id)).map(([, r]) => r);\n const readers = new Set([...READERS, ...all.flatMap((r) => [...r.aliases])]);\n const unseen = all.flatMap((r) => r.unseen).filter((u) => u.name === 'Text' || readers.has(u.name));\n if (unseen.length === 0) return;\n const at = (file: string) => relative(viteRoot, file).replaceAll('\\\\', '/');\n this.error(\n [\n `${unseen.length} read(s) whose key the build can't see, so their messages would be pruned and the key shown instead:`,\n ...unseen.map((u) => ` ${at(u.file)}:${u.line}:${u.column} ${u.code}`),\n 'Write each key at the read, as a literal or `area.${id}`; or, where every key it reads is written elsewhere or listed in `keep`, mark the line `prosebook-ignore`. `prune: \"loose\"` turns this check off.',\n ].join('\\n'),\n );\n },\n\n renderChunk(code) {\n if (!code.includes('__PROSEBOOK_LOCALE_') || generated === undefined) return null;\n const entries = generated.entries;\n const replaced = code.replace(PLACEHOLDER, (_match, index: string) => {\n const locale = placeholders[Number(index)]!;\n const list = entries.get(locale) ?? [];\n const compiled = compileLocale(list, kept);\n shipped.total += list.length;\n shipped.kept += compiled.rows.length;\n return localeExpression(compiled);\n });\n return { code: replaced, map: null };\n },\n\n generateBundle() {\n if (shipped.total === 0) return;\n this.info(\n `shipped ${shipped.kept} of ${shipped.total} messages across ${placeholders.length} locale(s); pruned ${shipped.total - shipped.kept} no code names`,\n );\n },\n };\n}\n\nexport default prosebook;\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,15 +1,148 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "prosebook",
|
|
3
|
-
"version": "0.0
|
|
4
|
-
"description": "
|
|
5
|
-
"
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
"
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
"
|
|
14
|
-
|
|
15
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "prosebook",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Every string your app shows, in one typed catalog: ICU messages compiled to plain functions, for React and any JavaScript.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"i18n",
|
|
7
|
+
"icu",
|
|
8
|
+
"intl",
|
|
9
|
+
"l10n",
|
|
10
|
+
"localization",
|
|
11
|
+
"messageformat",
|
|
12
|
+
"messageformat2",
|
|
13
|
+
"react",
|
|
14
|
+
"translation",
|
|
15
|
+
"typescript",
|
|
16
|
+
"ux-writing"
|
|
17
|
+
],
|
|
18
|
+
"homepage": "https://gkurt.com/prosebook/",
|
|
19
|
+
"bugs": {
|
|
20
|
+
"url": "https://github.com/gkurt/prosebook/issues"
|
|
21
|
+
},
|
|
22
|
+
"license": "MIT",
|
|
23
|
+
"author": {
|
|
24
|
+
"name": "Gokhan Kurt",
|
|
25
|
+
"email": "krtgkn@gmail.com",
|
|
26
|
+
"url": "https://gkurt.com"
|
|
27
|
+
},
|
|
28
|
+
"repository": {
|
|
29
|
+
"type": "git",
|
|
30
|
+
"url": "git+https://github.com/gkurt/prosebook.git"
|
|
31
|
+
},
|
|
32
|
+
"bin": {
|
|
33
|
+
"prosebook": "./dist/cli.js"
|
|
34
|
+
},
|
|
35
|
+
"files": [
|
|
36
|
+
"dist",
|
|
37
|
+
"src",
|
|
38
|
+
"schema",
|
|
39
|
+
"README.md",
|
|
40
|
+
"LICENSE"
|
|
41
|
+
],
|
|
42
|
+
"type": "module",
|
|
43
|
+
"sideEffects": false,
|
|
44
|
+
"imports": {
|
|
45
|
+
"#*": "./*"
|
|
46
|
+
},
|
|
47
|
+
"exports": {
|
|
48
|
+
".": {
|
|
49
|
+
"prosebook@dev": "./src/index.ts",
|
|
50
|
+
"import": {
|
|
51
|
+
"types": "./dist/index.d.ts",
|
|
52
|
+
"default": "./dist/index.js"
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
"./react": {
|
|
56
|
+
"prosebook@dev": "./src/react/index.tsx",
|
|
57
|
+
"import": {
|
|
58
|
+
"types": "./dist/react/index.d.ts",
|
|
59
|
+
"default": "./dist/react/index.js"
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
"./vite": {
|
|
63
|
+
"prosebook@dev": "./src/vite.ts",
|
|
64
|
+
"import": {
|
|
65
|
+
"types": "./dist/vite.d.ts",
|
|
66
|
+
"default": "./dist/vite.js"
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
"./config": {
|
|
70
|
+
"prosebook@dev": "./src/tools/config.ts",
|
|
71
|
+
"import": {
|
|
72
|
+
"types": "./dist/config.d.ts",
|
|
73
|
+
"default": "./dist/config.js"
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
"./tools": {
|
|
77
|
+
"prosebook@dev": "./src/tools/index.ts",
|
|
78
|
+
"import": {
|
|
79
|
+
"types": "./dist/tools.d.ts",
|
|
80
|
+
"default": "./dist/tools.js"
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
"./package.json": "./package.json"
|
|
84
|
+
},
|
|
85
|
+
"scripts": {
|
|
86
|
+
"typecheck": "tsc",
|
|
87
|
+
"lint": "oxlint",
|
|
88
|
+
"format": "oxfmt",
|
|
89
|
+
"check": "oxlint && oxfmt --check",
|
|
90
|
+
"fix": "oxlint --fix && oxfmt",
|
|
91
|
+
"test": "bun test --conditions=prosebook@dev",
|
|
92
|
+
"checks": "bun check && bun typecheck && bun run test",
|
|
93
|
+
"build": "tsdown",
|
|
94
|
+
"prepack": "tsdown",
|
|
95
|
+
"cli": "bun --conditions=prosebook@dev src/cli.ts",
|
|
96
|
+
"example": "vite examples/react-app",
|
|
97
|
+
"example:build": "vite build examples/react-app",
|
|
98
|
+
"site": "rm -rf _site && mkdir -p _site && cp -R site/* _site/",
|
|
99
|
+
"prepare": "husky",
|
|
100
|
+
"tegami": "bun scripts/tegami.mts"
|
|
101
|
+
},
|
|
102
|
+
"dependencies": {
|
|
103
|
+
"@formatjs/icu-messageformat-parser": "^3.5.22",
|
|
104
|
+
"messageformat": "^4.1.0",
|
|
105
|
+
"oxc-parser": "^0.156.0",
|
|
106
|
+
"yaml": "^2.9.1"
|
|
107
|
+
},
|
|
108
|
+
"devDependencies": {
|
|
109
|
+
"@happy-dom/global-registrator": "^21.0.4",
|
|
110
|
+
"@types/bun": "^1.4.4",
|
|
111
|
+
"@types/react": "^19.3.0",
|
|
112
|
+
"@types/react-dom": "^19.3.0",
|
|
113
|
+
"@vitejs/plugin-react": "^6.1.2",
|
|
114
|
+
"husky": "^9.1.7",
|
|
115
|
+
"lint-staged": "^17.6.0",
|
|
116
|
+
"oxfmt": "^0.75.0",
|
|
117
|
+
"oxlint": "^1.90.0",
|
|
118
|
+
"oxlint-tsgolint": "^7.0.2005",
|
|
119
|
+
"react": "^19.3.1",
|
|
120
|
+
"react-dom": "^19.3.1",
|
|
121
|
+
"tegami": "^1.5.0",
|
|
122
|
+
"tsdown": "^0.23.4",
|
|
123
|
+
"typescript": "^7.0.2",
|
|
124
|
+
"vite": "^8.3.5"
|
|
125
|
+
},
|
|
126
|
+
"peerDependencies": {
|
|
127
|
+
"react": ">=18",
|
|
128
|
+
"typescript": ">=7",
|
|
129
|
+
"vite": ">=6"
|
|
130
|
+
},
|
|
131
|
+
"peerDependenciesMeta": {
|
|
132
|
+
"react": {
|
|
133
|
+
"optional": true
|
|
134
|
+
},
|
|
135
|
+
"vite": {
|
|
136
|
+
"optional": true
|
|
137
|
+
},
|
|
138
|
+
"typescript": {
|
|
139
|
+
"optional": true
|
|
140
|
+
}
|
|
141
|
+
},
|
|
142
|
+
"lint-staged": {
|
|
143
|
+
"*": [
|
|
144
|
+
"oxlint --fix --no-error-on-unmatched-pattern",
|
|
145
|
+
"oxfmt --no-error-on-unmatched-pattern"
|
|
146
|
+
]
|
|
147
|
+
}
|
|
148
|
+
}
|