@oktis-works/plugin-runtime 0.5.10 → 0.7.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.
Files changed (46) hide show
  1. package/dist/bootstrap.d.ts +86 -21
  2. package/dist/bootstrap.d.ts.map +1 -1
  3. package/dist/bootstrap.js +254 -42
  4. package/dist/bootstrap.js.map +1 -1
  5. package/dist/content-query.d.ts +29 -0
  6. package/dist/content-query.d.ts.map +1 -0
  7. package/dist/content-query.js +109 -0
  8. package/dist/content-query.js.map +1 -0
  9. package/dist/hook-registry.d.ts +21 -21
  10. package/dist/hook-registry.d.ts.map +1 -1
  11. package/dist/hook-registry.js +26 -26
  12. package/dist/hook-registry.js.map +1 -1
  13. package/dist/http.d.ts +49 -0
  14. package/dist/http.d.ts.map +1 -0
  15. package/dist/http.js +313 -0
  16. package/dist/http.js.map +1 -0
  17. package/dist/i18n.d.ts +16 -0
  18. package/dist/i18n.d.ts.map +1 -0
  19. package/dist/i18n.js +73 -0
  20. package/dist/i18n.js.map +1 -0
  21. package/dist/index.d.ts +2 -1
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +1 -1
  24. package/dist/index.js.map +1 -1
  25. package/dist/loader.js +3 -3
  26. package/dist/loader.js.map +1 -1
  27. package/dist/manifest.d.ts +11 -6
  28. package/dist/manifest.d.ts.map +1 -1
  29. package/dist/manifest.js +227 -17
  30. package/dist/manifest.js.map +1 -1
  31. package/dist/plugin-api.d.ts +191 -38
  32. package/dist/plugin-api.d.ts.map +1 -1
  33. package/dist/plugin-api.js +572 -10
  34. package/dist/plugin-api.js.map +1 -1
  35. package/dist/plugin-migrations.d.ts +15 -0
  36. package/dist/plugin-migrations.d.ts.map +1 -0
  37. package/dist/plugin-migrations.js +68 -0
  38. package/dist/plugin-migrations.js.map +1 -0
  39. package/dist/sandbox.d.ts +13 -11
  40. package/dist/sandbox.d.ts.map +1 -1
  41. package/dist/sandbox.js +11 -9
  42. package/dist/sandbox.js.map +1 -1
  43. package/dist/style-isolation.d.ts +3 -3
  44. package/dist/style-isolation.js +6 -6
  45. package/dist/style-isolation.js.map +1 -1
  46. package/package.json +7 -6
package/dist/http.d.ts ADDED
@@ -0,0 +1,49 @@
1
+ import { Agent } from 'undici';
2
+ import { type PluginHttpApi } from '@oktis-works/plugin-sdk';
3
+ export declare const DEFAULT_TIMEOUT_MS = 10000;
4
+ export declare const MAX_TIMEOUT_MS = 60000;
5
+ export declare const DEFAULT_MAX_BYTES: number;
6
+ export declare const MAX_REDIRECTS = 3;
7
+ export interface ResolvedAddress {
8
+ address: string;
9
+ family: number;
10
+ }
11
+ /** Erro de api.http com flag de retentativa. */
12
+ export declare class HttpError extends Error {
13
+ readonly retriable: boolean;
14
+ constructor(message: string, retriable: boolean);
15
+ }
16
+ /** Is the IPv4 publicly routable? Fail-closed on any special/reserved range. */
17
+ export declare function isPublicIpv4(ip: string): boolean;
18
+ /** Is the IPv6 publicly routable? Fail-closed: only 2000::/3 (global unicast). */
19
+ export declare function isPublicIpv6(ip: string): boolean;
20
+ /** Any non-public IP in the list → false. */
21
+ export declare function isPublicIp(ip: string): boolean;
22
+ /** Picks the first public address (for pinning). Throws when none. */
23
+ export declare function selectPublicAddresses(addresses: ResolvedAddress[]): ResolvedAddress;
24
+ /**
25
+ * Manifest allowlist: exact entry or `*.suffix.com` (subdomains — the apex
26
+ * needs its own entry). Empty/absent list = any host (advertising is still
27
+ * guaranteed by IP validation).
28
+ */
29
+ export declare function isAllowedHost(hostname: string, allowHosts?: string[]): boolean;
30
+ type Resolver = (hostname: string) => Promise<ResolvedAddress[]>;
31
+ /**
32
+ * Lookup "puro" usado pelo undici Agent: resolve E valida no MESMO passo —
33
+ * the returned IP is exactly what the connection uses (real pinning, no
34
+ * de rebinding).
35
+ */
36
+ export declare function createSafeLookup(resolve?: Resolver): (hostname: string, _options: unknown, callback: (err: NodeJS.ErrnoException | null, address?: string | never, family?: number) => void) => void;
37
+ /** Dispatcher compartilhado com lookup validado (pinning). */
38
+ export declare function getSafeAgent(): Agent;
39
+ /** Validates a target before touching the network (scheme + allowlist + public DNS). */
40
+ export declare function validateTargetUrl(rawUrl: string, allowHosts?: string[]): Promise<URL>;
41
+ export interface HttpApiConfig {
42
+ /** Allowlist estrita do manifesto (httpPolicy.allowHosts). */
43
+ allowHosts?: string[];
44
+ /** Permission gate (http:outbound) — injected by the PluginAPI factory. */
45
+ requirePermission: (permission: string) => void;
46
+ }
47
+ export declare function createHttpApi(config: HttpApiConfig): PluginHttpApi;
48
+ export {};
49
+ //# sourceMappingURL=http.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAC/B,OAAO,EAAe,KAAK,aAAa,EAAmD,MAAM,yBAAyB,CAAC;AAE3H,eAAO,MAAM,kBAAkB,QAAS,CAAC;AACzC,eAAO,MAAM,cAAc,QAAS,CAAC;AACrC,eAAO,MAAM,iBAAiB,QAAkB,CAAC;AACjD,eAAO,MAAM,aAAa,IAAI,CAAC;AAE/B,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,gDAAgD;AAChD,qBAAa,SAAU,SAAQ,KAAK;IAGhC,QAAQ,CAAC,SAAS,EAAE,OAAO;gBAD3B,OAAO,EAAE,MAAM,EACN,SAAS,EAAE,OAAO;CAK9B;AAED,gFAAgF;AAChF,wBAAgB,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAoBhD;AAED,kFAAkF;AAClF,wBAAgB,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAkBhD;AAED,6CAA6C;AAC7C,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAE9C;AAED,sEAAsE;AACtE,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,eAAe,EAAE,GAAG,eAAe,CASnF;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,GAAG,OAAO,CAY9E;AAED,KAAK,QAAQ,GAAG,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC;AAQjE;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,GAAE,QAA0B,cAEtD,MAAM,YACN,OAAO,YACP,CAAC,GAAG,EAAE,MAAM,CAAC,cAAc,GAAG,IAAI,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,KAAK,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,IAAI,KAC/F,IAAI,CAeR;AAID,8DAA8D;AAC9D,wBAAgB,YAAY,IAAI,KAAK,CAUpC;AAED,wFAAwF;AACxF,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,CAmC3F;AAwGD,MAAM,WAAW,aAAa;IAC5B,8DAA8D;IAC9D,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,2EAA2E;IAC3E,iBAAiB,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;CACjD;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,aAAa,GAAG,aAAa,CAyClE"}
package/dist/http.js ADDED
@@ -0,0 +1,313 @@
1
+ // @oktis-works/plugin-runtime - api.http: cliente HTTP externo anti-SSRF
2
+ //
3
+ // Item 4 do plugin-parity-plan (+ Item 16 egress isolation). Camadas:
4
+ //
5
+ // 1. allowlist `httpPolicy.allowHosts` do manifesto (quando declarada);
6
+ // 2. apenas scheme http/https;
7
+ // 3. DNS pre-validation per HOP — EVERY resolved IP must be
8
+ // public (blocks RFC1918, loopback, link-local 169.254.169.254 =
9
+ // metadata de cloud, CGNAT, multicast, ULA/link-local IPv6);
10
+ // 4. DNS pinning: o dispatcher (undici Agent) conecta exatamente no IP
11
+ // validado (elimina a janela de DNS rebinding entre lookup e connect);
12
+ // 5. `manual` redirects with re-validation on every hop (max 3);
13
+ // 6. timeout por tentativa e teto de corpo;
14
+ // 7. retries only on network errors/5xx (GET/HEAD by default).
15
+ //
16
+ // Fail-closed: DNS that fails or resolves to a non-public IP NEVER lets the
17
+ // request through, even if the runtime fetch ignored the dispatcher (Bun).
18
+ import { promises as dnsPromises } from 'node:dns';
19
+ import { Agent } from 'undici';
20
+ import { PERMISSIONS } from '@oktis-works/plugin-sdk';
21
+ export const DEFAULT_TIMEOUT_MS = 10_000;
22
+ export const MAX_TIMEOUT_MS = 60_000;
23
+ export const DEFAULT_MAX_BYTES = 5 * 1024 * 1024;
24
+ export const MAX_REDIRECTS = 3;
25
+ /** Erro de api.http com flag de retentativa. */
26
+ export class HttpError extends Error {
27
+ retriable;
28
+ constructor(message, retriable) {
29
+ super(message);
30
+ this.retriable = retriable;
31
+ this.name = 'HttpError';
32
+ }
33
+ }
34
+ /** Is the IPv4 publicly routable? Fail-closed on any special/reserved range. */
35
+ export function isPublicIpv4(ip) {
36
+ const parts = ip.split('.');
37
+ if (parts.length !== 4)
38
+ return false;
39
+ const octets = parts.map((part) => Number(part));
40
+ if (octets.some((octet) => !Number.isInteger(octet) || octet < 0 || octet > 255))
41
+ return false;
42
+ const a = octets[0] ?? 0;
43
+ const b = octets[1] ?? 0;
44
+ const c = octets[2] ?? 0;
45
+ if (a === 0)
46
+ return false; // 0.0.0.0/8 "este host"
47
+ if (a === 10)
48
+ return false; // RFC1918
49
+ if (a === 127)
50
+ return false; // loopback
51
+ if (a === 169 && b === 254)
52
+ return false; // link-local = metadata cloud (169.254.169.254)
53
+ if (a === 172 && b >= 16 && b <= 31)
54
+ return false; // RFC1918
55
+ if (a === 192 && b === 168)
56
+ return false; // RFC1918
57
+ if (a === 100 && b >= 64 && b <= 127)
58
+ return false; // CGNAT RFC6598
59
+ if (a === 192 && b === 0 && c === 0)
60
+ return false; // RFC6890 IETF
61
+ if (a === 198 && (b === 18 || b === 19))
62
+ return false; // benchmark RFC2544
63
+ if (a >= 224)
64
+ return false; // multicast (224/4) + broadcast/reservado (240/4)
65
+ return true;
66
+ }
67
+ /** Is the IPv6 publicly routable? Fail-closed: only 2000::/3 (global unicast). */
68
+ export function isPublicIpv6(ip) {
69
+ const bare = (ip.split('%')[0] ?? '').toLowerCase();
70
+ if (bare === '::' || bare === '::1')
71
+ return false;
72
+ // IPv4-mapped ::ffff:a.b.c.d → aplica as regras de IPv4
73
+ const mapped = /^::ffff:(\d{1,3}(?:\.\d{1,3}){3})$/.exec(bare);
74
+ if (mapped?.[1])
75
+ return isPublicIpv4(mapped[1]);
76
+ // leading '::' compression outside mapped → special/deprecated → blocked
77
+ if (bare.startsWith('::'))
78
+ return false;
79
+ const firstBlock = bare.split(':')[0] ?? '';
80
+ if (firstBlock.includes('.'))
81
+ return false; // v4-suffix not handled above
82
+ const hextet = Number.parseInt(firstBlock, 16);
83
+ if (Number.isNaN(hextet))
84
+ return false;
85
+ // 2000::/3 = the only assigned global unicast block
86
+ return hextet >= 0x2000 && hextet <= 0x3fff;
87
+ }
88
+ /** Any non-public IP in the list → false. */
89
+ export function isPublicIp(ip) {
90
+ return ip.includes(':') ? isPublicIpv6(ip) : isPublicIpv4(ip);
91
+ }
92
+ /** Picks the first public address (for pinning). Throws when none. */
93
+ export function selectPublicAddresses(addresses) {
94
+ const safe = addresses.find((entry) => isPublicIp(entry.address));
95
+ if (!safe) {
96
+ throw new HttpError(`host resolves only to non-public address(es): ${addresses.map((entry) => entry.address).join(', ')}`, false);
97
+ }
98
+ return safe;
99
+ }
100
+ /**
101
+ * Manifest allowlist: exact entry or `*.suffix.com` (subdomains — the apex
102
+ * needs its own entry). Empty/absent list = any host (advertising is still
103
+ * guaranteed by IP validation).
104
+ */
105
+ export function isAllowedHost(hostname, allowHosts) {
106
+ if (!allowHosts || allowHosts.length === 0)
107
+ return true;
108
+ const host = hostname.toLowerCase().replace(/^\[|\]$/g, '');
109
+ return allowHosts.some((entry) => {
110
+ const pattern = entry.trim().toLowerCase();
111
+ if (!pattern)
112
+ return false;
113
+ if (pattern.startsWith('*.')) {
114
+ const suffix = pattern.slice(1); // ".sufixo.com"
115
+ return host.endsWith(suffix) && host.length > suffix.length;
116
+ }
117
+ return host === pattern;
118
+ });
119
+ }
120
+ const defaultResolver = async (hostname) => {
121
+ const bare = hostname.replace(/^\[|\]$/g, '');
122
+ const addresses = await dnsPromises.lookup(bare, { all: true, verbatim: true });
123
+ return addresses.map((entry) => ({ address: entry.address, family: entry.family }));
124
+ };
125
+ /**
126
+ * Lookup "puro" usado pelo undici Agent: resolve E valida no MESMO passo —
127
+ * the returned IP is exactly what the connection uses (real pinning, no
128
+ * de rebinding).
129
+ */
130
+ export function createSafeLookup(resolve = defaultResolver) {
131
+ return (hostname, _options, callback) => {
132
+ resolve(hostname).then((addresses) => {
133
+ try {
134
+ const safe = selectPublicAddresses(addresses);
135
+ callback(null, safe.address, safe.family);
136
+ }
137
+ catch (error) {
138
+ callback(error);
139
+ }
140
+ }, (error) => {
141
+ callback(error);
142
+ });
143
+ };
144
+ }
145
+ let sharedAgent = null;
146
+ /** Dispatcher compartilhado com lookup validado (pinning). */
147
+ export function getSafeAgent() {
148
+ if (!sharedAgent) {
149
+ sharedAgent = new Agent({
150
+ connect: {
151
+ // Signature compatible with net.LookupFunction via a structural cast
152
+ lookup: createSafeLookup(),
153
+ },
154
+ });
155
+ }
156
+ return sharedAgent;
157
+ }
158
+ /** Validates a target before touching the network (scheme + allowlist + public DNS). */
159
+ export async function validateTargetUrl(rawUrl, allowHosts) {
160
+ let url;
161
+ try {
162
+ url = new URL(rawUrl);
163
+ }
164
+ catch {
165
+ throw new HttpError(`invalid URL: ${rawUrl}`, false);
166
+ }
167
+ if (url.protocol !== 'http:' && url.protocol !== 'https:') {
168
+ throw new HttpError(`scheme not allowed: ${url.protocol}`, false);
169
+ }
170
+ if (!isAllowedHost(url.hostname, allowHosts)) {
171
+ throw new HttpError(`host "${url.hostname}" is not in httpPolicy.allowHosts`, false);
172
+ }
173
+ let addresses;
174
+ try {
175
+ addresses = await defaultResolver(url.hostname);
176
+ }
177
+ catch (error) {
178
+ throw new HttpError(`DNS resolution failed for ${url.hostname}: ${error instanceof Error ? error.message : String(error)}`, false);
179
+ }
180
+ if (addresses.length === 0) {
181
+ throw new HttpError(`no addresses for ${url.hostname}`, false);
182
+ }
183
+ // EVERY IP must be public (round-robin with one private IP is also blocked)
184
+ const unsafe = addresses.filter((entry) => !isPublicIp(entry.address));
185
+ if (unsafe.length > 0) {
186
+ throw new HttpError(`host ${url.hostname} resolves to non-public address(es): ${unsafe.map((entry) => entry.address).join(', ')}`, false);
187
+ }
188
+ return url;
189
+ }
190
+ async function readBodyCapped(response, maxBytes) {
191
+ if (!response.body)
192
+ return '';
193
+ const reader = response.body.getReader();
194
+ const chunks = [];
195
+ let total = 0;
196
+ try {
197
+ for (;;) {
198
+ const { done, value } = await reader.read();
199
+ if (done)
200
+ break;
201
+ if (value) {
202
+ total += value.byteLength;
203
+ if (total > maxBytes) {
204
+ await reader.cancel().catch(() => undefined);
205
+ throw new HttpError(`response body exceeds limit of ${maxBytes} bytes`, false);
206
+ }
207
+ chunks.push(value);
208
+ }
209
+ }
210
+ }
211
+ finally {
212
+ reader.releaseLock();
213
+ }
214
+ const merged = Buffer.concat(chunks.map((chunk) => Buffer.from(chunk)));
215
+ return merged.toString('utf8');
216
+ }
217
+ async function readResponse(response, maxBytes) {
218
+ const body = await readBodyCapped(response, maxBytes);
219
+ const headers = {};
220
+ response.headers.forEach((value, key) => {
221
+ headers[key.toLowerCase()] = value;
222
+ });
223
+ return {
224
+ status: response.status,
225
+ ok: response.ok,
226
+ headers,
227
+ body,
228
+ json() {
229
+ return JSON.parse(body);
230
+ },
231
+ };
232
+ }
233
+ /** Executa a cadeia de redirects (cada hop revalidado) — 1 tentativa. */
234
+ async function runRedirects(rawUrl, allowHosts, config) {
235
+ let currentUrl = rawUrl;
236
+ let method = config.method;
237
+ let body = config.body;
238
+ for (let hop = 0; hop <= MAX_REDIRECTS; hop += 1) {
239
+ const target = await validateTargetUrl(currentUrl, allowHosts);
240
+ const fetchInit = {
241
+ method,
242
+ headers: config.headers,
243
+ body: method === 'GET' || method === 'HEAD' ? undefined : body,
244
+ redirect: 'manual',
245
+ signal: AbortSignal.timeout(config.timeoutMs),
246
+ // Node/undici: conecta no IP validado (pinning). Runtimes que ignoram
247
+ // `dispatcher` (Bun) remain protected by the pre-validation above.
248
+ dispatcher: getSafeAgent(),
249
+ };
250
+ const response = await fetch(target.toString(), fetchInit);
251
+ if (response.status >= 300 && response.status < 400) {
252
+ const location = response.headers.get('location');
253
+ if (!location)
254
+ return readResponse(response, config.maxBytes);
255
+ if (hop === MAX_REDIRECTS) {
256
+ throw new HttpError(`too many redirects (max ${MAX_REDIRECTS})`, false);
257
+ }
258
+ // Libera o corpo do redirect sem consumir
259
+ await response.body?.cancel().catch(() => undefined);
260
+ currentUrl = new URL(location, target).toString();
261
+ if (response.status === 303 ||
262
+ ((response.status === 301 || response.status === 302) && method === 'POST')) {
263
+ method = 'GET';
264
+ body = undefined;
265
+ }
266
+ continue;
267
+ }
268
+ return readResponse(response, config.maxBytes);
269
+ }
270
+ throw new HttpError(`too many redirects (max ${MAX_REDIRECTS})`, false);
271
+ }
272
+ export function createHttpApi(config) {
273
+ async function request(rawUrl, options = {}) {
274
+ config.requirePermission(PERMISSIONS.HTTP_OUTBOUND);
275
+ const method = (options.method ?? 'GET').toUpperCase();
276
+ const timeoutMs = Math.min(Math.max(options.timeoutMs ?? DEFAULT_TIMEOUT_MS, 1), MAX_TIMEOUT_MS);
277
+ const maxBytes = options.maxBytes ?? DEFAULT_MAX_BYTES;
278
+ const retries = options.retries ?? (method === 'GET' || method === 'HEAD' ? 2 : 0);
279
+ const attemptConfig = {
280
+ method,
281
+ headers: options.headers,
282
+ body: options.body,
283
+ timeoutMs,
284
+ maxBytes,
285
+ };
286
+ let lastError;
287
+ for (let attempt = 0; attempt <= retries; attempt += 1) {
288
+ try {
289
+ const response = await runRedirects(rawUrl, config.allowHosts, attemptConfig);
290
+ if (response.status >= 500 && attempt < retries) {
291
+ lastError = new HttpError(`upstream ${response.status}`, true);
292
+ await new Promise((resolve) => setTimeout(resolve, 250 * 2 ** attempt));
293
+ continue;
294
+ }
295
+ return response;
296
+ }
297
+ catch (error) {
298
+ lastError = error;
299
+ const retriable = error instanceof HttpError ? error.retriable : true; // rede/timeout
300
+ if (!retriable || attempt >= retries)
301
+ break;
302
+ await new Promise((resolve) => setTimeout(resolve, 250 * 2 ** attempt));
303
+ }
304
+ }
305
+ throw lastError instanceof Error ? lastError : new Error(String(lastError));
306
+ }
307
+ return {
308
+ request,
309
+ get: (url, options) => request(url, { ...options, method: 'GET' }),
310
+ post: (url, body, options) => request(url, { ...options, method: 'POST', body }),
311
+ };
312
+ }
313
+ //# sourceMappingURL=http.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"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"}
package/dist/i18n.d.ts ADDED
@@ -0,0 +1,16 @@
1
+ import type { PluginManifest, PluginI18nApi } from '@oktis-works/plugin-sdk';
2
+ /**
3
+ * Fallback chain for a locale: `pt-BR` → [`pt-BR`, `pt`, `en`];
4
+ * `en` → [`en`]; `fr` → [`fr`, `en`]. Duplicates removed.
5
+ */
6
+ export declare function i18nFallbackChain(locale: string): string[];
7
+ /** Replaces `{token}` placeholders with stringified params (missing → kept). */
8
+ export declare function i18nInterpolate(template: string, params?: Record<string, unknown>): string;
9
+ /**
10
+ * Loads manifest `locales[]` JSON files (flat key/value) into the plugin's
11
+ * i18n store. The filename defines the locale (`locales/pt-BR.json` →
12
+ * `pt-BR`). Malformed/out-of-tree files are skipped — never breaks boot.
13
+ * Returns the number of successfully loaded files.
14
+ */
15
+ export declare function loadPluginLocales(pluginDir: string, manifest: PluginManifest, i18n: PluginI18nApi): Promise<number>;
16
+ //# sourceMappingURL=i18n.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"i18n.d.ts","sourceRoot":"","sources":["../src/i18n.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAE7E;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAU1D;AAED,gFAAgF;AAChF,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAM1F;AAED;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,cAAc,EACxB,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,MAAM,CAAC,CAwBjB"}
package/dist/i18n.js ADDED
@@ -0,0 +1,73 @@
1
+ // @oktis-works/plugin-runtime - Plugin i18n helpers (Item 9 do plugin-parity-plan)
2
+ //
3
+ // Server-side translations for plugins:
4
+ // - `api.i18n.load(locale, bundle)` merges flat { key: string } bundles;
5
+ // - `api.i18n.translate(key, params?, locale?)` resolves through the
6
+ // fallback chain (requested locale → base language → 'en' → key) with
7
+ // {param} interpolation;
8
+ // - manifest `locales[]` JSON files (flat key/value) are loaded at boot.
9
+ import { readFile } from 'node:fs/promises';
10
+ import { join } from 'node:path';
11
+ /**
12
+ * Fallback chain for a locale: `pt-BR` → [`pt-BR`, `pt`, `en`];
13
+ * `en` → [`en`]; `fr` → [`fr`, `en`]. Duplicates removed.
14
+ */
15
+ export function i18nFallbackChain(locale) {
16
+ const chain = [];
17
+ const push = (value) => {
18
+ if (value && !chain.includes(value))
19
+ chain.push(value);
20
+ };
21
+ push(locale);
22
+ const base = locale.split('-')[0];
23
+ if (base)
24
+ push(base);
25
+ push('en');
26
+ return chain;
27
+ }
28
+ /** Replaces `{token}` placeholders with stringified params (missing → kept). */
29
+ export function i18nInterpolate(template, params) {
30
+ if (!params || typeof params !== 'object')
31
+ return template;
32
+ return template.replace(/\{([a-zA-Z0-9_]+)\}/g, (match, token) => {
33
+ const value = params[token];
34
+ return value === undefined || value === null ? match : String(value);
35
+ });
36
+ }
37
+ /**
38
+ * Loads manifest `locales[]` JSON files (flat key/value) into the plugin's
39
+ * i18n store. The filename defines the locale (`locales/pt-BR.json` →
40
+ * `pt-BR`). Malformed/out-of-tree files are skipped — never breaks boot.
41
+ * Returns the number of successfully loaded files.
42
+ */
43
+ export async function loadPluginLocales(pluginDir, manifest, i18n) {
44
+ const files = manifest.locales;
45
+ if (!Array.isArray(files) || files.length === 0)
46
+ return 0;
47
+ let loaded = 0;
48
+ for (const relative of files) {
49
+ if (typeof relative !== 'string' || relative.includes('..') || relative.startsWith('/'))
50
+ continue;
51
+ try {
52
+ const raw = await readFile(join(pluginDir, relative), 'utf8');
53
+ const parsed = JSON.parse(raw);
54
+ if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed))
55
+ continue;
56
+ const locale = relative.replace(/\.json$/, '').split('/').pop() ?? '';
57
+ if (!locale)
58
+ continue;
59
+ const bundle = {};
60
+ for (const [key, value] of Object.entries(parsed)) {
61
+ if (typeof value === 'string')
62
+ bundle[key] = value;
63
+ }
64
+ i18n.load(locale, bundle);
65
+ loaded += 1;
66
+ }
67
+ catch {
68
+ // malformed locale file — skip (translation falls back to the key)
69
+ }
70
+ }
71
+ return loaded;
72
+ }
73
+ //# sourceMappingURL=i18n.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"i18n.js","sourceRoot":"","sources":["../src/i18n.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -6,8 +6,9 @@ export { readPluginManifest, normalizePluginManifest } from './manifest.js';
6
6
  export type { ManifestSource, ReadManifestResult } from './manifest.js';
7
7
  export { HookRegistry, HookRegistryStore, getHookRegistry, getHookRegistryStore, setHookRegistry, setHookRegistryStore, setHookTenantResolver, getCurrentHookTenantId, } from './hook-registry.js';
8
8
  export type { AddHookOptions, AuditLogEntry, HookCallback } from './hook-registry.js';
9
- export { bootstrapPlugins, resetLoadedPlugins, listLoadedScopes, unloadScope, unloadTenant, getLoadedPluginRoutes } from './bootstrap.js';
9
+ export { bootstrapPlugins, resetLoadedPlugins, listLoadedScopes, unloadScope, unloadTenant, getLoadedPluginRoutes, getLoadedPluginJobHandlers } from './bootstrap.js';
10
10
  export type { BootstrapPluginsOptions, BootstrapPluginsSql, PluginBootstrapResult, } from './bootstrap.js';
11
11
  export { createPluginApi, type PluginAPI, type PluginContext, type RouteDefinition, type TenantInfo, type UserInfo, type PluginApiDependencies, type PluginApiInternal, } from './plugin-api.js';
12
+ export type { PluginFieldTypeManifest } from '@oktis-works/plugin-sdk';
12
13
  export { scopePluginCss, getPluginScopeAttribute, wrapWithPluginScope, lintPluginCss, } from './style-isolation.js';
13
14
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,YAAY,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAC5E,YAAY,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACxE,OAAO,EACL,YAAY,EACZ,iBAAiB,EACjB,eAAe,EACf,oBAAoB,EACpB,eAAe,EACf,oBAAoB,EACpB,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACtF,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,WAAW,EAAE,YAAY,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAC1I,YAAY,EACV,uBAAuB,EACvB,mBAAmB,EACnB,qBAAqB,GACtB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,eAAe,EACf,KAAK,SAAS,EACd,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,UAAU,EACf,KAAK,QAAQ,EACb,KAAK,qBAAqB,EAC1B,KAAK,iBAAiB,GACvB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,cAAc,EACd,uBAAuB,EACvB,mBAAmB,EACnB,aAAa,GACd,MAAM,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,YAAY,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAC5E,YAAY,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACxE,OAAO,EACL,YAAY,EACZ,iBAAiB,EACjB,eAAe,EACf,oBAAoB,EACpB,eAAe,EACf,oBAAoB,EACpB,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACtF,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,WAAW,EAAE,YAAY,EAAE,qBAAqB,EAAE,0BAA0B,EAAE,MAAM,gBAAgB,CAAC;AACtK,YAAY,EACV,uBAAuB,EACvB,mBAAmB,EACnB,qBAAqB,GACtB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,eAAe,EACf,KAAK,SAAS,EACd,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,UAAU,EACf,KAAK,QAAQ,EACb,KAAK,qBAAqB,EAC1B,KAAK,iBAAiB,GACvB,MAAM,iBAAiB,CAAC;AACzB,YAAY,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AACvE,OAAO,EACL,cAAc,EACd,uBAAuB,EACvB,mBAAmB,EACnB,aAAa,GACd,MAAM,sBAAsB,CAAC"}
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@ export { PluginSandbox } from './sandbox.js';
2
2
  export { PluginLoader } from './loader.js';
3
3
  export { readPluginManifest, normalizePluginManifest } from './manifest.js';
4
4
  export { HookRegistry, HookRegistryStore, getHookRegistry, getHookRegistryStore, setHookRegistry, setHookRegistryStore, setHookTenantResolver, getCurrentHookTenantId, } from './hook-registry.js';
5
- export { bootstrapPlugins, resetLoadedPlugins, listLoadedScopes, unloadScope, unloadTenant, getLoadedPluginRoutes } from './bootstrap.js';
5
+ export { bootstrapPlugins, resetLoadedPlugins, listLoadedScopes, unloadScope, unloadTenant, getLoadedPluginRoutes, getLoadedPluginJobHandlers } from './bootstrap.js';
6
6
  export { createPluginApi, } from './plugin-api.js';
7
7
  export { scopePluginCss, getPluginScopeAttribute, wrapWithPluginScope, lintPluginCss, } from './style-isolation.js';
8
8
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE7C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAE5E,OAAO,EACL,YAAY,EACZ,iBAAiB,EACjB,eAAe,EACf,oBAAoB,EACpB,eAAe,EACf,oBAAoB,EACpB,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,WAAW,EAAE,YAAY,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAM1I,OAAO,EACL,eAAe,GAQhB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,cAAc,EACd,uBAAuB,EACvB,mBAAmB,EACnB,aAAa,GACd,MAAM,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE7C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAE5E,OAAO,EACL,YAAY,EACZ,iBAAiB,EACjB,eAAe,EACf,oBAAoB,EACpB,eAAe,EACf,oBAAoB,EACpB,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,WAAW,EAAE,YAAY,EAAE,qBAAqB,EAAE,0BAA0B,EAAE,MAAM,gBAAgB,CAAC;AAMtK,OAAO,EACL,eAAe,GAQhB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,cAAc,EACd,uBAAuB,EACvB,mBAAmB,EACnB,aAAa,GACd,MAAM,sBAAsB,CAAC"}
package/dist/loader.js CHANGED
@@ -23,10 +23,10 @@ export class PluginLoader {
23
23
  return plugins;
24
24
  }
25
25
  async loadPlugin(manifest, pluginPath) {
26
- // RULE-semver-compatibility: range compatibility.okcms deve satisfazer a versão do CMS
26
+ // RULE-semver-compatibility: the compatibility.okcms range must satisfy the CMS version
27
27
  const compat = manifest.compatibility?.okcms;
28
28
  if (typeof compat === 'string' && validRange(compat) && !satisfies(CMS_VERSION, compat)) {
29
- throw new Error(`Plugin "${manifest.name}" requer OkCMS ${compat}, mas a versão atual é ${CMS_VERSION}`);
29
+ throw new Error(`Plugin "${manifest.name}" requires OkCMS ${compat}, but the current version is ${CMS_VERSION}`);
30
30
  }
31
31
  const entryPath = resolve(join(pluginPath, manifest.main));
32
32
  if (!entryPath.startsWith(this.pluginsDir)) {
@@ -109,7 +109,7 @@ export class PluginLoader {
109
109
  return result.length > 0 ? result : [0];
110
110
  }
111
111
  async loadManifest(pluginPath) {
112
- // Fonte única (WP6): `manifest.json` canônico vence `package.json` (npm).
112
+ // Single source (WP6): the canonical `manifest.json` wins over `package.json` (npm).
113
113
  // Antes a ordem era inversa — um plugin com ambos os arquivos era lido de
114
114
  // um jeito no loader e de outro no sync/CLI.
115
115
  const { manifest } = await readPluginManifest(pluginPath);
@@ -1 +1 @@
1
- {"version":3,"file":"loader.js","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"loader.js","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"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"}
@@ -3,22 +3,27 @@ export type ManifestSource = 'manifest.json' | 'package.json';
3
3
  export interface ReadManifestResult {
4
4
  manifest: PluginManifest | null;
5
5
  source: ManifestSource | null;
6
- /** Problemas encontrados (motivo de recusa, quando `manifest` é null). */
6
+ /** Found issues (the rejection reason when `manifest` is null). */
7
7
  issues: string[];
8
8
  }
9
9
  /**
10
- * Lê o manifesto de um diretório de plugin com precedência única.
10
+ * Valida os campos do schema v2 (tudo opcional — um manifesto v1 continua
11
+ * valid). Returns the found issues; empty = valid.
12
+ */
13
+ export declare function validateManifestV2(merged: Record<string, unknown>): string[];
14
+ /**
15
+ * Reads a plugin directory's manifest with a single precedence rule.
11
16
  *
12
- * @param dir diretório do plugin
17
+ * @param dir the plugin directory
13
18
  * @param options.strict exige `main` e valida `type === 'plugin'` quando
14
- * declarado (usado por sync/instalação/CLI)
19
+ * declared (used by sync/install/CLI)
15
20
  */
16
21
  export declare function readPluginManifest(dir: string, options?: {
17
22
  strict?: boolean;
18
23
  }): Promise<ReadManifestResult>;
19
24
  /**
20
- * Normaliza o manifesto para gravação no banco (mantém só campos conhecidos,
21
- * preservando campos extras legítimos do autor).
25
+ * Normalizes the manifest for database storage (keeps only known fields,
26
+ * preserving the author's legitimate extra fields).
22
27
  */
23
28
  export declare function normalizePluginManifest(manifest: PluginManifest): Record<string, unknown>;
24
29
  //# sourceMappingURL=manifest.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAE9D,MAAM,MAAM,cAAc,GAAG,eAAe,GAAG,cAAc,CAAC;AAE9D,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,cAAc,GAAG,IAAI,CAAC;IAChC,MAAM,EAAE,cAAc,GAAG,IAAI,CAAC;IAC9B,0EAA0E;IAC1E,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAgBD;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,MAAM,EACX,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAO,GACjC,OAAO,CAAC,kBAAkB,CAAC,CAqC7B;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEzF"}
1
+ {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAG9D,MAAM,MAAM,cAAc,GAAG,eAAe,GAAG,cAAc,CAAC;AAE9D,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,cAAc,GAAG,IAAI,CAAC;IAChC,MAAM,EAAE,cAAc,GAAG,IAAI,CAAC;IAC9B,mEAAmE;IACnE,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAUD;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,EAAE,CAmM5E;AAYD;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,MAAM,EACX,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAO,GACjC,OAAO,CAAC,kBAAkB,CAAC,CAiD7B;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEzF"}