@wordrhyme/plugin 0.1.0-alpha.10

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.
Files changed (57) hide show
  1. package/dist/admin/index.d.ts +19 -0
  2. package/dist/admin/index.js +42 -0
  3. package/dist/admin/index.js.map +1 -0
  4. package/dist/artifact.d.ts +17 -0
  5. package/dist/artifact.js +97 -0
  6. package/dist/artifact.js.map +1 -0
  7. package/dist/chunk-3IM3FPTJ.js +1470 -0
  8. package/dist/chunk-3IM3FPTJ.js.map +1 -0
  9. package/dist/chunk-6GDCFR67.js +218 -0
  10. package/dist/chunk-6GDCFR67.js.map +1 -0
  11. package/dist/chunk-7EM22QYB.js +333 -0
  12. package/dist/chunk-7EM22QYB.js.map +1 -0
  13. package/dist/chunk-BI7E5CVM.js +26 -0
  14. package/dist/chunk-BI7E5CVM.js.map +1 -0
  15. package/dist/chunk-BVOTSKM2.js +254 -0
  16. package/dist/chunk-BVOTSKM2.js.map +1 -0
  17. package/dist/chunk-DY44Q4CK.js +188 -0
  18. package/dist/chunk-DY44Q4CK.js.map +1 -0
  19. package/dist/chunk-MZOLSLJ7.js +65 -0
  20. package/dist/chunk-MZOLSLJ7.js.map +1 -0
  21. package/dist/chunk-O4AYK3YP.js +156 -0
  22. package/dist/chunk-O4AYK3YP.js.map +1 -0
  23. package/dist/chunk-UGMYO6AU.js +37 -0
  24. package/dist/chunk-UGMYO6AU.js.map +1 -0
  25. package/dist/client-poND5ovI.d.ts +679 -0
  26. package/dist/client.d.ts +9 -0
  27. package/dist/client.js +68 -0
  28. package/dist/client.js.map +1 -0
  29. package/dist/dev-utils.d.ts +105 -0
  30. package/dist/dev-utils.js +35 -0
  31. package/dist/dev-utils.js.map +1 -0
  32. package/dist/entity-extensions-CnhKoT4k.d.ts +56 -0
  33. package/dist/globalization.d.ts +85 -0
  34. package/dist/globalization.js +53 -0
  35. package/dist/globalization.js.map +1 -0
  36. package/dist/index.d.ts +724 -0
  37. package/dist/index.js +931 -0
  38. package/dist/index.js.map +1 -0
  39. package/dist/locale.d.ts +15 -0
  40. package/dist/locale.js +13 -0
  41. package/dist/locale.js.map +1 -0
  42. package/dist/manifest-CTFX-h0w.d.ts +2053 -0
  43. package/dist/react.d.ts +227 -0
  44. package/dist/react.js +226 -0
  45. package/dist/react.js.map +1 -0
  46. package/dist/release-BDJeO54k.d.ts +230 -0
  47. package/dist/server.d.ts +115 -0
  48. package/dist/server.js +194 -0
  49. package/dist/server.js.map +1 -0
  50. package/dist/time.d.ts +34 -0
  51. package/dist/time.js +31 -0
  52. package/dist/time.js.map +1 -0
  53. package/dist/trpc.d.ts +44 -0
  54. package/dist/trpc.js +11 -0
  55. package/dist/trpc.js.map +1 -0
  56. package/dist/types-BJo3_91V.d.ts +1997 -0
  57. package/package.json +92 -0
@@ -0,0 +1,19 @@
1
+ import * as _trpc_client from '@trpc/client';
2
+
3
+ declare function createBrowserTrpcClient<TRouter>(url: string): _trpc_client.TRPCClient<TRouter>;
4
+ type BrowserTrpcClient<TRouter> = ReturnType<typeof createBrowserTrpcClient<TRouter>>;
5
+ /**
6
+ * Factory to create a typed tRPC client for a plugin's admin UI.
7
+ * Automatically resolves the plugin's normalized ID to the correct URL prefix.
8
+ *
9
+ * Usage: `const api = createPluginTrpcClient<ShopRouter>('shop')`
10
+ */
11
+ declare function createPluginTrpcClient<TRouter>(pluginId: string): BrowserTrpcClient<TRouter>;
12
+ /**
13
+ * Factory to create a typed tRPC client for the admin host root router.
14
+ *
15
+ * Usage: `const hostApi = createHostTrpcClient<AppRouter>()`
16
+ */
17
+ declare function createHostTrpcClient<TRouter>(): _trpc_client.TRPCClient<TRouter>;
18
+
19
+ export { createHostTrpcClient, createPluginTrpcClient };
@@ -0,0 +1,42 @@
1
+ import {
2
+ CLIENT_TIME_ZONE_HEADER,
3
+ getClientTimeZone
4
+ } from "../chunk-6GDCFR67.js";
5
+
6
+ // src/admin/trpc-client.ts
7
+ import { createTRPCClient, httpBatchLink } from "@trpc/client";
8
+ function createBrowserTrpcClient(url) {
9
+ return createTRPCClient({
10
+ links: [
11
+ httpBatchLink({
12
+ url,
13
+ headers() {
14
+ const timezone = getClientTimeZone();
15
+ return timezone ? { [CLIENT_TIME_ZONE_HEADER]: timezone } : {};
16
+ },
17
+ fetch(url2, options) {
18
+ return globalThis.fetch(url2, {
19
+ ...options,
20
+ credentials: "include"
21
+ });
22
+ }
23
+ })
24
+ ]
25
+ });
26
+ }
27
+ function normalizePluginId(pluginId) {
28
+ return pluginId.replace(/^com\.wordrhyme\./, "").replace(/\./g, "-");
29
+ }
30
+ function createPluginTrpcClient(pluginId) {
31
+ const normalizedId = normalizePluginId(pluginId);
32
+ const rootClient = createBrowserTrpcClient("/trpc");
33
+ return rootClient.pluginApis[normalizedId];
34
+ }
35
+ function createHostTrpcClient() {
36
+ return createBrowserTrpcClient("/trpc");
37
+ }
38
+ export {
39
+ createHostTrpcClient,
40
+ createPluginTrpcClient
41
+ };
42
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/admin/trpc-client.ts"],"sourcesContent":["import { createTRPCClient, httpBatchLink } from '@trpc/client';\nimport { CLIENT_TIME_ZONE_HEADER, getClientTimeZone } from '../time';\n\nfunction createBrowserTrpcClient<TRouter>(url: string) {\n // @ts-expect-error -- generic factory; Router constraint is satisfied by consumer's type argument\n return createTRPCClient<TRouter>({\n links: [\n httpBatchLink({\n url,\n headers() {\n const timezone = getClientTimeZone();\n return timezone ? { [CLIENT_TIME_ZONE_HEADER]: timezone } : {};\n },\n fetch(url, options) {\n return globalThis.fetch(url as Parameters<typeof globalThis.fetch>[0], {\n ...(options as RequestInit),\n credentials: 'include',\n });\n },\n }),\n ],\n });\n}\n\ntype BrowserTrpcClient<TRouter> = ReturnType<typeof createBrowserTrpcClient<TRouter>>;\n\nfunction normalizePluginId(pluginId: string) {\n return pluginId.replace(/^com\\.wordrhyme\\./, '').replace(/\\./g, '-');\n}\n\n/**\n * Factory to create a typed tRPC client for a plugin's admin UI.\n * Automatically resolves the plugin's normalized ID to the correct URL prefix.\n *\n * Usage: `const api = createPluginTrpcClient<ShopRouter>('shop')`\n */\nexport function createPluginTrpcClient<TRouter>(pluginId: string) {\n const normalizedId = normalizePluginId(pluginId);\n const rootClient = createBrowserTrpcClient<any>('/trpc') as any;\n\n return rootClient.pluginApis[normalizedId] as BrowserTrpcClient<TRouter>;\n}\n\n/**\n * Factory to create a typed tRPC client for the admin host root router.\n *\n * Usage: `const hostApi = createHostTrpcClient<AppRouter>()`\n */\nexport function createHostTrpcClient<TRouter>() {\n return createBrowserTrpcClient<TRouter>('/trpc');\n}\n"],"mappings":";;;;;;AAAA,SAAS,kBAAkB,qBAAqB;AAGhD,SAAS,wBAAiC,KAAa;AAEnD,SAAO,iBAA0B;AAAA,IAC7B,OAAO;AAAA,MACH,cAAc;AAAA,QACV;AAAA,QACA,UAAU;AACN,gBAAM,WAAW,kBAAkB;AACnC,iBAAO,WAAW,EAAE,CAAC,uBAAuB,GAAG,SAAS,IAAI,CAAC;AAAA,QACjE;AAAA,QACA,MAAMA,MAAK,SAAS;AAChB,iBAAO,WAAW,MAAMA,MAA+C;AAAA,YACnE,GAAI;AAAA,YACJ,aAAa;AAAA,UACjB,CAAC;AAAA,QACL;AAAA,MACJ,CAAC;AAAA,IACL;AAAA,EACJ,CAAC;AACL;AAIA,SAAS,kBAAkB,UAAkB;AACzC,SAAO,SAAS,QAAQ,qBAAqB,EAAE,EAAE,QAAQ,OAAO,GAAG;AACvE;AAQO,SAAS,uBAAgC,UAAkB;AAC9D,QAAM,eAAe,kBAAkB,QAAQ;AAC/C,QAAM,aAAa,wBAA6B,OAAO;AAEvD,SAAO,WAAW,WAAW,YAAY;AAC7C;AAOO,SAAS,uBAAgC;AAC5C,SAAO,wBAAiC,OAAO;AACnD;","names":["url"]}
@@ -0,0 +1,17 @@
1
+ import { P as PluginManifest } from './manifest-CTFX-h0w.js';
2
+ import { P as PluginRelease } from './release-BDJeO54k.js';
3
+ import 'zod';
4
+
5
+ declare const MAX_PLUGIN_ARCHIVE_BYTES: number;
6
+ declare const MAX_PLUGIN_EXTRACTED_BYTES: number;
7
+ declare const MAX_PLUGIN_ARCHIVE_FILES = 5000;
8
+ declare function pluginArtifactSha256(data: Uint8Array): string;
9
+ interface InspectedPluginArtifact {
10
+ manifest: PluginManifest;
11
+ release: PluginRelease;
12
+ entries: Record<string, Uint8Array>;
13
+ archiveSha256: string;
14
+ }
15
+ declare function inspectPluginArtifact(data: Uint8Array): InspectedPluginArtifact;
16
+
17
+ export { type InspectedPluginArtifact, MAX_PLUGIN_ARCHIVE_BYTES, MAX_PLUGIN_ARCHIVE_FILES, MAX_PLUGIN_EXTRACTED_BYTES, inspectPluginArtifact, pluginArtifactSha256 };
@@ -0,0 +1,97 @@
1
+ import {
2
+ pluginArchivePathSchema,
3
+ pluginReleaseSchema
4
+ } from "./chunk-DY44Q4CK.js";
5
+ import {
6
+ pluginManifestSchema
7
+ } from "./chunk-3IM3FPTJ.js";
8
+ import "./chunk-BI7E5CVM.js";
9
+
10
+ // src/artifact.ts
11
+ import { createHash } from "crypto";
12
+ import { strFromU8, unzipSync } from "fflate";
13
+ var MAX_PLUGIN_ARCHIVE_BYTES = 100 * 1024 * 1024;
14
+ var MAX_PLUGIN_EXTRACTED_BYTES = 250 * 1024 * 1024;
15
+ var MAX_PLUGIN_ARCHIVE_FILES = 5e3;
16
+ var RELEASE_PATH = "release.json";
17
+ var CHECKSUM_PATH = "checksums.sha256";
18
+ function verifyChecksums(entries, release) {
19
+ const raw = entries[CHECKSUM_PATH];
20
+ if (!raw) throw new Error(`plugin archive must contain ${CHECKSUM_PATH}`);
21
+ const checksums = /* @__PURE__ */ new Map();
22
+ for (const line of strFromU8(raw).split(/\r?\n/).filter(Boolean)) {
23
+ const match = /^([a-f0-9]{64}) {2}(.+)$/.exec(line);
24
+ if (!match) throw new Error(`invalid ${CHECKSUM_PATH} entry`);
25
+ const checksum = match[1];
26
+ const filePath = match[2];
27
+ pluginArchivePathSchema.parse(filePath);
28
+ if (checksums.has(filePath)) throw new Error(`duplicate ${CHECKSUM_PATH} entry: ${filePath}`);
29
+ checksums.set(filePath, checksum);
30
+ }
31
+ const expectedPaths = [...release.files.map((file) => file.path), RELEASE_PATH].sort();
32
+ if (checksums.size !== expectedPaths.length) {
33
+ throw new Error(`${CHECKSUM_PATH} does not match release contents`);
34
+ }
35
+ for (const filePath of expectedPaths) {
36
+ const content = entries[filePath];
37
+ if (!content || checksums.get(filePath) !== pluginArtifactSha256(content)) {
38
+ throw new Error(`${CHECKSUM_PATH} mismatch: ${filePath}`);
39
+ }
40
+ }
41
+ }
42
+ function pluginArtifactSha256(data) {
43
+ return createHash("sha256").update(data).digest("hex");
44
+ }
45
+ function inspectPluginArtifact(data) {
46
+ if (data.byteLength > MAX_PLUGIN_ARCHIVE_BYTES) {
47
+ throw new Error(`plugin archive exceeds ${MAX_PLUGIN_ARCHIVE_BYTES} bytes`);
48
+ }
49
+ const entries = unzipSync(data);
50
+ const paths = Object.keys(entries);
51
+ if (paths.length > MAX_PLUGIN_ARCHIVE_FILES) {
52
+ throw new Error(`plugin archive exceeds ${MAX_PLUGIN_ARCHIVE_FILES} files`);
53
+ }
54
+ let extractedBytes = 0;
55
+ for (const [filePath, content] of Object.entries(entries)) {
56
+ pluginArchivePathSchema.parse(filePath);
57
+ extractedBytes += content.byteLength;
58
+ if (extractedBytes > MAX_PLUGIN_EXTRACTED_BYTES) {
59
+ throw new Error(`plugin archive exceeds ${MAX_PLUGIN_EXTRACTED_BYTES} extracted bytes`);
60
+ }
61
+ }
62
+ const manifestData = entries["manifest.json"];
63
+ const releaseData = entries[RELEASE_PATH];
64
+ if (!manifestData || !releaseData) {
65
+ throw new Error("plugin archive must contain manifest.json and release.json");
66
+ }
67
+ const manifest = pluginManifestSchema.parse(JSON.parse(strFromU8(manifestData)));
68
+ const release = pluginReleaseSchema.parse(JSON.parse(strFromU8(releaseData)));
69
+ if (manifest.pluginId !== release.pluginId || manifest.version !== release.version) {
70
+ throw new Error("manifest and release identities do not match");
71
+ }
72
+ for (const file of release.files) {
73
+ const content = entries[file.path];
74
+ if (!content) throw new Error(`release file is missing: ${file.path}`);
75
+ if (content.byteLength !== file.size || pluginArtifactSha256(content) !== file.sha256) {
76
+ throw new Error(`release file checksum mismatch: ${file.path}`);
77
+ }
78
+ }
79
+ verifyChecksums(entries, release);
80
+ const allowedPaths = /* @__PURE__ */ new Set([
81
+ ...release.files.map((file) => file.path),
82
+ RELEASE_PATH,
83
+ CHECKSUM_PATH,
84
+ "signature.json"
85
+ ]);
86
+ const undeclared = paths.find((filePath) => !allowedPaths.has(filePath));
87
+ if (undeclared) throw new Error(`archive contains undeclared file: ${undeclared}`);
88
+ return { manifest, release, entries, archiveSha256: pluginArtifactSha256(data) };
89
+ }
90
+ export {
91
+ MAX_PLUGIN_ARCHIVE_BYTES,
92
+ MAX_PLUGIN_ARCHIVE_FILES,
93
+ MAX_PLUGIN_EXTRACTED_BYTES,
94
+ inspectPluginArtifact,
95
+ pluginArtifactSha256
96
+ };
97
+ //# sourceMappingURL=artifact.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/artifact.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { strFromU8, unzipSync } from \"fflate\";\nimport { type PluginManifest, pluginManifestSchema } from \"./manifest\";\nimport { type PluginRelease, pluginArchivePathSchema, pluginReleaseSchema } from \"./release\";\n\nexport const MAX_PLUGIN_ARCHIVE_BYTES = 100 * 1024 * 1024;\nexport const MAX_PLUGIN_EXTRACTED_BYTES = 250 * 1024 * 1024;\nexport const MAX_PLUGIN_ARCHIVE_FILES = 5_000;\n\nconst RELEASE_PATH = \"release.json\";\nconst CHECKSUM_PATH = \"checksums.sha256\";\n\nfunction verifyChecksums(entries: Record<string, Uint8Array>, release: PluginRelease): void {\n const raw = entries[CHECKSUM_PATH];\n if (!raw) throw new Error(`plugin archive must contain ${CHECKSUM_PATH}`);\n\n const checksums = new Map<string, string>();\n for (const line of strFromU8(raw).split(/\\r?\\n/).filter(Boolean)) {\n const match = /^([a-f0-9]{64}) {2}(.+)$/.exec(line);\n if (!match) throw new Error(`invalid ${CHECKSUM_PATH} entry`);\n const checksum = match[1]!;\n const filePath = match[2]!;\n pluginArchivePathSchema.parse(filePath);\n if (checksums.has(filePath)) throw new Error(`duplicate ${CHECKSUM_PATH} entry: ${filePath}`);\n checksums.set(filePath, checksum);\n }\n\n const expectedPaths = [...release.files.map((file) => file.path), RELEASE_PATH].sort();\n if (checksums.size !== expectedPaths.length) {\n throw new Error(`${CHECKSUM_PATH} does not match release contents`);\n }\n for (const filePath of expectedPaths) {\n const content = entries[filePath];\n if (!content || checksums.get(filePath) !== pluginArtifactSha256(content)) {\n throw new Error(`${CHECKSUM_PATH} mismatch: ${filePath}`);\n }\n }\n}\n\nexport function pluginArtifactSha256(data: Uint8Array): string {\n return createHash(\"sha256\").update(data).digest(\"hex\");\n}\n\nexport interface InspectedPluginArtifact {\n manifest: PluginManifest;\n release: PluginRelease;\n entries: Record<string, Uint8Array>;\n archiveSha256: string;\n}\n\nexport function inspectPluginArtifact(data: Uint8Array): InspectedPluginArtifact {\n if (data.byteLength > MAX_PLUGIN_ARCHIVE_BYTES) {\n throw new Error(`plugin archive exceeds ${MAX_PLUGIN_ARCHIVE_BYTES} bytes`);\n }\n\n const entries = unzipSync(data);\n const paths = Object.keys(entries);\n if (paths.length > MAX_PLUGIN_ARCHIVE_FILES) {\n throw new Error(`plugin archive exceeds ${MAX_PLUGIN_ARCHIVE_FILES} files`);\n }\n\n let extractedBytes = 0;\n for (const [filePath, content] of Object.entries(entries)) {\n pluginArchivePathSchema.parse(filePath);\n extractedBytes += content.byteLength;\n if (extractedBytes > MAX_PLUGIN_EXTRACTED_BYTES) {\n throw new Error(`plugin archive exceeds ${MAX_PLUGIN_EXTRACTED_BYTES} extracted bytes`);\n }\n }\n\n const manifestData = entries[\"manifest.json\"];\n const releaseData = entries[RELEASE_PATH];\n if (!manifestData || !releaseData) {\n throw new Error(\"plugin archive must contain manifest.json and release.json\");\n }\n\n const manifest = pluginManifestSchema.parse(JSON.parse(strFromU8(manifestData)));\n const release = pluginReleaseSchema.parse(JSON.parse(strFromU8(releaseData)));\n if (manifest.pluginId !== release.pluginId || manifest.version !== release.version) {\n throw new Error(\"manifest and release identities do not match\");\n }\n\n for (const file of release.files) {\n const content = entries[file.path];\n if (!content) throw new Error(`release file is missing: ${file.path}`);\n if (content.byteLength !== file.size || pluginArtifactSha256(content) !== file.sha256) {\n throw new Error(`release file checksum mismatch: ${file.path}`);\n }\n }\n verifyChecksums(entries, release);\n\n const allowedPaths = new Set([\n ...release.files.map((file) => file.path),\n RELEASE_PATH,\n CHECKSUM_PATH,\n \"signature.json\",\n ]);\n const undeclared = paths.find((filePath) => !allowedPaths.has(filePath));\n if (undeclared) throw new Error(`archive contains undeclared file: ${undeclared}`);\n\n return { manifest, release, entries, archiveSha256: pluginArtifactSha256(data) };\n}\n"],"mappings":"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","names":[]}