@wordrhyme/plugin 0.1.0-alpha.5 → 0.1.0-alpha.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/artifact.d.ts +1 -1
- package/dist/artifact.js +2 -1
- package/dist/artifact.js.map +1 -1
- package/dist/chunk-BI7E5CVM.js +26 -0
- package/dist/chunk-BI7E5CVM.js.map +1 -0
- package/dist/{chunk-46KUIGB6.js → chunk-BVOTSKM2.js} +36 -12
- package/dist/chunk-BVOTSKM2.js.map +1 -0
- package/dist/{chunk-QNCOGISF.js → chunk-FOCLZY64.js} +114 -3
- package/dist/chunk-FOCLZY64.js.map +1 -0
- package/dist/{chunk-YQDKOEUI.js → chunk-NAWUXVZQ.js} +43 -15
- package/dist/chunk-NAWUXVZQ.js.map +1 -0
- package/dist/{chunk-ZUBFLOKU.js → chunk-O4AYK3YP.js} +5 -2
- package/dist/chunk-O4AYK3YP.js.map +1 -0
- package/dist/{client-WXWbuuvd.d.ts → client-CKtDWayV.d.ts} +1 -1
- package/dist/client.d.ts +2 -2
- package/dist/client.js +2 -1
- package/dist/dev-utils.d.ts +6 -2
- package/dist/dev-utils.js +3 -1
- package/dist/{entity-extensions-B5BbZH-m.d.ts → entity-extensions-gJuSTXYZ.d.ts} +2 -2
- package/dist/globalization.d.ts +7 -2
- package/dist/globalization.js +11 -1
- package/dist/index.d.ts +381 -8
- package/dist/index.js +449 -18
- package/dist/index.js.map +1 -1
- package/dist/locale.d.ts +15 -0
- package/dist/locale.js +13 -0
- package/dist/locale.js.map +1 -0
- package/dist/{manifest-CPSCN_Ft.d.ts → manifest-CDTCsMYV.d.ts} +39 -4
- package/dist/react.d.ts +50 -3
- package/dist/react.js +105 -11
- package/dist/react.js.map +1 -1
- package/dist/server.d.ts +5 -4
- package/dist/server.js +1 -1
- package/dist/trpc.d.ts +2 -1
- package/dist/trpc.js +1 -1
- package/dist/{types-8P7XyoyQ.d.ts → types-9v-WZ_NU.d.ts} +230 -1
- package/package.json +10 -1
- package/dist/chunk-46KUIGB6.js.map +0 -1
- package/dist/chunk-QNCOGISF.js.map +0 -1
- package/dist/chunk-YQDKOEUI.js.map +0 -1
- package/dist/chunk-ZUBFLOKU.js.map +0 -1
|
@@ -109,6 +109,14 @@ interface PluginContext {
|
|
|
109
109
|
crudExtensions?: PluginCrudExtensionsCapability | undefined;
|
|
110
110
|
/** Public web surface capability injected for plugin-owned web route handlers. */
|
|
111
111
|
web?: PluginWebCapability | undefined;
|
|
112
|
+
/** Agent runtime capability; injected only for plugins declaring `capabilities.agent.runtime`. */
|
|
113
|
+
agent?: PluginAgentCapability | undefined;
|
|
114
|
+
/** Governed action invoker; injected only for plugins declaring `capabilities.agent.invoker`. */
|
|
115
|
+
actions?: PluginActionInvokerCapability | undefined;
|
|
116
|
+
/** Governed AI generation; available to plugins and resolved through the official Runtime. */
|
|
117
|
+
ai?: PluginAiCapability | undefined;
|
|
118
|
+
/** Host registration boundary; injected only for the declared official AI Runtime provider. */
|
|
119
|
+
aiRuntime?: PluginAiRuntimeCapability | undefined;
|
|
112
120
|
}
|
|
113
121
|
/**
|
|
114
122
|
* Public SDK shape for the Host-provided Drizzle-compatible database.
|
|
@@ -213,6 +221,8 @@ interface WebPluginRouteRequest {
|
|
|
213
221
|
currency?: string | undefined;
|
|
214
222
|
timezone?: string | undefined;
|
|
215
223
|
globalization?: GlobalizationState | undefined;
|
|
224
|
+
/** Host-bound translator for common + the current route owner namespace. */
|
|
225
|
+
t?: NonNullable<GlobalizationState["t"]> | undefined;
|
|
216
226
|
tenant?: WebPluginTenantInfo | undefined;
|
|
217
227
|
site?: WebPluginSiteInfo | undefined;
|
|
218
228
|
renderSlot?: WebSlotRenderer | undefined;
|
|
@@ -396,6 +406,217 @@ interface PluginPermissionCheckContext {
|
|
|
396
406
|
apiTokenScopes?: string[] | undefined;
|
|
397
407
|
}
|
|
398
408
|
type PluginApisCapability = Record<string, any>;
|
|
409
|
+
/** A tool statically declared by a plugin manifest and reconciled into the Core agent tool registry. */
|
|
410
|
+
interface AgentToolDescriptor {
|
|
411
|
+
/** Tool id as declared in the manifest (unique within the plugin). */
|
|
412
|
+
id: string;
|
|
413
|
+
/** Declaring plugin id (reverse-domain). */
|
|
414
|
+
pluginId: string;
|
|
415
|
+
title: string;
|
|
416
|
+
summary?: string | undefined;
|
|
417
|
+
}
|
|
418
|
+
/**
|
|
419
|
+
* Read surface over the Core agent tool registry.
|
|
420
|
+
* Injected only for plugins with `capabilities.agent.runtime === true`.
|
|
421
|
+
* Listing is declaration-scoped: only tools from loaded plugins appear, and
|
|
422
|
+
* tenant-disabled contributors are filtered when an organization is in scope.
|
|
423
|
+
*/
|
|
424
|
+
interface PluginAgentCapability {
|
|
425
|
+
listTools(): Promise<AgentToolDescriptor[]>;
|
|
426
|
+
}
|
|
427
|
+
interface AiUsage {
|
|
428
|
+
inputTokens: number;
|
|
429
|
+
outputTokens: number;
|
|
430
|
+
totalTokens: number;
|
|
431
|
+
costUsd: number;
|
|
432
|
+
}
|
|
433
|
+
interface AiBudget {
|
|
434
|
+
/** Per-request ceiling supplied by the caller; the effective deployment may lower it. */
|
|
435
|
+
maxCostUsd?: number | undefined;
|
|
436
|
+
maxOutputTokens?: number | undefined;
|
|
437
|
+
}
|
|
438
|
+
interface AiModelHint {
|
|
439
|
+
provider: string;
|
|
440
|
+
model: string;
|
|
441
|
+
}
|
|
442
|
+
interface AiTextRequest {
|
|
443
|
+
prompt: string;
|
|
444
|
+
system?: string | undefined;
|
|
445
|
+
/** Optional plugin-local alias declared in the manifest for administrator binding. */
|
|
446
|
+
alias?: string | undefined;
|
|
447
|
+
/** Explicit deployment selected from listModels(). */
|
|
448
|
+
model?: string | undefined;
|
|
449
|
+
/** Revision returned with the explicit model selection. */
|
|
450
|
+
revision?: string | undefined;
|
|
451
|
+
/** Developer fallback hint; the effective policy default wins when unavailable. */
|
|
452
|
+
defaultModel?: AiModelHint | undefined;
|
|
453
|
+
budget?: AiBudget | undefined;
|
|
454
|
+
signal?: AbortSignal | undefined;
|
|
455
|
+
}
|
|
456
|
+
interface AiTextResult {
|
|
457
|
+
text: string;
|
|
458
|
+
provider: string;
|
|
459
|
+
model: string;
|
|
460
|
+
responseModel?: string | undefined;
|
|
461
|
+
modelId: string;
|
|
462
|
+
revision: string;
|
|
463
|
+
alias?: string | undefined;
|
|
464
|
+
usage: AiUsage;
|
|
465
|
+
}
|
|
466
|
+
/** Structural on purpose: Zod and other validators can be passed without coupling the SDK to one library. */
|
|
467
|
+
interface AiObjectSchema<T> {
|
|
468
|
+
parse(value: unknown): T;
|
|
469
|
+
}
|
|
470
|
+
interface AiObjectRequest<T> extends AiTextRequest {
|
|
471
|
+
schema: AiObjectSchema<T>;
|
|
472
|
+
}
|
|
473
|
+
interface AiObjectResult<T> {
|
|
474
|
+
object: T;
|
|
475
|
+
provider: string;
|
|
476
|
+
model: string;
|
|
477
|
+
responseModel?: string | undefined;
|
|
478
|
+
modelId: string;
|
|
479
|
+
revision: string;
|
|
480
|
+
alias?: string | undefined;
|
|
481
|
+
usage: AiUsage;
|
|
482
|
+
}
|
|
483
|
+
interface AiModelOption {
|
|
484
|
+
id: string;
|
|
485
|
+
name: string;
|
|
486
|
+
provider: string;
|
|
487
|
+
model: string;
|
|
488
|
+
reasoning: boolean;
|
|
489
|
+
input: Array<'text' | 'image'>;
|
|
490
|
+
contextWindow: number;
|
|
491
|
+
maxOutputTokens: number;
|
|
492
|
+
}
|
|
493
|
+
interface AiModelCatalog {
|
|
494
|
+
revision: string;
|
|
495
|
+
defaultModel: string | null;
|
|
496
|
+
models: AiModelOption[];
|
|
497
|
+
}
|
|
498
|
+
interface AiModelListRequest {
|
|
499
|
+
alias?: string | undefined;
|
|
500
|
+
}
|
|
501
|
+
type AiStreamEvent = {
|
|
502
|
+
type: 'text-delta';
|
|
503
|
+
delta: string;
|
|
504
|
+
} | {
|
|
505
|
+
type: 'usage';
|
|
506
|
+
usage: AiUsage;
|
|
507
|
+
provider: string;
|
|
508
|
+
model: string;
|
|
509
|
+
responseModel?: string | undefined;
|
|
510
|
+
modelId: string;
|
|
511
|
+
revision: string;
|
|
512
|
+
alias?: string | undefined;
|
|
513
|
+
} | {
|
|
514
|
+
type: 'done';
|
|
515
|
+
};
|
|
516
|
+
interface PluginAiCapability {
|
|
517
|
+
/** Optional, backward-compatible availability probe for AI-enabled UI. */
|
|
518
|
+
status?(): Promise<{
|
|
519
|
+
available: boolean;
|
|
520
|
+
reason?: string | undefined;
|
|
521
|
+
}>;
|
|
522
|
+
listModels(request?: AiModelListRequest): Promise<AiModelCatalog>;
|
|
523
|
+
generateText(request: AiTextRequest): Promise<AiTextResult>;
|
|
524
|
+
generateObject<T>(request: AiObjectRequest<T>): Promise<AiObjectResult<T>>;
|
|
525
|
+
stream(request: AiTextRequest): AsyncIterable<AiStreamEvent>;
|
|
526
|
+
}
|
|
527
|
+
interface AiRuntimeInvocation {
|
|
528
|
+
invocationId: string;
|
|
529
|
+
organizationId: string;
|
|
530
|
+
userId: string;
|
|
531
|
+
pluginId: string;
|
|
532
|
+
alias?: string | undefined;
|
|
533
|
+
}
|
|
534
|
+
interface AiUsageAuthorization {
|
|
535
|
+
units: number;
|
|
536
|
+
deploymentId: string;
|
|
537
|
+
revision: string;
|
|
538
|
+
alias?: string | undefined;
|
|
539
|
+
provider: string;
|
|
540
|
+
model: string;
|
|
541
|
+
estimatedCostUsd: number;
|
|
542
|
+
}
|
|
543
|
+
interface AiUsageObservation {
|
|
544
|
+
status: 'succeeded' | 'failed' | 'aborted';
|
|
545
|
+
deploymentId: string;
|
|
546
|
+
revision: string;
|
|
547
|
+
alias?: string | undefined;
|
|
548
|
+
provider: string;
|
|
549
|
+
model: string;
|
|
550
|
+
responseModel?: string | undefined;
|
|
551
|
+
usage?: AiUsage | undefined;
|
|
552
|
+
errorCode?: string | undefined;
|
|
553
|
+
}
|
|
554
|
+
/** Narrow Host services offered to the AI Runtime handler at invocation time. */
|
|
555
|
+
interface AiRuntimeHost {
|
|
556
|
+
getSetting<T = unknown>(key: string): Promise<T | null>;
|
|
557
|
+
getSecret<T = unknown>(key: string): Promise<T>;
|
|
558
|
+
authorizeUsage(input: AiUsageAuthorization): Promise<void>;
|
|
559
|
+
recordUsage(input: AiUsageObservation): Promise<void>;
|
|
560
|
+
}
|
|
561
|
+
interface AiRuntimeHandler {
|
|
562
|
+
/** Read-only readiness probe. It validates the effective model and required credential without reserving usage. */
|
|
563
|
+
checkReady?(invocation: AiRuntimeInvocation, host: AiRuntimeHost): Promise<void>;
|
|
564
|
+
listModels(invocation: AiRuntimeInvocation, request: AiModelListRequest, host: AiRuntimeHost): Promise<AiModelCatalog>;
|
|
565
|
+
generateText(invocation: AiRuntimeInvocation, request: AiTextRequest, host: AiRuntimeHost): Promise<AiTextResult>;
|
|
566
|
+
generateObject<T>(invocation: AiRuntimeInvocation, request: AiObjectRequest<T>, host: AiRuntimeHost): Promise<AiObjectResult<T>>;
|
|
567
|
+
stream(invocation: AiRuntimeInvocation, request: AiTextRequest, host: AiRuntimeHost): AsyncIterable<AiStreamEvent>;
|
|
568
|
+
}
|
|
569
|
+
interface PluginAiRuntimeCapability {
|
|
570
|
+
register(handler: AiRuntimeHandler): () => void;
|
|
571
|
+
listAliases(): Promise<AiAliasDescriptor[]>;
|
|
572
|
+
}
|
|
573
|
+
interface AiAliasDescriptor {
|
|
574
|
+
id: string;
|
|
575
|
+
pluginId: string;
|
|
576
|
+
alias: string;
|
|
577
|
+
name: string;
|
|
578
|
+
description?: string | undefined;
|
|
579
|
+
}
|
|
580
|
+
/**
|
|
581
|
+
* Action Contract declared on a tRPC procedure via `.meta({ action: {...} })`.
|
|
582
|
+
* `actionId` is a stable identifier decoupled from the procedure path
|
|
583
|
+
* (renames are a rebinding, detected by drift tooling — plan decision 10).
|
|
584
|
+
*/
|
|
585
|
+
interface ActionContractMeta {
|
|
586
|
+
/** Stable id, lowercase dot-separated (e.g. "spike-studio.greeting.create"). */
|
|
587
|
+
actionId: string;
|
|
588
|
+
/** Contract revision; approval tokens and callers bind to it. */
|
|
589
|
+
revision: number;
|
|
590
|
+
kind: "query" | "command";
|
|
591
|
+
risk: "low" | "medium" | "high";
|
|
592
|
+
summary?: string | undefined;
|
|
593
|
+
}
|
|
594
|
+
/** Catalog entry exposed to invoker plugins. Procedure paths are not exposed. */
|
|
595
|
+
interface ActionDescriptor extends ActionContractMeta {
|
|
596
|
+
/** Owning plugin id, or null for core-owned actions. */
|
|
597
|
+
pluginId: string | null;
|
|
598
|
+
permission: {
|
|
599
|
+
action: string;
|
|
600
|
+
subject: string;
|
|
601
|
+
};
|
|
602
|
+
}
|
|
603
|
+
interface ActionInvokeRequest {
|
|
604
|
+
actionId: string;
|
|
605
|
+
revision: number;
|
|
606
|
+
args?: unknown;
|
|
607
|
+
/** Required for actions the contract marks `risk: 'high'`. */
|
|
608
|
+
approvalToken?: string;
|
|
609
|
+
}
|
|
610
|
+
/**
|
|
611
|
+
* Governed action invocation surface (AI Action Gateway, Phase 0 spike).
|
|
612
|
+
* Injected only for plugins with `capabilities.agent.invoker === true`.
|
|
613
|
+
* The Host resolves `actionId` to a procedure binding itself — callers never
|
|
614
|
+
* choose paths — and derives principal identity from the live request context.
|
|
615
|
+
*/
|
|
616
|
+
interface PluginActionInvokerCapability {
|
|
617
|
+
list(): Promise<ActionDescriptor[]>;
|
|
618
|
+
invoke(request: ActionInvokeRequest): Promise<unknown>;
|
|
619
|
+
}
|
|
399
620
|
type EAuthModel = "oauth_refresh" | "api_key" | "hmac" | "token" | "amazon_spapi";
|
|
400
621
|
type EAuthStatus = "ok" | "reauth" | "retry";
|
|
401
622
|
type EAuthUse = "products" | "orders" | "fulfillment" | "test" | string;
|
|
@@ -880,6 +1101,14 @@ interface PluginSettingsCapability {
|
|
|
880
1101
|
* @returns The setting value or default
|
|
881
1102
|
*/
|
|
882
1103
|
get<T = unknown>(key: string, defaultValue?: T): Promise<T | null>;
|
|
1104
|
+
/**
|
|
1105
|
+
* Check whether an exact scoped setting exists without reading its value.
|
|
1106
|
+
* Use encrypted=true for credential status probes that must not decrypt secrets.
|
|
1107
|
+
*/
|
|
1108
|
+
has(key: string, options?: {
|
|
1109
|
+
global?: boolean;
|
|
1110
|
+
encrypted?: boolean;
|
|
1111
|
+
}): Promise<boolean>;
|
|
883
1112
|
/**
|
|
884
1113
|
* Set a setting value
|
|
885
1114
|
*
|
|
@@ -1596,4 +1825,4 @@ type ApiPayload<T> = {
|
|
|
1596
1825
|
[K in keyof T]: T[K] extends Date ? string : T[K] extends Date | null ? string | null : T[K] extends Date | undefined ? string | undefined : T[K];
|
|
1597
1826
|
};
|
|
1598
1827
|
|
|
1599
|
-
export { type
|
|
1828
|
+
export { type PluginAgentCapability as $, type ActionContractMeta as A, type EAuthProvider as B, type EAuthRefreshInput as C, type EAuthRefreshResult as D, type EAuthModel as E, type EAuthStatus as F, type EAuthTokenResult as G, type HookContext as H, type EAuthUpsertInput as I, type EAuthUse as J, HookAbortError as K, type HookEmitOptions as L, HookPriority as M, MARKETPLACE_PUBLISH_AUTH_METHODS as N, type MarketplaceAttestationTargetV1 as O, type PluginMediaInfo as P, type MarketplaceExecutionErrorCode as Q, type MarketplaceExecutionFailureCode as R, type MarketplaceOrganizationExecutionV1 as S, type MarketplacePlatformReadAction as T, type MarketplacePublishActor as U, type MarketplacePublishAuthMethod as V, type WebPluginSiteInfo as W, type MarketplacePublisherAction as X, type MarketplaceRegistrySigningCapability as Y, type OpaquePublisherCandidateV1 as Z, type PluginActionInvokerCapability as _, type PluginContext as a, type WebPluginTenantInfo as a$, type PluginAiCapability as a0, type PluginAiRuntimeCapability as a1, type PluginApisCapability as a2, type PluginArtifactCapability as a3, type PluginAssetCapability as a4, type PluginAssetCreateOptions as a5, type PluginAssetInfo as a6, type PluginAssetQuery as a7, type PluginAssetUpdateData as a8, type PluginAssetVariant as a9, type PluginNotificationTarget as aA, type PluginNotificationTemplate as aB, type PluginOrganizationProvisioningCapability as aC, type PluginPaginatedResult as aD, type PluginPermissionCapability as aE, type PluginPermissionCheckContext as aF, type PluginPermissionDef as aG, type PluginQueueCapability as aH, type PluginScopedDb as aI, type PluginSettingEntry as aJ, type PluginSettingOptions as aK, type PluginSettingsCapability as aL, type PluginStorageCapability as aM, type PluginStorageProvider as aN, type PluginStorageProviderConfig as aO, type PluginStorageProviderInfo as aP, type PluginStorageUploadInput as aQ, type PluginStorageUploadResult as aR, type PluginTraceCapability as aS, type PluginUsageCapability as aT, type PluginWebCapability as aU, type ReadonlyPluginScopedDb as aV, type WebPluginHead as aW, type WebPluginHeadLink as aX, type WebPluginRouteHandler as aY, type WebPluginRouteRequest as aZ, type WebPluginRouteResult as a_, type PluginCurrencyCapability as aa, type PluginEAuthCapability as ab, type PluginEntityExtensionCapability as ac, type PluginEntityExtensionFilter as ad, type PluginFileCapability as ae, type PluginFileInfo as af, type PluginFileQuery as ag, type PluginFileUploadInput as ah, type PluginHookCapability as ai, type PluginJobOptions as aj, type PluginJobStatus as ak, type PluginMediaCapability as al, type PluginMediaQuery as am, type PluginMediaUpdateData as an, type PluginMediaUploadInput as ao, type PluginMediaVariant as ap, type PluginMetricsAllowedLabels as aq, type PluginMetricsCapability as ar, type PluginNotificationActor as as, type PluginNotificationCapability as at, type PluginNotificationChannel as au, type PluginNotificationEvent as av, type PluginNotificationInput as aw, type PluginNotificationResult as ax, type PluginNotificationSendParams as ay, type PluginNotificationSendResult as az, type HookHandlerOptions as b, type WebSlotExtensionQuery as b0, type WebSlotQueryResult as b1, type WebSlotRemoteExtension as b2, type WebSlotRenderOptions as b3, type WebSlotRenderRequest as b4, type WebSlotRenderResult as b5, type WebSlotRenderer as b6, type HookTransaction as c, type PluginLogger as d, type ActionDescriptor as e, type ActionInvokeRequest as f, type AgentToolDescriptor as g, type AiAliasDescriptor as h, type AiBudget as i, type AiModelCatalog as j, type AiModelHint as k, type AiModelListRequest as l, type AiModelOption as m, type AiObjectRequest as n, type AiObjectResult as o, type AiObjectSchema as p, type AiRuntimeHandler as q, type AiRuntimeHost as r, type AiRuntimeInvocation as s, type AiStreamEvent as t, type AiTextRequest as u, type AiTextResult as v, type AiUsage as w, type AiUsageAuthorization as x, type AiUsageObservation as y, type ApiPayload as z };
|
package/package.json
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wordrhyme/plugin",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.7",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/denvey/wordrhyme.git",
|
|
9
|
+
"directory": "packages/plugin"
|
|
10
|
+
},
|
|
6
11
|
"main": "./dist/index.js",
|
|
7
12
|
"types": "./dist/index.d.ts",
|
|
8
13
|
"exports": {
|
|
@@ -36,6 +41,10 @@
|
|
|
36
41
|
"types": "./dist/globalization.d.ts",
|
|
37
42
|
"import": "./dist/globalization.js"
|
|
38
43
|
},
|
|
44
|
+
"./locale": {
|
|
45
|
+
"types": "./dist/locale.d.ts",
|
|
46
|
+
"import": "./dist/locale.js"
|
|
47
|
+
},
|
|
39
48
|
"./time": {
|
|
40
49
|
"types": "./dist/time.d.ts",
|
|
41
50
|
"import": "./dist/time.js"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/globalization.ts"],"sourcesContent":["import Decimal from 'decimal.js';\n\nDecimal.set({\n precision: 28,\n rounding: Decimal.ROUND_HALF_EVEN,\n});\n\nexport type TextDirection = 'ltr' | 'rtl';\n\nexport type TranslationMessages = Record<string, string>;\n\nexport type I18nTextField = string | Record<string, string | null | undefined> | null | undefined;\n\nexport interface LanguageInfo {\n locale: string;\n name: string;\n nativeName?: string | null | undefined;\n isDefault?: boolean | undefined;\n isEnabled?: boolean | undefined;\n sortOrder?: number | null | undefined;\n direction?: TextDirection | undefined;\n}\n\nexport interface CurrencyInfo {\n code: string;\n nameI18n: Record<string, string>;\n symbol: string;\n decimalDigits: number;\n isBase: boolean;\n currentRate: string | null;\n}\n\nexport type CurrencyInfoInput = {\n code: string;\n nameI18n?: Record<string, string> | null | undefined;\n symbol?: string | null | undefined;\n decimalDigits?: number | null | undefined;\n isBase?: boolean | null | undefined;\n currentRate?: string | null | undefined;\n};\n\nexport interface GlobalizationState {\n locale: string;\n direction: TextDirection;\n availableLocales: string[];\n languages?: LanguageInfo[] | undefined;\n currency: string;\n currencies: CurrencyInfo[];\n baseCurrency: CurrencyInfo;\n timezone?: string | undefined;\n fallbackLocale?: string | undefined;\n messages?: TranslationMessages | undefined;\n t?: Translator | undefined;\n p?: PriceFormatter | undefined;\n changeLocale?: ((locale: string) => void | Promise<void>) | undefined;\n changeCurrency?: ((currencyCode: string) => void | Promise<void>) | undefined;\n}\n\nexport interface FormatPriceOptions {\n showSymbol?: boolean | undefined;\n currencyDisplay?: 'symbol' | 'code' | 'name' | 'narrowSymbol' | undefined;\n notation?: 'standard' | 'compact' | undefined;\n signDisplay?: 'auto' | 'always' | 'exceptZero' | 'never' | undefined;\n decimalDigits?: number | undefined;\n locale?: string | undefined;\n toCurrency?: string | CurrencyInfo | undefined;\n}\n\nexport type Translator = (\n key: string,\n paramsOrFallback?: Record<string, string | number> | string,\n) => string;\n\nexport type PriceFormatter = (\n cents: number,\n fromCurrencyOrOptions?: string | CurrencyInfo | FormatPriceOptions,\n options?: FormatPriceOptions,\n) => string;\n\nexport const DEFAULT_CURRENCY: CurrencyInfo = {\n code: 'USD',\n nameI18n: { 'en-US': 'US Dollar', 'zh-CN': '美元' },\n symbol: '$',\n decimalDigits: 2,\n isBase: true,\n currentRate: '1',\n};\n\nconst RTL_LANGUAGE_CODES = new Set(['ar', 'he', 'fa', 'ur']);\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value && typeof value === 'object' && !Array.isArray(value));\n}\n\nfunction isCurrencyInfo(value: unknown): value is CurrencyInfo {\n return isRecord(value) && typeof value['code'] === 'string';\n}\n\nfunction isCurrencyCatalog(value: readonly CurrencyInfo[] | CurrencyInfo): value is readonly CurrencyInfo[] {\n return Array.isArray(value);\n}\n\nfunction readRate(currency: CurrencyInfo): Decimal {\n if (currency.isBase) return new Decimal(1);\n\n try {\n const rate = new Decimal(currency.currentRate ?? '1');\n return rate.gt(0) ? rate : new Decimal(1);\n } catch {\n return new Decimal(1);\n }\n}\n\nfunction minorUnitFactor(currency: CurrencyInfo): Decimal {\n return new Decimal(10).pow(Math.max(0, currency.decimalDigits));\n}\n\nexport function getTextDirection(locale: string): TextDirection {\n const languageCode = locale.split('-')[0]?.toLowerCase();\n return languageCode && RTL_LANGUAGE_CODES.has(languageCode) ? 'rtl' : 'ltr';\n}\n\nexport function normalizeCurrencyInfo(\n currency: CurrencyInfoInput,\n fallback: CurrencyInfo = DEFAULT_CURRENCY,\n): CurrencyInfo {\n const code = currency.code.toUpperCase();\n return {\n code,\n nameI18n: currency.nameI18n ?? (code === fallback.code ? fallback.nameI18n : {}),\n symbol: currency.symbol ?? (code === fallback.code ? fallback.symbol : code),\n decimalDigits: typeof currency.decimalDigits === 'number' ? currency.decimalDigits : fallback.decimalDigits,\n isBase: currency.isBase ?? code === fallback.code,\n currentRate: currency.isBase ? '1' : (currency.currentRate ?? null),\n };\n}\n\nexport function normalizeCurrencies(currencies: readonly CurrencyInfoInput[]): CurrencyInfo[] {\n if (currencies.length === 0) return [DEFAULT_CURRENCY];\n const normalized = currencies.map((currency) => normalizeCurrencyInfo(currency));\n const hasBase = normalized.some((currency) => currency.isBase);\n if (hasBase) return normalized;\n\n return normalized.map((currency, index) => ({\n ...currency,\n isBase: index === 0,\n currentRate: index === 0 ? '1' : currency.currentRate,\n }));\n}\n\nexport function findCurrency(\n currencies: readonly CurrencyInfo[],\n currencyCode: string | undefined,\n): CurrencyInfo | undefined {\n if (!currencyCode) return undefined;\n const normalizedCode = currencyCode.toUpperCase();\n return currencies.find((currency) => currency.code.toUpperCase() === normalizedCode);\n}\n\nexport function getBaseCurrency(currencies: readonly CurrencyInfo[]): CurrencyInfo {\n return currencies.find((currency) => currency.isBase) ?? currencies[0] ?? DEFAULT_CURRENCY;\n}\n\nexport function resolveCurrencyInfo(\n currency: string | CurrencyInfo | undefined,\n currencies: readonly CurrencyInfo[],\n fallback: CurrencyInfo = getBaseCurrency(currencies),\n): CurrencyInfo {\n if (isCurrencyInfo(currency)) return normalizeCurrencyInfo(currency, fallback);\n return findCurrency(currencies, currency) ?? normalizeCurrencyInfo({ code: currency ?? fallback.code }, fallback);\n}\n\nexport function bankersRound(value: number, decimalDigits: number): number {\n const decimal = new Decimal(value);\n const factor = new Decimal(10).pow(decimalDigits);\n return decimal.times(factor).round().div(factor).toNumber();\n}\n\nexport function toCents(displayAmount: number, decimalDigits: number): number {\n const factor = new Decimal(10).pow(decimalDigits);\n return new Decimal(displayAmount).times(factor).round().toNumber();\n}\n\nexport function fromCents(cents: number, decimalDigits: number): number {\n const factor = new Decimal(10).pow(decimalDigits);\n return new Decimal(cents).div(factor).toNumber();\n}\n\nexport function convertCurrency(\n cents: number,\n fromCurrency: CurrencyInfo,\n toCurrency: CurrencyInfo,\n currenciesOrBaseCurrency: readonly CurrencyInfo[] | CurrencyInfo,\n): number {\n if (fromCurrency.code === toCurrency.code) return cents;\n\n const catalog = isCurrencyCatalog(currenciesOrBaseCurrency)\n ? currenciesOrBaseCurrency\n : [currenciesOrBaseCurrency, fromCurrency, toCurrency];\n const baseCurrency = isCurrencyCatalog(currenciesOrBaseCurrency)\n ? getBaseCurrency(catalog)\n : currenciesOrBaseCurrency;\n\n const from = normalizeCurrencyInfo(fromCurrency, baseCurrency);\n const to = normalizeCurrencyInfo(toCurrency, baseCurrency);\n const sourceMinor = new Decimal(cents);\n const sourceMajor = sourceMinor.div(minorUnitFactor(from));\n const baseMajor = sourceMajor.div(readRate(from));\n const targetMajor = baseMajor.times(readRate(to));\n return targetMajor.times(minorUnitFactor(to)).round().toNumber();\n}\n\nexport function formatCurrencyAmount(\n cents: number,\n currency: CurrencyInfo,\n locale: string,\n options: FormatPriceOptions = {},\n): string {\n const {\n showSymbol = true,\n currencyDisplay = 'symbol',\n notation = 'standard',\n signDisplay = 'auto',\n decimalDigits,\n } = options;\n const digits = decimalDigits ?? currency.decimalDigits;\n const displayAmount = fromCents(cents, currency.decimalDigits);\n\n try {\n const formatter = new Intl.NumberFormat(locale, showSymbol ? {\n style: 'currency',\n currency: currency.code,\n currencyDisplay,\n notation,\n signDisplay,\n minimumFractionDigits: digits,\n maximumFractionDigits: digits,\n } : {\n style: 'decimal',\n notation,\n signDisplay,\n minimumFractionDigits: digits,\n maximumFractionDigits: digits,\n });\n return formatter.format(displayAmount);\n } catch {\n const symbol = showSymbol ? currency.symbol : '';\n return `${symbol}${displayAmount.toFixed(digits)}`;\n }\n}\n\nexport function formatPrice(\n cents: number,\n fromCurrency: string | CurrencyInfo,\n state: GlobalizationState,\n options: FormatPriceOptions = {},\n): string {\n const currencies = normalizeCurrencies(state.currencies.length ? state.currencies : [state.baseCurrency]);\n const baseCurrency = normalizeCurrencyInfo(state.baseCurrency, getBaseCurrency(currencies));\n const sourceCurrency = resolveCurrencyInfo(fromCurrency, currencies, baseCurrency);\n const targetCurrency = resolveCurrencyInfo(options.toCurrency ?? state.currency, currencies, baseCurrency);\n const converted = convertCurrency(cents, sourceCurrency, targetCurrency, currencies);\n\n return formatCurrencyAmount(\n converted,\n targetCurrency,\n options.locale ?? state.locale,\n options,\n );\n}\n\nexport function getI18nText(\n field: I18nTextField,\n locale: string,\n fallbackLocale = 'en-US',\n): string {\n if (typeof field === 'string') return field;\n if (!field || typeof field !== 'object') return '';\n\n const languageCode = locale.split('-')[0];\n const fallbackLanguageCode = fallbackLocale.split('-')[0];\n const candidates = [\n field[locale],\n languageCode ? field[languageCode] : undefined,\n field[fallbackLocale],\n fallbackLanguageCode ? field[fallbackLanguageCode] : undefined,\n ...Object.values(field),\n ];\n\n return candidates.find((value): value is string => typeof value === 'string' && value.length > 0) ?? '';\n}\n\nexport function createTranslator(messages: TranslationMessages | undefined): Translator {\n const translations = messages ?? {};\n return (key, paramsOrFallback) => {\n let value = translations[key];\n if (!value) {\n return typeof paramsOrFallback === 'string' ? paramsOrFallback : key;\n }\n if (paramsOrFallback && typeof paramsOrFallback === 'object') {\n for (const [name, replacement] of Object.entries(paramsOrFallback)) {\n value = value.replace(new RegExp(`\\\\{${name}\\\\}`, 'g'), String(replacement));\n }\n }\n return value;\n };\n}\n\nfunction isFormatPriceOptions(value: unknown): value is FormatPriceOptions {\n return isRecord(value) && !('code' in value);\n}\n\nexport function createPriceFormatter(\n state: GlobalizationState,\n defaultFromCurrency?: string | CurrencyInfo,\n): PriceFormatter {\n return (cents, fromCurrencyOrOptions, options) => {\n const fromCurrency = isFormatPriceOptions(fromCurrencyOrOptions)\n ? defaultFromCurrency ?? state.baseCurrency\n : fromCurrencyOrOptions ?? defaultFromCurrency ?? state.baseCurrency;\n const formatOptions = isFormatPriceOptions(fromCurrencyOrOptions)\n ? fromCurrencyOrOptions\n : options;\n\n return formatPrice(cents, fromCurrency, state, formatOptions);\n };\n}\n\nexport function withGlobalizationHelpers(\n state: GlobalizationState,\n handlers: Pick<GlobalizationState, 'changeLocale' | 'changeCurrency'> = {},\n): GlobalizationState {\n return {\n ...state,\n t: state.t ?? createTranslator(state.messages),\n p: state.p ?? createPriceFormatter(state),\n ...handlers,\n };\n}\n\nexport function buildGlobalizationUrl(\n url: string | URL,\n updates: { locale?: string | null | undefined; currency?: string | null | undefined },\n): string {\n const raw = String(url);\n const isAbsolute = /^[a-z][a-z\\d+\\-.]*:/i.test(raw);\n const parsed = new URL(raw, 'https://wordrhyme.local');\n\n if (updates.locale === null) {\n parsed.searchParams.delete('lang');\n } else if (updates.locale) {\n parsed.searchParams.set('lang', updates.locale);\n }\n\n if (updates.currency === null) {\n parsed.searchParams.delete('currency');\n } else if (updates.currency) {\n parsed.searchParams.set('currency', updates.currency.toUpperCase());\n }\n\n return isAbsolute ? parsed.toString() : `${parsed.pathname}${parsed.search}${parsed.hash}`;\n}\n\nexport { Decimal };\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/manifest.ts"],"sourcesContent":["import { z } from 'zod';\n\n// ========== Notification Schema Components ==========\n\n/**\n * Aggregation Strategy - how to group notifications from plugins\n */\nexport const aggregationStrategySchema = z.enum(['none', 'by_target', 'by_actor', 'by_type']);\nexport type AggregationStrategy = z.infer<typeof aggregationStrategySchema>;\n\n/**\n * Notification Category - determines retention policy and view strategy\n */\nexport const notificationCategorySchema = z.enum(['system', 'collaboration', 'social']);\nexport type NotificationCategory = z.infer<typeof notificationCategorySchema>;\n\n/**\n * Plugin Notification Type - declares a type of notification the plugin can send\n */\nexport const notificationTypeSchema = z.object({\n id: z.string().min(1).regex(/^[a-z0-9_]+$/, 'type id must be lowercase alphanumeric with underscores'),\n category: notificationCategorySchema,\n aggregation: aggregationStrategySchema.default('none'),\n i18n: z.record(\n z.string(), // locale key (e.g., 'en-US', 'zh-CN')\n z.object({\n title: z.string().min(1),\n description: z.string().optional(),\n })\n ),\n});\nexport type PluginNotificationType = z.infer<typeof notificationTypeSchema>;\n\n/**\n * Notification Webhooks - async callbacks for notification events\n */\nexport const notificationWebhooksSchema = z.object({\n onClicked: z.string().url().optional(),\n onArchived: z.string().url().optional(),\n}).optional();\n\n/**\n * Notification Rate Limit - plugin-declared limits (platform may enforce lower)\n */\nexport const notificationRateLimitSchema = z.object({\n maxPerMinute: z.number().int().positive().max(10000).default(100),\n maxPerHour: z.number().int().positive().max(20000).default(1000),\n maxPerDay: z.number().int().positive().max(100000).default(10000),\n}).partial();\n\n/**\n * Notification Permission Types\n */\nexport const notificationPermissionSchema = z.enum([\n 'notification:send',\n 'notification:send:batch',\n 'notification:read:own',\n]);\n\n/**\n * Plugin Notifications Configuration\n */\nexport const notificationsConfigSchema = z.object({\n types: z.array(notificationTypeSchema).min(1),\n permissions: z.array(notificationPermissionSchema).optional(),\n rateLimit: notificationRateLimitSchema.optional(),\n webhooks: notificationWebhooksSchema,\n}).optional();\n\n// ========== Admin Extension Schema (Slot & Fill) ==========\n\nexport const permissionDeclarationSchema = z.union([\n z.string().min(1),\n z.object({\n action: z.string().min(1),\n subject: z.string().min(1),\n anonymous: z.boolean().optional(),\n }),\n]);\n\nexport const navTargetSchema = z.object({\n slot: z.literal('nav.sidebar'),\n path: z.string(),\n icon: z.string().optional(),\n order: z.number().optional(),\n permission: permissionDeclarationSchema.optional(),\n /** @deprecated Use permission instead. */\n requiredPermission: z.string().optional(),\n parent: z.string().optional(),\n});\n\nexport const navGroupTargetSchema = z.object({\n slot: z.literal('nav.sidebar.group'),\n path: z.string().optional(),\n icon: z.string().optional(),\n order: z.number().optional(),\n});\n\nexport const routeTargetSchema = z.object({\n slot: z.literal('plugin.route'),\n path: z.string(),\n order: z.number().optional(),\n params: z.record(z.string(), z.string()).optional(),\n});\n\nexport const settingsTargetSchema = z.object({\n slot: z.literal('settings.plugin'),\n category: z.string().optional(),\n order: z.number().optional(),\n visibility: z.enum(['platform', 'all']).optional(),\n});\n\nexport const dashboardTargetSchema = z.object({\n slot: z.enum(['dashboard.widgets', 'dashboard.overview']),\n order: z.number().optional(),\n colSpan: z.union([z.literal(1), z.literal(2), z.literal(3), z.literal(4)]).optional(),\n});\n\nexport const genericTargetSchema = z.object({\n slot: z.string(),\n order: z.number().optional(),\n});\n\nexport const targetSchema = z.union([\n navTargetSchema,\n navGroupTargetSchema,\n routeTargetSchema,\n settingsTargetSchema,\n dashboardTargetSchema,\n genericTargetSchema,\n]);\n\nexport const adminExtensionSchema = z.object({\n id: z.string().min(1),\n label: z.string().min(1),\n icon: z.string().optional(),\n targets: z.array(targetSchema).min(1),\n});\n\nexport const adminSlotPropSchema = z.union([\n z.string().min(1),\n z.object({\n name: z.string().min(1),\n type: z.string().optional(),\n required: z.boolean().optional(),\n description: z.string().optional(),\n }).passthrough(),\n]);\n\nexport const adminSlotSchema = z.object({\n slot: z.string().min(1),\n description: z.string().optional(),\n props: z.array(adminSlotPropSchema).optional(),\n}).passthrough();\n\nexport const adminTourPlacementSchema = z.enum([\n 'top',\n 'top-start',\n 'top-end',\n 'bottom',\n 'bottom-start',\n 'bottom-end',\n 'left',\n 'left-start',\n 'left-end',\n 'right',\n 'right-start',\n 'right-end',\n 'auto',\n 'center',\n]);\nexport type AdminTourPlacement = z.infer<typeof adminTourPlacementSchema>;\n\nexport const adminTourStepSchema = z.object({\n target: z.string().min(1),\n title: z.string().min(1).optional(),\n titleKey: z.string().min(1).optional(),\n content: z.string().min(1).optional(),\n contentKey: z.string().min(1).optional(),\n placement: adminTourPlacementSchema.optional(),\n}).refine((step) => Boolean(step.content || step.contentKey), {\n message: 'admin tour step must define content or contentKey',\n path: ['content'],\n});\nexport type AdminTourStep = z.infer<typeof adminTourStepSchema>;\n\nexport const adminTourSchema = z.object({\n id: z.string().min(1),\n label: z.string().min(1).optional(),\n labelKey: z.string().min(1).optional(),\n routePatterns: z.array(z.string().min(1)).optional(),\n order: z.number().optional(),\n steps: z.array(adminTourStepSchema).min(1),\n});\nexport type AdminTour = z.infer<typeof adminTourSchema>;\n\nexport const pluginI18nSchema = z.record(\n z.string().min(1),\n z.record(z.string().min(1), z.string())\n);\n\n// ========== Entity Extension Schema ==========\n\nconst extensionTargetPluginIdSchema = z.string()\n .min(1)\n .max(160)\n .regex(/^[a-z0-9-]+(\\.[a-z0-9-]+)+$/, 'target pluginId must be reverse-domain format');\n\nconst crudIdSchema = z.string()\n .min(1)\n .max(80)\n .regex(/^[a-zA-Z][a-zA-Z0-9_-]*$/, 'crud id must be an identifier');\n\nconst entityNameSchema = z.string()\n .min(1)\n .max(160)\n .regex(/^[a-z0-9-]+(\\.[a-z0-9-]+)+$/, 'entity must be dot-separated (e.g., \"shop.store\")');\n\nconst extensionFieldNameSchema = z.string()\n .min(1)\n .max(80)\n .regex(/^[a-zA-Z][a-zA-Z0-9_]*$/, 'field must be an identifier');\n\nexport const entityExtensionFieldTypeSchema = z.enum([\n 'text',\n 'number',\n 'boolean',\n 'date',\n 'datetime',\n 'select',\n 'ref',\n 'json',\n]);\n\nexport const entityExtensionRefSchema = z.object({\n entity: entityNameSchema,\n display: z.string().min(1).optional(),\n changed: z.string().min(1).optional(),\n}).passthrough();\n\nexport const autoCrudFieldOptionSchema = z.object({\n label: z.string().min(1),\n value: z.string().min(1),\n searchText: z.union([\n z.string().min(1),\n z.array(z.string().min(1)),\n ]).optional(),\n count: z.number().optional(),\n disabled: z.boolean().optional(),\n}).passthrough();\n\nexport const autoCrudDataSourceSchema = z.string().min(1);\n\nexport const autoCrudFieldConfigSchema = z.object({\n label: z.string().min(1).optional(),\n enum: z.array(autoCrudFieldOptionSchema).optional(),\n dataSource: autoCrudDataSourceSchema.optional(),\n hidden: z.boolean().optional(),\n table: z.union([z.literal(false), z.record(z.string(), z.unknown())]).optional(),\n filter: z.union([z.literal(false), z.record(z.string(), z.unknown())]).optional(),\n form: z.union([z.literal(false), z.record(z.string(), z.unknown())]).optional(),\n search: z.boolean().optional(),\n}).passthrough();\n\nexport const entityExtensionOwnedFieldSchema = autoCrudFieldConfigSchema.extend({\n label: z.string().min(1),\n type: entityExtensionFieldTypeSchema,\n ref: entityExtensionRefSchema.optional(),\n});\n\nexport const entityExtensionFieldSchema = z.union([\n entityExtensionOwnedFieldSchema,\n autoCrudFieldConfigSchema,\n]);\n\nexport const autoCrudActionZoneSchema = z.enum(['toolbar', 'row', 'batch']);\n\nexport const autoCrudActionSchema = z.object({\n type: z.enum([\n 'create',\n 'import',\n 'export',\n 'view',\n 'edit',\n 'copy',\n 'delete',\n 'batchUpdate',\n 'custom',\n ]),\n id: z.string().min(1).optional(),\n label: z.string().min(1).optional(),\n component: z.string().min(1).optional(),\n onClick: z.string().min(1).optional(),\n order: z.number().optional(),\n hidden: z.boolean().optional(),\n position: z.enum(['start', 'end']).optional(),\n variant: z.enum(['default', 'destructive']).optional(),\n}).passthrough();\n\nexport const autoCrudActionsSchema = z.object({\n toolbar: z.array(autoCrudActionSchema).optional(),\n row: z.array(autoCrudActionSchema).optional(),\n batch: z.array(autoCrudActionSchema).optional(),\n}).passthrough();\n\nexport const entityExtensionCrudConfigSchema = z.object({\n fields: z.record(extensionFieldNameSchema, entityExtensionFieldSchema).optional(),\n actions: autoCrudActionsSchema.optional(),\n}).passthrough();\n\nexport const entityExtensionSlotSchema = z.object({\n slot: z.string().min(1),\n component: z.string().min(1),\n order: z.number().optional(),\n label: z.string().optional(),\n}).passthrough();\n\nconst entityExtensionBaseSchema = z.object({\n fields: z.record(\n crudIdSchema,\n z.record(extensionFieldNameSchema, entityExtensionFieldSchema),\n ).optional(),\n slots: z.array(entityExtensionSlotSchema).optional(),\n hide: z.record(crudIdSchema, z.array(extensionFieldNameSchema)).optional(),\n}).passthrough();\n\nexport const entityExtensionSchema = entityExtensionBaseSchema.superRefine((extension, ctx) => {\n const reservedKeys = new Set(['fields', 'slots', 'hide']);\n for (const [key, value] of Object.entries(extension)) {\n if (reservedKeys.has(key)) continue;\n if (typeof value !== 'object' || value === null || Array.isArray(value)) continue;\n\n const record = value as Record<string, unknown>;\n if (!('fields' in record) && !('actions' in record)) continue;\n\n const parsed = entityExtensionCrudConfigSchema.safeParse(value);\n if (!parsed.success) {\n for (const issue of parsed.error.issues) {\n ctx.addIssue({\n ...issue,\n path: [key, ...issue.path],\n });\n }\n }\n }\n});\n\nexport const entityExtensionUseSchema = z.object({\n pluginId: z.string().regex(/^[a-z0-9-]+(\\.[a-z0-9-]+)+$/, 'pluginId must be reverse-domain format'),\n targetId: z.string().min(1).max(240),\n field: extensionFieldNameSchema,\n required: z.boolean().optional(),\n}).passthrough();\n\nexport const pluginUsesSchema = z.object({\n extensions: z.array(entityExtensionUseSchema).optional(),\n}).passthrough();\n\n// ========== Web Surface Schema ==========\n\nexport const webSsrContractVersionSchema = z.union([z.literal(1), z.literal('1')]);\n\nexport const webPluginRouteSchema = z.object({\n id: z.string().min(1).optional(),\n path: z.string().min(1).regex(/^\\//, 'web route path must start with /'),\n handler: z.string().min(1).optional(),\n component: z.string().min(1),\n permission: permissionDeclarationSchema.optional(),\n order: z.number().optional(),\n}).passthrough();\n\nexport const webExtensionTargetSchema = z.object({\n pluginId: extensionTargetPluginIdSchema,\n slot: z.string().min(1),\n permission: permissionDeclarationSchema.optional(),\n order: z.number().optional(),\n}).passthrough();\n\nexport const webExtensionQuerySchema = z.object({\n id: z.string().min(1),\n procedure: z.string().min(1),\n inputFrom: z.enum(['slotProps', 'static']).optional(),\n staticInput: z.record(z.string(), z.unknown()).optional(),\n}).passthrough();\n\nexport const webExtensionSchema = z.object({\n id: z.string().min(1),\n label: z.string().min(1).optional(),\n component: z.string().min(1),\n expose: z.string().min(1).optional(),\n permission: permissionDeclarationSchema.optional(),\n targets: z.array(webExtensionTargetSchema).min(1),\n queries: z.array(webExtensionQuerySchema).optional(),\n}).passthrough();\n\nexport const webDesignBlockSchema = z.object({\n id: z.string().min(1),\n component: z.string().min(1),\n title: z.string().min(1).optional(),\n /** @deprecated Use title instead. */\n label: z.string().min(1).optional(),\n category: z.string().min(1).optional(),\n icon: z.string().min(1).optional(),\n defaultProps: z.record(z.string(), z.unknown()).optional(),\n previewProps: z.record(z.string(), z.unknown()).optional(),\n propsSchema: z.record(z.string(), z.unknown()).optional(),\n settingsSchema: z.record(z.string(), z.unknown()).optional(),\n designable: z.object({\n resource: z.record(z.string(), z.unknown()).optional(),\n behavior: z.record(z.string(), z.unknown()).optional(),\n }).optional(),\n previewImage: z.string().min(1).optional(),\n order: z.number().optional(),\n}).passthrough().superRefine((block, ctx) => {\n if ('schema' in block) {\n ctx.addIssue({\n code: 'custom',\n path: ['schema'],\n message: 'web.design.blocks[] must not declare platform schema; use propsSchema/settingsSchema for configuration metadata',\n });\n }\n\n if (!block.title && !block.label) {\n ctx.addIssue({\n code: 'custom',\n path: ['title'],\n message: 'web.design.blocks[] must define title or label',\n });\n }\n});\n\nexport const webDesignSlotSchema = z.object({\n id: z.string().min(1),\n label: z.string().min(1).optional(),\n scope: z.enum(['site', 'route', 'template', 'entity']).optional(),\n routeId: z.string().min(1).optional(),\n templateId: z.string().min(1).optional(),\n acceptedBlocks: z.array(z.string().min(1)).optional(),\n order: z.number().optional(),\n}).passthrough();\n\nexport const webDesignTemplateSchema = z.object({\n id: z.string().min(1),\n label: z.string().min(1).optional(),\n routeId: z.string().min(1).optional(),\n entityType: z.string().min(1).optional(),\n component: z.string().min(1),\n slots: z.array(z.string().min(1)).optional(),\n order: z.number().optional(),\n}).passthrough();\n\nexport const webDesignDataSourceSchema = z.object({\n id: z.string().min(1),\n title: z.string().min(1).optional(),\n /** @deprecated Use title instead. */\n label: z.string().min(1).optional(),\n permission: permissionDeclarationSchema.optional(),\n inputSchema: z.record(z.string(), z.unknown()).optional(),\n outputSchema: z.record(z.string(), z.unknown()).optional(),\n order: z.number().optional(),\n}).passthrough().superRefine((dataSource, ctx) => {\n if (!dataSource.title && !dataSource.label) {\n ctx.addIssue({\n code: 'custom',\n path: ['title'],\n message: 'web.design.dataSources[] must define title or label',\n });\n }\n});\n\nexport const webDesignActionSchema = z.object({\n id: z.string().min(1),\n title: z.string().min(1).optional(),\n /** @deprecated Use title instead. */\n label: z.string().min(1).optional(),\n permission: permissionDeclarationSchema.optional(),\n inputSchema: z.record(z.string(), z.unknown()).optional(),\n order: z.number().optional(),\n}).passthrough().superRefine((action, ctx) => {\n if (!action.title && !action.label) {\n ctx.addIssue({\n code: 'custom',\n path: ['title'],\n message: 'web.design.actions[] must define title or label',\n });\n }\n});\n\nexport const webDesignSurfaceSchema = z.object({\n editorEntry: z.string().min(1).optional(),\n previewEntry: z.string().min(1).optional(),\n blocks: z.array(webDesignBlockSchema).optional(),\n slots: z.array(webDesignSlotSchema).optional(),\n templates: z.array(webDesignTemplateSchema).optional(),\n dataSources: z.array(webDesignDataSourceSchema).optional(),\n actions: z.array(webDesignActionSchema).optional(),\n}).superRefine((design, ctx) => {\n const hasDesignSurface = Boolean(\n design.blocks?.length\n || design.slots?.length\n || design.templates?.length\n || design.dataSources?.length\n || design.actions?.length\n );\n if (!hasDesignSurface) {\n ctx.addIssue({\n code: 'custom',\n path: [],\n message: 'web.design must declare at least one block, slot, template, dataSource, or action',\n });\n }\n});\n\nexport const webSurfaceSchema = z.object({\n ssrContractVersion: webSsrContractVersionSchema.optional(),\n serverEntry: z.string().min(1).optional(),\n clientEntry: z.string().min(1).optional(),\n remoteEntry: z.string().min(1).optional(),\n devRemoteEntry: z.string().min(1).optional(),\n moduleName: z.string().min(1).optional(),\n exposes: z.record(z.string(), z.string()).optional(),\n routes: z.array(webPluginRouteSchema).optional(),\n fills: z.never().optional(),\n extensions: z.array(webExtensionSchema).optional(),\n design: webDesignSurfaceSchema.optional(),\n /** @deprecated Use serverEntry/clientEntry plus routes[].handler/component. */\n entry: z.string().optional(),\n /** @deprecated Use routes[].component. */\n components: z.array(z.string()).optional(),\n}).superRefine((web, ctx) => {\n const hasRoutes = Boolean(web.routes?.length);\n const hasExtensions = Boolean(web.extensions?.length);\n const usesSsrSurface = Boolean(\n web.ssrContractVersion\n || web.serverEntry\n || web.clientEntry\n || hasRoutes\n );\n const usesRemoteSurface = Boolean(\n web.remoteEntry\n || web.devRemoteEntry\n || web.moduleName\n || web.exposes\n || hasExtensions\n );\n if (!usesSsrSurface && !usesRemoteSurface) return;\n\n if (hasRoutes && !web.ssrContractVersion) {\n ctx.addIssue({\n code: 'custom',\n path: ['ssrContractVersion'],\n message: 'web.ssrContractVersion is required for SSR web surface',\n });\n }\n if (hasRoutes && !web.serverEntry) {\n ctx.addIssue({\n code: 'custom',\n path: ['serverEntry'],\n message: 'web.serverEntry is required for SSR web surface',\n });\n }\n if (hasRoutes && !web.clientEntry) {\n ctx.addIssue({\n code: 'custom',\n path: ['clientEntry'],\n message: 'web.clientEntry is required for SSR web surface',\n });\n }\n if (hasExtensions && !web.remoteEntry) {\n ctx.addIssue({\n code: 'custom',\n path: ['remoteEntry'],\n message: 'web.remoteEntry is required when web.extensions are declared',\n });\n }\n for (const [index, route] of (web.routes ?? []).entries()) {\n if (!route.id) {\n ctx.addIssue({\n code: 'custom',\n path: ['routes', index, 'id'],\n message: 'web.routes[].id is required for SSR web surface',\n });\n }\n if (!route.handler) {\n ctx.addIssue({\n code: 'custom',\n path: ['routes', index, 'handler'],\n message: 'web.routes[].handler is required for SSR web surface',\n });\n }\n if (!route.permission) {\n ctx.addIssue({\n code: 'custom',\n path: ['routes', index, 'permission'],\n message: 'web.routes[].permission is required for SSR web surface',\n });\n }\n }\n});\n\n// ========== Main Plugin Manifest Schema ==========\n\n/**\n * Plugin Manifest Schema - Validated at plugin load time\n *\n * This is the authoritative schema for manifest.json files.\n */\nexport const pluginManifestSchema = z.object({\n // === Identity ===\n pluginId: z.string().regex(/^[a-z0-9-]+(\\.[a-z0-9-]+)+$/, 'pluginId must be reverse-domain format (e.g., com.vendor.plugin-name)'),\n version: z.string().regex(/^\\d+\\.\\d+\\.\\d+/, 'version must be semver format'),\n name: z.string().min(1).max(100),\n description: z.string().max(500).optional(),\n vendor: z.string().min(1).max(100),\n private: z.boolean().optional(),\n type: z.enum(['backend', 'frontend', 'full', 'extension', 'integration', 'feature']).optional(),\n\n // === UI Translations ===\n // Locale -> { key: translated text }. Stored under namespace `plugin.{pluginId}`.\n i18n: pluginI18nSchema.optional(),\n\n // === Runtime ===\n runtime: z.enum(['node']).default('node'),\n\n // Note: surfaces is auto-generated from server/admin/web presence\n // Used by plugin marketplace for filtering\n\n // === Compatibility ===\n engines: z.object({\n wordrhyme: z.string(), // semver range, e.g., \"^0.1.0\"\n node: z.string().optional(), // e.g., \">=20.0.0\"\n }),\n\n // === Capabilities Declared ===\n capabilities: z.object({\n ui: z.object({\n adminPage: z.boolean().optional(),\n webPage: z.boolean().optional(),\n webTheme: z.boolean().optional(),\n webDesigner: z.boolean().optional(),\n settingsTab: z.boolean().optional(),\n }).optional(),\n storage: z.object({\n provider: z.boolean().optional(),\n }).optional(),\n artifacts: z.object({\n write: z.boolean().optional(),\n }).optional(),\n provides: z.array(z.string()).optional(), // e.g., [\"logger-adapter\", \"cache-adapter\"]\n billing: z.object({\n subjects: z.array(z.object({\n subject: z.string().min(1).regex(\n /^[a-z0-9-]+(\\.[a-z0-9-]+)+\\.[a-zA-Z0-9_]+$/,\n 'subject must be dot-separated (e.g., \"com.vendor.plugin.apiCalls\")'\n ),\n type: z.enum(['boolean', 'metered']),\n unit: z.string().optional(),\n description: z.string().optional(),\n })).optional(),\n procedures: z.record(z.string(), z.string()).optional(),\n }).optional(),\n }).optional(),\n\n // === Exports ===\n exports: z.object({\n loggerAdapter: z.string().optional(), // e.g., \"./dist/logger-adapter.js\"\n cacheAdapter: z.string().optional(),\n }).optional(),\n\n // === Permissions Defined ===\n permissions: z.object({\n definitions: z.array(z.object({\n key: z.string().regex(/^[a-z0-9_.]+$/, 'Permission key must be lowercase with dots/underscores'),\n description: z.string().optional(),\n })).optional(),\n required: z.array(z.string()).optional(),\n /**\n * Quick-select action groups for the permission configuration UI.\n * Keyed by CASL subject name. Each subject can have multiple groups,\n * and groups may overlap (same action in multiple groups).\n *\n * @example\n * ```json\n * {\n * \"Article\": [\n * { \"key\": \"editor\", \"label\": \"Editor\", \"actions\": [\"create\", \"update\"] },\n * { \"key\": \"full\", \"label\": \"Full Access\", \"actions\": [\"create\", \"update\", \"delete\", \"publish\"] }\n * ]\n * }\n * ```\n */\n actionGroups: z.record(\n z.string(), // subject name\n z.array(z.object({\n key: z.string().min(1),\n label: z.string().min(1),\n actions: z.array(z.string().min(1)).min(1),\n })),\n ).optional(),\n }).optional(),\n\n // === Server Entry ===\n server: z.object({\n entry: z.string(), // e.g., \"./dist/server/index.js\"\n router: z.boolean().optional(), // Exports tRPC router\n nestModule: z.string().optional(), // NestJS module for advanced plugins, e.g., \"./dist/server/hello.module.js\"\n fastifyRoutes: z.string().optional(), // Fastify route registrar, e.g., \"./dist/server/http/routes.js\"\n publicServices: z.array(z.object({\n name: z.string().min(1).max(80).regex(/^[a-z0-9-]+$/),\n mountPath: z.string().regex(/^\\/api\\/[a-z0-9/-]+$/),\n methods: z.array(z.enum(['GET', 'POST', 'PUT', 'PATCH', 'DELETE'])).min(1),\n auth: z.enum(['public', 'bearer', 'session', 'user']).default('public'),\n maxBodyBytes: z.number().int().positive().max(100 * 1024 * 1024).default(1024 * 1024),\n })).optional(),\n trustedApiTokenProxy: z.object({\n invoker: z.string().min(1),\n paths: z.array(z.string().min(1)).min(1),\n }).optional(),\n hooks: z.array(z.enum(['onInstall', 'onEnable', 'onDisable', 'onUninstall'])).optional(),\n }).optional(),\n\n // === Admin UI Entry ===\n admin: z.object({\n remoteEntry: z.string(), // e.g., \"./dist/admin/remoteEntry.js\"\n devRemoteEntry: z.string().optional(), // Dev mode: e.g., \"http://localhost:3010/remoteEntry.js\"\n moduleName: z.string().optional(), // MF2.0 module name\n exposes: z.record(z.string(), z.string()).optional(),\n extensions: z.array(adminExtensionSchema).optional(),\n slots: z.array(adminSlotSchema).optional(),\n tours: z.array(adminTourSchema).optional(),\n /** @deprecated Use slots instead. */\n extensionSlots: z.array(adminSlotSchema).optional(),\n /** @deprecated Use extensions[] instead */\n menus: z.array(z.object({\n label: z.string(),\n icon: z.string().optional(),\n path: z.string(),\n order: z.number().optional(),\n parentId: z.string().optional(),\n permission: permissionDeclarationSchema.optional(),\n /** @deprecated Use permission instead. */\n requiredPermission: z.string().optional(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n })).optional(),\n }).optional(),\n\n // === Web UI Entry ===\n web: webSurfaceSchema.optional(),\n\n // === Dependencies ===\n dependencies: z.array(z.string()).optional(), // Other plugin IDs\n conflicts: z.array(z.string()).optional(), // Conflicting plugin IDs\n peerDependencies: z.record(z.string(), z.string()).optional(), // e.g., { react: \"^18.0.0\" }\n compatibilityMode: z.enum(['strict', 'lenient', 'fallback']).optional(),\n\n // === Entity Extensions ===\n extends: z.record(extensionTargetPluginIdSchema, entityExtensionSchema).optional(),\n uses: pluginUsesSchema.optional(),\n\n // === Data Retention ===\n dataRetention: z.object({\n onDisable: z.enum(['retain']).optional(),\n onUninstall: z.enum(['delete', 'archive', 'retain']).optional(),\n tables: z.array(z.string()).optional(),\n }).optional(),\n\n // === Infrastructure (Tenant Config Delegation) ===\n infrastructure: z.object({\n tenantOverride: z.boolean(),\n riskLevel: z.enum(['high', 'medium', 'low']),\n sensitiveFields: z.array(z.string()).default([]),\n }).optional(),\n\n // === Notifications ===\n notifications: notificationsConfigSchema,\n});\n\nexport type PluginManifest = z.infer<typeof pluginManifestSchema>;\nexport type AdminSlotProp = z.infer<typeof adminSlotPropSchema>;\nexport type AdminSlot = z.infer<typeof adminSlotSchema>;\nexport type EntityExtensionFieldType = z.infer<typeof entityExtensionFieldTypeSchema>;\nexport type EntityExtensionField = z.infer<typeof entityExtensionFieldSchema>;\nexport type AutoCrudActionZone = z.infer<typeof autoCrudActionZoneSchema>;\nexport type AutoCrudAction = z.infer<typeof autoCrudActionSchema>;\nexport type AutoCrudActions = z.infer<typeof autoCrudActionsSchema>;\nexport type EntityExtensionCrudConfig = z.infer<typeof entityExtensionCrudConfigSchema>;\nexport type EntityExtensionSlot = z.infer<typeof entityExtensionSlotSchema>;\nexport type EntityExtension = z.infer<typeof entityExtensionSchema>;\nexport type EntityExtensionUse = z.infer<typeof entityExtensionUseSchema>;\nexport type WebSsrContractVersion = z.infer<typeof webSsrContractVersionSchema>;\nexport type WebPluginRoute = z.infer<typeof webPluginRouteSchema>;\nexport type WebExtensionTarget = z.infer<typeof webExtensionTargetSchema>;\nexport type WebExtensionQuery = z.infer<typeof webExtensionQuerySchema>;\nexport type WebExtension = z.infer<typeof webExtensionSchema>;\nexport type WebDesignBlock = z.infer<typeof webDesignBlockSchema>;\nexport type WebDesignSlot = z.infer<typeof webDesignSlotSchema>;\nexport type WebDesignTemplate = z.infer<typeof webDesignTemplateSchema>;\nexport type WebDesignDataSource = z.infer<typeof webDesignDataSourceSchema>;\nexport type WebDesignAction = z.infer<typeof webDesignActionSchema>;\nexport type WebDesignSurface = z.infer<typeof webDesignSurfaceSchema>;\nexport type WebSurface = z.infer<typeof webSurfaceSchema>;\n\n/**\n * Plugin Surface Type - Auto-generated from manifest configuration\n *\n * Indicates on which surfaces this plugin runs:\n * - 'server': Has server-side logic (backend API, database, queue jobs, etc.)\n * - 'admin': Has admin UI components (management dashboard)\n * - 'web': Has frontend/customer-facing UI (public website, user portal)\n */\nexport type PluginSurface = 'server' | 'admin' | 'web';\n\n/**\n * Get plugin surfaces from manifest\n *\n * Auto-generates surfaces array based on which sections are present.\n * Used by plugin marketplace for filtering and display.\n *\n * @param manifest - Plugin manifest\n * @returns Array of surfaces, e.g., ['server', 'admin']\n *\n * @example\n * // Full-stack plugin\n * getPluginSurfaces(manifest) // ['server', 'admin', 'web']\n *\n * // Backend-only plugin (e.g., LBAC, payment gateway)\n * getPluginSurfaces(manifest) // ['server']\n *\n * // Frontend-only plugin (e.g., theme, widget)\n * getPluginSurfaces(manifest) // ['admin', 'web']\n */\nexport function getPluginSurfaces(manifest: PluginManifest): PluginSurface[] {\n const surfaces: PluginSurface[] = [];\n\n if (manifest.server) {\n surfaces.push('server');\n }\n\n if (manifest.admin) {\n surfaces.push('admin');\n }\n\n if (manifest.web) {\n surfaces.push('web');\n }\n\n return surfaces;\n}\n\n/**\n * Check if plugin has specific surface\n *\n * @param manifest - Plugin manifest\n * @param surface - Surface to check\n * @returns true if plugin has this surface\n */\nexport function hasSurface(manifest: PluginManifest, surface: PluginSurface): boolean {\n return getPluginSurfaces(manifest).includes(surface);\n}\n\n/**\n * Get plugin type for backwards compatibility\n *\n * @deprecated Use getPluginSurfaces() instead for more granular control\n * @param manifest - Plugin manifest\n * @returns Plugin type classification\n */\nexport function getPluginType(manifest: PluginManifest): 'backend' | 'frontend' | 'full' {\n const surfaces = getPluginSurfaces(manifest);\n const hasServer = surfaces.includes('server');\n const hasUI = surfaces.includes('admin') || surfaces.includes('web');\n\n if (hasServer && hasUI) return 'full';\n if (hasServer) return 'backend';\n return 'frontend';\n}\n\n/**\n * Plugin Status - Runtime state of a plugin\n */\nexport type PluginStatus = 'enabled' | 'disabled' | 'crashed' | 'invalid' | 'archived' | 'uninstalled';\n\n/**\n * Plugin Capabilities - What the plugin declared it needs\n */\nexport interface PluginCapabilities {\n ui?: {\n adminPage?: boolean;\n webPage?: boolean;\n webTheme?: boolean;\n webDesigner?: boolean;\n settingsTab?: boolean;\n };\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/dev-utils.ts"],"sourcesContent":["/**\n * Plugin Development Utilities\n * \n * Shared utilities for plugin development, including automatic port assignment.\n */\n\nexport type PluginRemoteSurface = 'admin' | 'web';\n\nexport interface ResolvedPluginRemoteEntry {\n remoteEntry: string;\n source: 'dev' | 'manifest';\n}\n\nexport interface ResolvePluginRemoteEntryOptions {\n pluginId: string;\n manifestRemoteEntry: string;\n devRemoteEntry?: string | undefined;\n surface?: PluginRemoteSurface | undefined;\n isDev?: boolean | undefined;\n probeTimeoutMs?: number | undefined;\n entryChunkPaths?: readonly string[] | undefined;\n}\n\ninterface DevProbeCacheEntry {\n result: ResolvedPluginRemoteEntry;\n expiresAt: number;\n}\n\ninterface StorageLike {\n getItem(key: string): string | null;\n setItem(key: string, value: string): void;\n}\n\ninterface RuntimeLike {\n location?: { search?: string | undefined } | undefined;\n sessionStorage?: StorageLike | undefined;\n localStorage?: StorageLike | undefined;\n fetch?: ((url: string, init: { method: 'HEAD' | 'GET'; signal?: unknown }) => Promise<{ ok: boolean; status: number }>) | undefined;\n AbortSignal?: { timeout?: (ms: number) => unknown } | undefined;\n AbortController?: (new () => { signal: unknown; abort: () => void }) | undefined;\n setTimeout?: ((handler: () => void, timeoutMs: number) => unknown) | undefined;\n clearTimeout?: ((handle: unknown) => void) | undefined;\n}\n\nconst DEV_ADMIN_ENTRY_CHUNK_PATHS = [\n '/static/js/admin.js',\n '/static/js/src_admin_index_tsx.js',\n] as const;\n\nconst DEV_WEB_ENTRY_CHUNK_PATHS = [\n '/static/js/web.js',\n '/static/js/client.js',\n '/static/js/src_web_index_tsx.js',\n '/static/js/src_web_client_tsx.js',\n] as const;\n\nconst DEV_REMOTE_FAILURE_TTL_MS = 30_000;\nconst DEV_PROBE_CACHE_STORAGE_KEY = 'wr.plugin-dev-probe-cache';\nconst DEV_REMOTE_OPT_IN_QUERY_KEY = 'pluginDevRemote';\nconst DEV_REMOTE_OPT_IN_STORAGE_KEY = 'wr.plugin-dev-remote';\nconst devProbeCache = new Map<string, DevProbeCacheEntry>();\n\n/**\n * Calculate a deterministic dev port for a plugin based on its ID.\n * \n * This allows multiple plugins to run simultaneously without port conflicts,\n * while keeping the port assignment automatic and predictable.\n * \n * Port range: 3010-3109 (100 possible ports)\n * \n * @param pluginId - Full plugin ID (e.g., \"com.wordrhyme.hello-world\")\n * @returns Port number for the plugin's dev server\n * \n * @example\n * getPluginDevPort('com.wordrhyme.hello-world') // e.g., 3042\n * getPluginDevPort('com.wordrhyme.analytics') // e.g., 3015\n */\nexport function getPluginDevPort(pluginId: string): number {\n const BASE_PORT = 3010;\n const PORT_RANGE = 100;\n\n // Simple hash based on character codes\n const hash = pluginId.split('').reduce((acc, char) => {\n return acc + char.charCodeAt(0);\n }, 0);\n\n return BASE_PORT + (hash % PORT_RANGE);\n}\n\n/**\n * Get the dev remote entry URL for a plugin.\n * \n * @param pluginId - Full plugin ID\n * @returns Full URL to the plugin's remoteEntry.js in dev mode\n */\nexport function getPluginDevRemoteEntry(pluginId: string): string {\n const port = getPluginDevPort(pluginId);\n return `http://localhost:${port}/remoteEntry.js`;\n}\n\n/**\n * Calculate a deterministic public web dev port for a plugin.\n *\n * Public web remotes run beside admin remotes, so they use the same stable\n * plugin hash with a +100 offset.\n */\nexport function getPluginWebDevPort(pluginId: string): number {\n return getPluginDevPort(pluginId) + 100;\n}\n\n/**\n * Get the public web dev remote entry URL for a plugin.\n */\nexport function getPluginWebDevRemoteEntry(pluginId: string): string {\n return `http://localhost:${getPluginWebDevPort(pluginId)}/remoteEntry.js`;\n}\n\n/**\n * Normalize plugin ID to a valid Module Federation name.\n * \n * MF names must be valid JavaScript identifiers.\n * \"com.wordrhyme.hello-world\" → \"plugin_hello_world\"\n * \n * @param pluginId - Full plugin ID\n * @returns Valid MF module name\n */\nexport function getPluginMfName(pluginId: string): string {\n // Extract the last segment and convert to underscore format\n const shortId = pluginId.replace(/^com\\.wordrhyme\\./, '');\n return `plugin_${shortId.replace(/-/g, '_')}`;\n}\n\nfunction runtime(): RuntimeLike {\n return globalThis as unknown as RuntimeLike;\n}\n\nfunction readQueryValue(search: string | undefined, key: string): string | null {\n const query = search?.replace(/^\\?/, '');\n if (!query) return null;\n\n for (const part of query.split('&')) {\n const [rawKey, rawValue = ''] = part.split('=');\n if (!rawKey) continue;\n try {\n if (decodeURIComponent(rawKey.replace(/\\+/g, ' ')) === key) {\n return decodeURIComponent(rawValue.replace(/\\+/g, ' '));\n }\n } catch {\n if (rawKey === key) return rawValue;\n }\n }\n\n return null;\n}\n\nfunction matchesPluginOptIn(rawValue: string | null, pluginId: string): boolean {\n const value = rawValue?.trim();\n if (!value) return false;\n\n return value === '1'\n || value.toLowerCase() === 'true'\n || value.toLowerCase() === 'all'\n || value === pluginId;\n}\n\nexport function isPluginDevRemoteEnabled(pluginId: string): boolean {\n const host = runtime();\n if (matchesPluginOptIn(readQueryValue(host.location?.search, DEV_REMOTE_OPT_IN_QUERY_KEY), pluginId)) {\n return true;\n }\n\n try {\n if (matchesPluginOptIn(host.sessionStorage?.getItem(DEV_REMOTE_OPT_IN_STORAGE_KEY) ?? null, pluginId)) {\n return true;\n }\n } catch {\n // Ignore storage access failures.\n }\n\n try {\n if (matchesPluginOptIn(host.localStorage?.getItem(DEV_REMOTE_OPT_IN_STORAGE_KEY) ?? null, pluginId)) {\n return true;\n }\n } catch {\n // Ignore storage access failures.\n }\n\n return false;\n}\n\nfunction readStoredProbeCache(): Record<string, DevProbeCacheEntry> {\n try {\n const raw = runtime().sessionStorage?.getItem(DEV_PROBE_CACHE_STORAGE_KEY);\n if (!raw) return {};\n const parsed = JSON.parse(raw) as Record<string, DevProbeCacheEntry> | null;\n return parsed && typeof parsed === 'object' ? parsed : {};\n } catch {\n return {};\n }\n}\n\nfunction writeStoredProbeCache(cache: Record<string, DevProbeCacheEntry>) {\n try {\n runtime().sessionStorage?.setItem(DEV_PROBE_CACHE_STORAGE_KEY, JSON.stringify(cache));\n } catch {\n // Ignore storage failures and rely on in-memory cache.\n }\n}\n\nfunction probeCacheKey(surface: PluginRemoteSurface, pluginId: string, devRemoteEntry: string): string {\n return `${surface}:${pluginId}:${devRemoteEntry}`;\n}\n\nfunction getCachedProbeResult(key: string, now: number): ResolvedPluginRemoteEntry | null {\n const cached = devProbeCache.get(key);\n if (cached) {\n if (cached.expiresAt <= now) {\n devProbeCache.delete(key);\n } else {\n return cached.result;\n }\n }\n\n const storedCache = readStoredProbeCache();\n const stored = storedCache[key];\n if (!stored) return null;\n if (stored.expiresAt <= now) {\n delete storedCache[key];\n writeStoredProbeCache(storedCache);\n devProbeCache.delete(key);\n return null;\n }\n devProbeCache.set(key, stored);\n return stored.result;\n}\n\nfunction cacheProbeResult(key: string, result: ResolvedPluginRemoteEntry, ttlMs: number) {\n const entry = {\n result,\n expiresAt: Date.now() + ttlMs,\n };\n devProbeCache.set(key, entry);\n\n const storedCache = readStoredProbeCache();\n storedCache[key] = entry;\n writeStoredProbeCache(storedCache);\n}\n\nfunction createTimeoutSignal(timeoutMs: number): { signal?: unknown; cleanup: () => void } {\n const host = runtime();\n const timeout = host.AbortSignal?.timeout;\n if (timeout) {\n return { signal: timeout(timeoutMs), cleanup: () => {} };\n }\n\n const Controller = host.AbortController;\n if (!Controller || !host.setTimeout || !host.clearTimeout) {\n return { cleanup: () => {} };\n }\n\n const probeController = new Controller();\n const timeoutId = host.setTimeout(() => probeController.abort(), timeoutMs);\n return {\n signal: probeController.signal,\n cleanup: () => host.clearTimeout?.(timeoutId),\n };\n}\n\nfunction resolveChunkUrl(path: string, devRemoteEntry: string): string {\n const originMatch = devRemoteEntry.match(/^(https?:\\/\\/[^/?#]+)(?:[/?#]|$)/);\n if (originMatch?.[1] && path.startsWith('/')) {\n return `${originMatch[1]}${path}`;\n }\n\n const base = devRemoteEntry.replace(/[?#].*$/, '').replace(/\\/[^/]*$/, '/');\n return `${base}${path.replace(/^\\//, '')}`;\n}\n\nasync function requestOk(url: string, signal: unknown): Promise<boolean> {\n const fetcher = runtime().fetch;\n if (!fetcher) return false;\n\n const response = await fetcher(url, {\n method: 'HEAD',\n ...(signal ? { signal } : {}),\n });\n\n if (response.ok) return true;\n if (response.status !== 405) return false;\n\n const fallbackResponse = await fetcher(url, {\n method: 'GET',\n ...(signal ? { signal } : {}),\n });\n return fallbackResponse.ok;\n}\n\nasync function canLoadDevRemote(\n devRemoteEntry: string,\n surface: PluginRemoteSurface,\n signal: unknown,\n entryChunkPaths?: readonly string[] | undefined,\n): Promise<boolean> {\n if (!await requestOk(devRemoteEntry, signal)) {\n return false;\n }\n\n const chunkPaths = entryChunkPaths\n ?? (surface === 'web' ? DEV_WEB_ENTRY_CHUNK_PATHS : DEV_ADMIN_ENTRY_CHUNK_PATHS);\n for (const path of chunkPaths) {\n if (await requestOk(resolveChunkUrl(path, devRemoteEntry), signal)) {\n return true;\n }\n }\n\n return false;\n}\n\nfunction defaultDevRemoteEntry(pluginId: string, surface: PluginRemoteSurface): string {\n return surface === 'web'\n ? getPluginWebDevRemoteEntry(pluginId)\n : getPluginDevRemoteEntry(pluginId);\n}\n\nexport async function resolvePluginRemoteEntry({\n pluginId,\n manifestRemoteEntry,\n devRemoteEntry,\n surface = 'admin',\n isDev = false,\n probeTimeoutMs = 1500,\n entryChunkPaths,\n}: ResolvePluginRemoteEntryOptions): Promise<ResolvedPluginRemoteEntry> {\n const manifestResult = {\n remoteEntry: manifestRemoteEntry,\n source: 'manifest',\n } as const;\n\n if (!isDev || !isPluginDevRemoteEnabled(pluginId)) {\n return manifestResult;\n }\n\n const devUrl = devRemoteEntry?.trim() || defaultDevRemoteEntry(pluginId, surface);\n const cacheKey = probeCacheKey(surface, pluginId, devUrl);\n const cachedResult = getCachedProbeResult(cacheKey, Date.now());\n if (cachedResult) {\n return cachedResult;\n }\n\n const { signal, cleanup } = createTimeoutSignal(probeTimeoutMs);\n\n try {\n if (await canLoadDevRemote(devUrl, surface, signal, entryChunkPaths)) {\n return {\n remoteEntry: devUrl,\n source: 'dev',\n };\n }\n } catch {\n // Ignore and fall back to the manifest bundle below.\n } finally {\n cleanup();\n }\n\n console.log(`[Plugin] ${pluginId}: ${surface} dev server 不在线,使用预构建静态文件`);\n cacheProbeResult(cacheKey, manifestResult, DEV_REMOTE_FAILURE_TTL_MS);\n return manifestResult;\n}\n\nexport function appendRemoteEntryCacheBust(remoteEntry: string, value: string | number): string {\n const separator = remoteEntry.includes('?') ? '&' : '?';\n return `${remoteEntry}${separator}t=${encodeURIComponent(String(value))}`;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/trpc.ts"],"sourcesContent":["import { initTRPC, TRPCError } from \"@trpc/server\";\nimport type { PluginContext, PluginPermissionCapability, PluginScopedDb, PluginSettingsCapability } from \"./types\";\n\n/**\n * tRPC builders for plugins\n *\n * Plugins use these to define their API routes, just like a normal tRPC project.\n */\nconst t = initTRPC.context<PluginContext>().meta<Record<string, unknown>>().create();\n\nconst ANONYMOUS_ROLE = \"anonymous\";\n\nfunction allowsAnonymousAccess(meta: unknown): boolean {\n if (!meta || typeof meta !== \"object\") return false;\n\n const metaRecord = meta as Record<string, unknown>;\n const permission = metaRecord[\"permission\"];\n if (permission && typeof permission === \"object\") {\n const permissionRecord = permission as Record<string, unknown>;\n if (permissionRecord[\"anonymous\"] === true) return true;\n }\n\n if (metaRecord[\"anonymous\"] === true) return true;\n\n const access = metaRecord[\"access\"];\n if (access === \"anonymous\") return true;\n\n if (access && typeof access === \"object\") {\n const accessRecord = access as Record<string, unknown>;\n return (\n accessRecord[\"anonymous\"] === true ||\n accessRecord[\"allowAnonymous\"] === true ||\n accessRecord[\"mode\"] === \"anonymous\"\n );\n }\n\n return false;\n}\n\nfunction injectAnonymousRole(target: Record<string, unknown>) {\n const roles = Array.isArray(target[\"userRoles\"]) ? [...(target[\"userRoles\"] as string[])] : [];\n if (!roles.includes(ANONYMOUS_ROLE)) {\n roles.push(ANONYMOUS_ROLE);\n }\n target[\"userRoles\"] = roles;\n if (!target[\"userRole\"]) {\n target[\"userRole\"] = ANONYMOUS_ROLE;\n }\n}\n\nfunction isTrustedSystemContext(ctxRecord: Record<string, unknown>): boolean {\n if (ctxRecord[\"isSystemContext\"] === true || ctxRecord[\"actorType\"] === \"system\") {\n return true;\n }\n\n if (ctxRecord[\"invoker\"] === \"scheduler\") {\n return true;\n }\n\n const principal = ctxRecord[\"principal\"];\n return (\n principal !== null &&\n typeof principal === \"object\" &&\n (principal as Record<string, unknown>)[\"kind\"] === \"system\"\n );\n}\n\ntype PluginProcedureMiddleware = (opts: any) => Promise<any>;\n\nconst pluginProcedureBase = t.procedure.use(async (opts) => {\n const ctxRecord = (opts.ctx as Record<string, unknown> | undefined) ?? {};\n const shouldEnforcePluginAccess = ctxRecord[\"__enforcePluginAccess\"] === true;\n const isAnonymousRequest = !ctxRecord[\"userId\"];\n\n if (shouldEnforcePluginAccess && isAnonymousRequest && !isTrustedSystemContext(ctxRecord)) {\n if (!allowsAnonymousAccess(opts.meta)) {\n throw new TRPCError({\n code: \"UNAUTHORIZED\",\n message: \"Authentication required\",\n });\n }\n\n injectAnonymousRole(ctxRecord);\n\n const requestContextRef = ctxRecord[\"__requestContextRef\"];\n if (requestContextRef && typeof requestContextRef === \"object\") {\n injectAnonymousRole(requestContextRef as Record<string, unknown>);\n }\n }\n\n const pluginProcedureMiddlewares = ((opts.ctx as Record<string, unknown> | undefined)?.[\n \"__pluginProcedureMiddlewares\"\n ] ?? []) as PluginProcedureMiddleware[];\n\n const run = (index: number, accumulatedOverrides: Record<string, unknown>) => {\n if (index >= pluginProcedureMiddlewares.length) {\n return opts.next(accumulatedOverrides as any);\n }\n\n const middleware = pluginProcedureMiddlewares[index]!;\n return middleware({\n ...opts,\n ...accumulatedOverrides,\n next: (nextOverrides?: Record<string, unknown>) =>\n run(index + 1, {\n ...accumulatedOverrides,\n ...(nextOverrides ?? {}),\n }),\n });\n };\n\n return run(0, {});\n});\n\n/**\n * Plugin router builder\n *\n * @example\n * ```ts\n * import { pluginRouter, pluginProcedure } from '@wordrhyme/plugin';\n *\n * export const router = pluginRouter({\n * hello: pluginProcedure.query(() => 'Hello from plugin!'),\n * });\n * ```\n */\nexport const pluginRouter = t.router;\n\n/**\n * Plugin procedure builder (with context)\n *\n * Use this to define procedures that have access to PluginContext.\n */\nexport const pluginProcedure = pluginProcedureBase;\n\n/**\n * Default no-op permission capability (for standalone plugin development)\n */\nconst defaultPermissions: PluginPermissionCapability = {\n can: async () => false,\n require: async () => {\n throw new Error(\"Permission capability not available\");\n },\n hasDeclared: () => false,\n};\n\n/**\n * Default no-op settings capability (for standalone plugin development)\n */\nconst defaultSettings: PluginSettingsCapability = {\n get: async () => null,\n set: async () => {\n throw new Error(\"Settings capability not available\");\n },\n delete: async () => {\n throw new Error(\"Settings capability not available\");\n },\n list: async () => [],\n isFeatureEnabled: async () => false,\n};\n\nconst defaultDb = new Proxy({} as PluginScopedDb, {\n get() {\n throw new Error(\"Database capability not available in this standalone plugin context\");\n },\n});\n\n/**\n * Create plugin context (used by Core to inject context)\n *\n * This is called by PluginManager when invoking plugin handlers.\n */\nexport function createPluginContext(partial: Partial<PluginContext> & { pluginId: string }): PluginContext {\n return {\n pluginId: partial.pluginId,\n organizationId: partial.organizationId,\n originalOrganizationId: partial.originalOrganizationId,\n userId: partial.userId,\n user: partial.user,\n requestId: partial.requestId,\n userRole: partial.userRole,\n userRoles: partial.userRoles,\n currentTeamId: partial.currentTeamId,\n locale: partial.locale,\n timezone: partial.timezone,\n clientTimeZone: partial.clientTimeZone,\n resolveDateRange: partial.resolveDateRange,\n actorType: partial.actorType,\n apiTokenId: partial.apiTokenId,\n apiTokenScopes: partial.apiTokenScopes,\n isSystemContext: partial.isSystemContext,\n principal: partial.principal,\n invoker: partial.invoker,\n logger: partial.logger ?? {\n info: (msg, meta) => console.log(`[${partial.pluginId}]`, msg, meta),\n warn: (msg, meta) => console.warn(`[${partial.pluginId}]`, msg, meta),\n error: (msg, meta) => console.error(`[${partial.pluginId}]`, msg, meta),\n debug: (msg, meta) => console.debug(`[${partial.pluginId}]`, msg, meta),\n },\n permissions: partial.permissions ?? defaultPermissions,\n plugins: partial.plugins,\n db: partial.db ?? defaultDb,\n organizationProvisioning: partial.organizationProvisioning,\n tx: partial.tx,\n settings: partial.settings ?? defaultSettings,\n currency: partial.currency,\n hooks: partial.hooks,\n metrics: partial.metrics,\n trace: partial.trace,\n media: partial.media,\n storage: partial.storage,\n notifications: partial.notifications,\n queue: partial.queue,\n usage: partial.usage,\n entityExtensions: partial.entityExtensions,\n crudExtensions: partial.crudExtensions,\n };\n}\n\n// Re-export tRPC types for convenience\nexport type { inferRouterInputs, inferRouterOutputs } from \"@trpc/server\";\n"],"mappings":"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","names":[]}
|