fortiplugin-bundle-adapter 0.0.7 → 0.0.9
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/runtime/index.cjs +274 -0
- package/dist/runtime/index.cjs.map +1 -0
- package/dist/runtime/index.d.mts +123 -0
- package/dist/runtime/index.d.ts +123 -0
- package/dist/runtime/index.mjs +246 -0
- package/dist/runtime/index.mjs.map +1 -0
- package/dist/types.cjs +19 -0
- package/dist/types.cjs.map +1 -0
- package/dist/types.d.mts +299 -0
- package/dist/types.d.ts +299 -0
- package/dist/types.mjs +1 -0
- package/dist/types.mjs.map +1 -0
- package/package.json +12 -2
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/runtime/index.ts
|
|
21
|
+
var runtime_exports = {};
|
|
22
|
+
__export(runtime_exports, {
|
|
23
|
+
createFactory: () => createFactory,
|
|
24
|
+
createPluginResolver: () => createPluginResolver
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(runtime_exports);
|
|
27
|
+
|
|
28
|
+
// src/runtime/create-factory.ts
|
|
29
|
+
function isObject(v) {
|
|
30
|
+
return !!v && typeof v === "object";
|
|
31
|
+
}
|
|
32
|
+
function isCallable(v) {
|
|
33
|
+
return typeof v === "function";
|
|
34
|
+
}
|
|
35
|
+
var REACT_ELEMENT_SYMBOLS = /* @__PURE__ */ new Set([
|
|
36
|
+
/* @__PURE__ */ Symbol.for("react.element"),
|
|
37
|
+
/* @__PURE__ */ Symbol.for("react.transitional.element")
|
|
38
|
+
]);
|
|
39
|
+
function isReactElement(v) {
|
|
40
|
+
if (!isObject(v)) return false;
|
|
41
|
+
const x = v.$$typeof;
|
|
42
|
+
return typeof x === "symbol" && REACT_ELEMENT_SYMBOLS.has(x);
|
|
43
|
+
}
|
|
44
|
+
function unwrapNamespaceDefault(mod) {
|
|
45
|
+
if (!mod) return mod;
|
|
46
|
+
if (isObject(mod) && "default" in mod) return mod.default;
|
|
47
|
+
return mod;
|
|
48
|
+
}
|
|
49
|
+
function pickExport(mod, exportName) {
|
|
50
|
+
if (!mod) return void 0;
|
|
51
|
+
if (isObject(mod) && exportName in mod) return mod[exportName];
|
|
52
|
+
if (exportName === "default") return unwrapNamespaceDefault(mod);
|
|
53
|
+
return void 0;
|
|
54
|
+
}
|
|
55
|
+
function looksTaggedFactory(fn, tagKey) {
|
|
56
|
+
return fn?.[tagKey] === true;
|
|
57
|
+
}
|
|
58
|
+
function isAbsoluteHttpUrl(url) {
|
|
59
|
+
return /^https?:\/\//i.test(String(url ?? "").trim());
|
|
60
|
+
}
|
|
61
|
+
function getLaravelOrigin() {
|
|
62
|
+
const ziggyUrl = window?.Ziggy?.url;
|
|
63
|
+
if (typeof ziggyUrl === "string" && ziggyUrl.length) {
|
|
64
|
+
return new URL(ziggyUrl).origin;
|
|
65
|
+
}
|
|
66
|
+
return window.location.origin.replace(/:\d+$/, "");
|
|
67
|
+
}
|
|
68
|
+
async function maybeImportUrl(url) {
|
|
69
|
+
const raw = String(url ?? "").trim();
|
|
70
|
+
if (!raw) throw new Error("Missing import url");
|
|
71
|
+
if (isAbsoluteHttpUrl(raw)) {
|
|
72
|
+
throw new Error(`Absolute import urls are not allowed: ${raw}`);
|
|
73
|
+
}
|
|
74
|
+
const path = raw.startsWith("/") ? raw : `/${raw}`;
|
|
75
|
+
const finalUrl = `${getLaravelOrigin()}${path}`;
|
|
76
|
+
return import(
|
|
77
|
+
/* @vite-ignore */
|
|
78
|
+
finalUrl
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
async function createFactory(file, env, opts = {}, hostPropsOverride) {
|
|
82
|
+
const exportName = opts.exportName ?? "default";
|
|
83
|
+
const mode = opts.mode ?? "auto";
|
|
84
|
+
const unwrapReturnedDefault = opts.unwrapReturnedDefault ?? true;
|
|
85
|
+
const runtimeKey = opts.runtimeKey ?? "imports";
|
|
86
|
+
const tagKey = opts.tagKey ?? "__forti_prep_factory__";
|
|
87
|
+
const hostUrlsOverride = opts.hostUrlsOverride ?? false;
|
|
88
|
+
const mod = await import(
|
|
89
|
+
/* @vite-ignore */
|
|
90
|
+
file
|
|
91
|
+
);
|
|
92
|
+
const picked = pickExport(mod, exportName);
|
|
93
|
+
if (picked == null) {
|
|
94
|
+
const keys = isObject(mod) ? Object.keys(mod) : [];
|
|
95
|
+
throw new Error(
|
|
96
|
+
`[fortiplugin-bundle-adapter] Export "${exportName}" not found in "${file}". Available keys: ${keys.length ? keys.join(", ") : "(none)"}`
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
const imports = {
|
|
100
|
+
react: env.react,
|
|
101
|
+
"react/jsx-runtime": env.jsxRuntime,
|
|
102
|
+
...env.imports ?? {}
|
|
103
|
+
};
|
|
104
|
+
if (env.hostUrls) {
|
|
105
|
+
for (const [id, url] of Object.entries(env.hostUrls)) {
|
|
106
|
+
const already = Object.prototype.hasOwnProperty.call(imports, id);
|
|
107
|
+
if (already && !hostUrlsOverride) continue;
|
|
108
|
+
try {
|
|
109
|
+
imports[id] = await maybeImportUrl(url);
|
|
110
|
+
} catch (err) {
|
|
111
|
+
const msg = err?.message ? String(err.message) : String(err);
|
|
112
|
+
throw new Error(
|
|
113
|
+
`[fortiplugin-bundle-adapter] Failed to import host URL for "${id}".
|
|
114
|
+
URL: ${url}
|
|
115
|
+
Error: ${msg}`
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
const deps = {
|
|
121
|
+
[runtimeKey]: imports,
|
|
122
|
+
...env.depsExtra ?? {}
|
|
123
|
+
};
|
|
124
|
+
let component = picked;
|
|
125
|
+
let wasFactory = false;
|
|
126
|
+
if (mode !== "component" && isCallable(picked)) {
|
|
127
|
+
const fn = picked;
|
|
128
|
+
const shouldTryCall = mode === "factory" || looksTaggedFactory(fn, tagKey) || mode === "auto";
|
|
129
|
+
if (shouldTryCall) {
|
|
130
|
+
let resolved;
|
|
131
|
+
try {
|
|
132
|
+
resolved = fn(deps);
|
|
133
|
+
if (resolved && typeof resolved.then === "function") {
|
|
134
|
+
resolved = await resolved;
|
|
135
|
+
}
|
|
136
|
+
} catch (err) {
|
|
137
|
+
if (mode === "factory") throw err;
|
|
138
|
+
resolved = void 0;
|
|
139
|
+
}
|
|
140
|
+
if (unwrapReturnedDefault && isObject(resolved) && "default" in resolved) {
|
|
141
|
+
resolved = resolved.default;
|
|
142
|
+
}
|
|
143
|
+
const looksLikeWeCalledAComponent = isReactElement(resolved) || resolved == null;
|
|
144
|
+
if (!looksLikeWeCalledAComponent) {
|
|
145
|
+
component = resolved;
|
|
146
|
+
wasFactory = true;
|
|
147
|
+
} else if (mode === "factory") {
|
|
148
|
+
throw new Error(
|
|
149
|
+
`[fortiplugin-bundle-adapter] Factory call did not return a component export for "${file}". Got: ${resolved == null ? String(resolved) : "ReactElement"}`
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
const hostProps = {
|
|
155
|
+
...env.hostProps ?? {},
|
|
156
|
+
...hostPropsOverride ?? {}
|
|
157
|
+
};
|
|
158
|
+
const render = ((renderProps) => {
|
|
159
|
+
const mergedProps = { ...renderProps ?? {}, ...hostProps };
|
|
160
|
+
if (isReactElement(component)) {
|
|
161
|
+
const clone = env.react.cloneElement;
|
|
162
|
+
return typeof clone === "function" ? clone(component, mergedProps) : component;
|
|
163
|
+
}
|
|
164
|
+
return env.react.createElement(component, mergedProps);
|
|
165
|
+
});
|
|
166
|
+
render.component = component;
|
|
167
|
+
render.module = mod;
|
|
168
|
+
render.exportName = exportName;
|
|
169
|
+
render.wasFactory = wasFactory;
|
|
170
|
+
render.file = file;
|
|
171
|
+
render.imports = imports;
|
|
172
|
+
render.hostProps = hostProps;
|
|
173
|
+
return render;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// src/runtime/create-resolver.ts
|
|
177
|
+
function mergeRecord(a, b) {
|
|
178
|
+
return { ...a ?? {}, ...b ?? {} };
|
|
179
|
+
}
|
|
180
|
+
function mergeEnv(base, patch) {
|
|
181
|
+
if (!patch) return base;
|
|
182
|
+
return {
|
|
183
|
+
...base,
|
|
184
|
+
...patch,
|
|
185
|
+
// deep-merge the maps
|
|
186
|
+
imports: mergeRecord(base.imports, patch.imports),
|
|
187
|
+
hostUrls: mergeRecord(base.hostUrls, patch.hostUrls),
|
|
188
|
+
depsExtra: mergeRecord(base.depsExtra, patch.depsExtra),
|
|
189
|
+
// hostProps handled separately by resolver (priority props contract)
|
|
190
|
+
hostProps: base.hostProps
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
function mergeOptions(base, patch) {
|
|
194
|
+
return { ...base ?? {}, ...patch ?? {} };
|
|
195
|
+
}
|
|
196
|
+
function createPluginResolver(config) {
|
|
197
|
+
const defaults = {
|
|
198
|
+
env: config.env,
|
|
199
|
+
options: config.options ?? {},
|
|
200
|
+
hostProps: config.hostProps ?? {}
|
|
201
|
+
};
|
|
202
|
+
const R = defaults.env.react;
|
|
203
|
+
async function resolve(file, overrides) {
|
|
204
|
+
const env = mergeEnv(defaults.env, overrides?.env);
|
|
205
|
+
const options = mergeOptions(defaults.options, overrides?.options);
|
|
206
|
+
const hostProps = mergeRecord(defaults.hostProps, overrides?.hostProps);
|
|
207
|
+
return createFactory(file, env, options, hostProps);
|
|
208
|
+
}
|
|
209
|
+
function withOverrides(overrides) {
|
|
210
|
+
return createPluginResolver({
|
|
211
|
+
env: mergeEnv(defaults.env, overrides.env),
|
|
212
|
+
options: mergeOptions(defaults.options, overrides.options),
|
|
213
|
+
hostProps: mergeRecord(defaults.hostProps, overrides.hostProps)
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
function Embed(p) {
|
|
217
|
+
const { file, props, hostProps, overrides, fallback = null, onErrorRender, onResolved } = p;
|
|
218
|
+
const [renderFn, setRenderFn] = R.useState(null);
|
|
219
|
+
const [error, setError] = R.useState(null);
|
|
220
|
+
const latest = R.useRef({ props, hostProps, overrides, onResolved });
|
|
221
|
+
latest.current = { props, hostProps, overrides, onResolved };
|
|
222
|
+
R.useEffect(() => {
|
|
223
|
+
let cancelled = false;
|
|
224
|
+
setRenderFn(null);
|
|
225
|
+
setError(null);
|
|
226
|
+
(async () => {
|
|
227
|
+
try {
|
|
228
|
+
const mergedOverrides = {
|
|
229
|
+
...latest.current.overrides ?? {},
|
|
230
|
+
hostProps: mergeRecord(
|
|
231
|
+
latest.current.overrides?.hostProps ?? {},
|
|
232
|
+
latest.current.hostProps ?? {}
|
|
233
|
+
)
|
|
234
|
+
};
|
|
235
|
+
const prepared = await resolve(file, mergedOverrides);
|
|
236
|
+
if (cancelled) return;
|
|
237
|
+
setRenderFn(() => prepared);
|
|
238
|
+
latest.current.onResolved?.({
|
|
239
|
+
file: prepared.file,
|
|
240
|
+
exportName: prepared.exportName,
|
|
241
|
+
wasFactory: prepared.wasFactory,
|
|
242
|
+
component: prepared.component,
|
|
243
|
+
module: prepared.module
|
|
244
|
+
});
|
|
245
|
+
} catch (e) {
|
|
246
|
+
if (cancelled) return;
|
|
247
|
+
setError(e);
|
|
248
|
+
}
|
|
249
|
+
})();
|
|
250
|
+
return () => {
|
|
251
|
+
cancelled = true;
|
|
252
|
+
};
|
|
253
|
+
}, [file]);
|
|
254
|
+
if (error) {
|
|
255
|
+
if (onErrorRender) return onErrorRender(error);
|
|
256
|
+
const msg = String(error?.stack ?? error?.message ?? error);
|
|
257
|
+
return R.createElement("pre", { style: { whiteSpace: "pre-wrap" } }, msg);
|
|
258
|
+
}
|
|
259
|
+
if (!renderFn) return fallback;
|
|
260
|
+
return renderFn(latest.current.props);
|
|
261
|
+
}
|
|
262
|
+
return {
|
|
263
|
+
resolve,
|
|
264
|
+
with: withOverrides,
|
|
265
|
+
Embed,
|
|
266
|
+
defaults
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
270
|
+
0 && (module.exports = {
|
|
271
|
+
createFactory,
|
|
272
|
+
createPluginResolver
|
|
273
|
+
});
|
|
274
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/runtime/index.ts","../../src/runtime/create-factory.ts","../../src/runtime/create-resolver.ts"],"sourcesContent":["export * from './create-factory';\r\nexport * from './create-resolver';","// src/runtime/create-factory.ts\r\n// noinspection GrazieInspection\r\n\r\nimport type * as ReactNS from \"react\";\r\nimport type * as JsxRuntimeNS from \"react/jsx-runtime\";\r\n\r\nexport type ReactLike = typeof ReactNS;\r\nexport type JsxRuntimeLike = typeof JsxRuntimeNS;\r\n\r\nexport type ImportMap = Record<string, any>;\r\n\r\nexport type CreateFactoryEnv = {\r\n react: ReactLike;\r\n jsxRuntime: JsxRuntimeLike;\r\n\r\n /**\r\n * Optional injected modules (merged into the import map).\r\n * Example: { \"@inertiajs/core\": InertiaCore, \"@host/ui\": HostUI }\r\n */\r\n imports?: ImportMap;\r\n\r\n /**\r\n * Optional mapping of virtual IDs to CORS-safe ESM URLs for local dev.\r\n * These URLs will be dynamically imported and added into the import map.\r\n */\r\n hostUrls?: Record<string, string>;\r\n\r\n /**\r\n * Optional base props coming from the host runtime / plugin caller.\r\n * These props are **PRIORITY** and override any props passed to `render()`.\r\n */\r\n hostProps?: Record<string, any>;\r\n\r\n /**\r\n * Extra arbitrary values the host wants to pass into the factory deps object.\r\n */\r\n depsExtra?: Record<string, any>;\r\n};\r\n\r\nexport type CreateFactoryOptions = {\r\n exportName?: string; // default: \"default\"\r\n mode?: \"auto\" | \"factory\" | \"component\"; // default: \"auto\"\r\n unwrapReturnedDefault?: boolean; // default: true\r\n runtimeKey?: string; // default: \"imports\"\r\n tagKey?: string; // default: \"__forti_prep_factory__\"\r\n hostUrlsOverride?: boolean; // default: false\r\n};\r\n\r\nfunction isObject(v: unknown): v is Record<string, any> {\r\n return !!v && typeof v === \"object\";\r\n}\r\n\r\nfunction isCallable(v: unknown): v is (...args: any[]) => any {\r\n return typeof v === \"function\";\r\n}\r\n\r\nconst REACT_ELEMENT_SYMBOLS = new Set<symbol>([\r\n Symbol.for(\"react.element\"),\r\n Symbol.for(\"react.transitional.element\"),\r\n]);\r\n\r\nfunction isReactElement(v: unknown): boolean {\r\n if (!isObject(v)) return false;\r\n const x = (v as any).$$typeof;\r\n return typeof x === \"symbol\" && REACT_ELEMENT_SYMBOLS.has(x);\r\n}\r\n\r\nfunction unwrapNamespaceDefault(mod: any): any {\r\n if (!mod) return mod;\r\n if (isObject(mod) && \"default\" in mod) return mod.default;\r\n return mod;\r\n}\r\n\r\nfunction pickExport(mod: any, exportName: string): any {\r\n if (!mod) return undefined;\r\n\r\n if (isObject(mod) && exportName in mod) return mod[exportName];\r\n\r\n if (exportName === \"default\") return unwrapNamespaceDefault(mod);\r\n\r\n return undefined;\r\n}\r\n\r\nfunction looksTaggedFactory(fn: Function, tagKey: string): boolean {\r\n return (fn as any)?.[tagKey] === true;\r\n}\r\n\r\nfunction isAbsoluteHttpUrl(url: string): boolean {\r\n return /^https?:\\/\\//i.test(String(url ?? '').trim());\r\n}\r\n\r\nfunction getLaravelOrigin(): string {\r\n const ziggyUrl = (window as any)?.Ziggy?.url;\r\n if (typeof ziggyUrl === 'string' && ziggyUrl.length) {\r\n return new URL(ziggyUrl).origin;\r\n }\r\n return window.location.origin.replace(/:\\d+$/, '');\r\n}\r\n\r\n/**\r\n * Import only non-absolute URLs.\r\n * - Rejects http(s) absolute URLs\r\n * - Accepts site-relative URLs like \"/vendor/...\" or \"/anything/...\"\r\n * - Forces the Laravel origin to avoid Vite :5173\r\n */\r\nasync function maybeImportUrl(url: string): Promise<any> {\r\n const raw = String(url ?? '').trim();\r\n if (!raw) throw new Error('Missing import url');\r\n\r\n // must NOT be absolute\r\n if (isAbsoluteHttpUrl(raw)) {\r\n throw new Error(`Absolute import urls are not allowed: ${raw}`);\r\n }\r\n\r\n // normalize to site-relative\r\n const path = raw.startsWith('/') ? raw : `/${raw}`;\r\n\r\n // force Laravel origin (avoid Vite :5173)\r\n const finalUrl = `${getLaravelOrigin()}${path}`;\r\n\r\n // IMPORTANT: url is runtime-dynamic → Vite must not pre-bundle it\r\n // @ts-ignore\r\n return import(/* @vite-ignore */ finalUrl);\r\n}\r\n\r\nexport type PreparedRenderFactory<P = any> = ((props?: Partial<P>) => any) & {\r\n component: any;\r\n module: any;\r\n exportName: string;\r\n wasFactory: boolean;\r\n file: string;\r\n\r\n /**\r\n * The final import map passed into the factory deps.\r\n */\r\n imports: ImportMap;\r\n\r\n /**\r\n * Host/base props attached to the renderer (priority).\r\n */\r\n hostProps: Record<string, any>;\r\n};\r\n\r\n/**\r\n * Import `file` NOW, resolve the component export (default or named),\r\n * then return a render factory you can call later with component props.\r\n */\r\nexport async function createFactory<P = any>(\r\n file: string,\r\n env: CreateFactoryEnv,\r\n opts: CreateFactoryOptions = {},\r\n hostPropsOverride?: Partial<P>\r\n): Promise<PreparedRenderFactory<P>> {\r\n const exportName = opts.exportName ?? \"default\";\r\n const mode = opts.mode ?? \"auto\";\r\n const unwrapReturnedDefault = opts.unwrapReturnedDefault ?? true;\r\n const runtimeKey = opts.runtimeKey ?? \"imports\";\r\n const tagKey = opts.tagKey ?? \"__forti_prep_factory__\";\r\n const hostUrlsOverride = opts.hostUrlsOverride ?? false;\r\n\r\n // 1) Import the plugin module/bundle\r\n const mod = (await import(/* @vite-ignore */ file)) as any;\r\n\r\n const picked = pickExport(mod, exportName);\r\n if (picked == null) {\r\n const keys = isObject(mod) ? Object.keys(mod) : [];\r\n throw new Error(\r\n `[fortiplugin-bundle-adapter] Export \"${exportName}\" not found in \"${file}\". ` +\r\n `Available keys: ${keys.length ? keys.join(\", \") : \"(none)\"}`\r\n );\r\n }\r\n\r\n // 2) Build import map for the adapted wrapper\r\n const imports: ImportMap = {\r\n react: env.react,\r\n \"react/jsx-runtime\": env.jsxRuntime,\r\n ...(env.imports ?? {}),\r\n };\r\n\r\n // 3) Dev-mode host bundles by URL (CORS-safe ESM)\r\n if (env.hostUrls) {\r\n for (const [id, url] of Object.entries(env.hostUrls)) {\r\n const already = Object.prototype.hasOwnProperty.call(imports, id);\r\n if (already && !hostUrlsOverride) continue;\r\n\r\n try {\r\n imports[id] = await maybeImportUrl(url);\r\n } catch (err: any) {\r\n const msg = err?.message ? String(err.message) : String(err);\r\n throw new Error(\r\n `[fortiplugin-bundle-adapter] Failed to import host URL for \"${id}\".\\n` +\r\n `URL: ${url}\\n` +\r\n `Error: ${msg}`\r\n );\r\n }\r\n }\r\n }\r\n\r\n // 4) deps object for adapted wrapper (we always pass explicit object)\r\n const deps = {\r\n [runtimeKey]: imports,\r\n ...(env.depsExtra ?? {}),\r\n };\r\n\r\n let component: any = picked;\r\n let wasFactory = false;\r\n\r\n // 5) Resolve factory → component (only if needed)\r\n if (mode !== \"component\" && isCallable(picked)) {\r\n const fn = picked as (deps: any) => any;\r\n\r\n const shouldTryCall =\r\n mode === \"factory\" || looksTaggedFactory(fn, tagKey) || mode === \"auto\";\r\n\r\n if (shouldTryCall) {\r\n let resolved: any;\r\n\r\n try {\r\n resolved = fn(deps);\r\n if (resolved && typeof (resolved as any).then === \"function\") {\r\n resolved = await resolved;\r\n }\r\n } catch (err) {\r\n if (mode === \"factory\") throw err;\r\n resolved = undefined; // rollback in auto\r\n }\r\n\r\n if (unwrapReturnedDefault && isObject(resolved) && \"default\" in resolved) {\r\n resolved = (resolved as any).default;\r\n }\r\n\r\n const looksLikeWeCalledAComponent =\r\n isReactElement(resolved) || resolved == null;\r\n\r\n if (!looksLikeWeCalledAComponent) {\r\n component = resolved;\r\n wasFactory = true;\r\n } else if (mode === \"factory\") {\r\n throw new Error(\r\n `[fortiplugin-bundle-adapter] Factory call did not return a component export for \"${file}\". ` +\r\n `Got: ${resolved == null ? String(resolved) : \"ReactElement\"}`\r\n );\r\n }\r\n // auto mode rollback => treat picked as component\r\n }\r\n }\r\n\r\n // 6) Host props are PRIORITY (override render() props)\r\n const hostProps: Record<string, any> = {\r\n ...(env.hostProps ?? {}),\r\n ...(hostPropsOverride ?? {}),\r\n };\r\n\r\n // 7) Render function merges:\r\n // renderProps (defaults) + hostProps (priority)\r\n const render = ((renderProps?: Partial<P>) => {\r\n const mergedProps = {...(renderProps ?? {}), ...hostProps} as any;\r\n\r\n if (isReactElement(component)) {\r\n // If component is already an element, attach merged props via cloneElement\r\n const clone = (env.react as any).cloneElement;\r\n return typeof clone === \"function\" ? clone(component, mergedProps) : component;\r\n }\r\n\r\n return (env.react as any).createElement(component, mergedProps);\r\n }) as PreparedRenderFactory<P>;\r\n\r\n render.component = component;\r\n render.module = mod;\r\n render.exportName = exportName;\r\n render.wasFactory = wasFactory;\r\n render.file = file;\r\n render.imports = imports;\r\n render.hostProps = hostProps;\r\n\r\n return render;\r\n}","// src/runtime/create-resolver.ts\r\n\r\nimport type {\r\n CreateFactoryEnv,\r\n CreateFactoryOptions,\r\n PreparedRenderFactory,\r\n} from \"./create-factory\";\r\nimport {createFactory} from \"./create-factory\";\r\n\r\nexport type CreateResolverConfig = {\r\n env: CreateFactoryEnv;\r\n options?: CreateFactoryOptions;\r\n\r\n /**\r\n * Base host props (priority) that should always be applied.\r\n * These override any props passed to render().\r\n */\r\n hostProps?: Record<string, any>;\r\n};\r\n\r\nexport type ResolveOverrides = {\r\n env?: Partial<CreateFactoryEnv>;\r\n options?: Partial<CreateFactoryOptions>;\r\n hostProps?: Record<string, any>;\r\n};\r\n\r\nfunction mergeRecord(a?: Record<string, any>, b?: Record<string, any>) {\r\n return {...(a ?? {}), ...(b ?? {})};\r\n}\r\n\r\nfunction mergeEnv(base: CreateFactoryEnv, patch?: Partial<CreateFactoryEnv>): CreateFactoryEnv {\r\n if (!patch) return base;\r\n\r\n return {\r\n ...base,\r\n ...patch,\r\n // deep-merge the maps\r\n imports: mergeRecord(base.imports, patch.imports),\r\n hostUrls: mergeRecord(base.hostUrls, patch.hostUrls),\r\n depsExtra: mergeRecord(base.depsExtra, patch.depsExtra),\r\n // hostProps handled separately by resolver (priority props contract)\r\n hostProps: base.hostProps,\r\n };\r\n}\r\n\r\nfunction mergeOptions(\r\n base?: CreateFactoryOptions,\r\n patch?: Partial<CreateFactoryOptions>\r\n): CreateFactoryOptions {\r\n return {...(base ?? {}), ...(patch ?? {})};\r\n}\r\n\r\nexport type PluginResolver = {\r\n /**\r\n * Resolve a plugin entry (file URL/path) into a callable renderer.\r\n * You can pass per-call overrides (e.g. inertia imports).\r\n */\r\n resolve<P = any>(file: string, overrides?: ResolveOverrides): Promise<PreparedRenderFactory<P>>;\r\n\r\n /**\r\n * Create a new resolver inheriting this resolver, with extra defaults.\r\n * Great for adding inertia / host UI / dev URLs once, then reusing everywhere.\r\n */\r\n with(overrides: ResolveOverrides): PluginResolver;\r\n\r\n /**\r\n * A React component already bound to this resolver.\r\n * Only needs `file` and props.\r\n */\r\n Embed: <P extends Record<string, any> = Record<string, any>>(\r\n props: EmbedProps<P>\r\n ) => any;\r\n\r\n /**\r\n * Expose effective defaults (handy for debugging).\r\n */\r\n defaults: Required<CreateResolverConfig>;\r\n};\r\n\r\nexport type EmbedProps<P extends Record<string, any> = Record<string, any>> = {\r\n file: string;\r\n\r\n /**\r\n * Default props (non-priority).\r\n * Host props override these.\r\n */\r\n props?: Partial<P>;\r\n\r\n /**\r\n * Per-embed host props (priority).\r\n * These override `props`.\r\n */\r\n hostProps?: Partial<P>;\r\n\r\n /**\r\n * Per-embed resolver overrides (env/options/hostProps).\r\n * Useful when a specific plugin needs inertia, etc.\r\n */\r\n overrides?: ResolveOverrides;\r\n\r\n fallback?: any;\r\n onErrorRender?: (error: unknown) => any;\r\n\r\n onResolved?: (info: {\r\n file: string;\r\n exportName: string;\r\n wasFactory: boolean;\r\n component: any;\r\n module: any;\r\n }) => void;\r\n};\r\n\r\nexport function createPluginResolver(config: CreateResolverConfig): PluginResolver {\r\n const defaults: Required<CreateResolverConfig> = {\r\n env: config.env,\r\n options: config.options ?? {},\r\n hostProps: config.hostProps ?? {},\r\n };\r\n\r\n const R = defaults.env.react as any;\r\n\r\n async function resolve<P = any>(file: string, overrides?: ResolveOverrides) {\r\n const env = mergeEnv(defaults.env, overrides?.env);\r\n const options = mergeOptions(defaults.options, overrides?.options);\r\n\r\n // Priority host props contract:\r\n // - base resolver hostProps always apply\r\n // - per-call overrides hostProps can add/override base hostProps\r\n const hostProps = mergeRecord(defaults.hostProps, overrides?.hostProps);\r\n\r\n // @ts-ignore\r\n return createFactory<P>(file, env, options, hostProps);\r\n }\r\n\r\n function withOverrides(overrides: ResolveOverrides): PluginResolver {\r\n return createPluginResolver({\r\n env: mergeEnv(defaults.env, overrides.env),\r\n options: mergeOptions(defaults.options, overrides.options),\r\n hostProps: mergeRecord(defaults.hostProps, overrides.hostProps),\r\n });\r\n }\r\n\r\n function Embed<P extends Record<string, any> = Record<string, any>>(p: EmbedProps<P>) {\r\n const {file, props, hostProps, overrides, fallback = null, onErrorRender, onResolved} = p;\r\n\r\n const [renderFn, setRenderFn] = R.useState(null as null | ((pp?: Partial<P>) => any));\r\n const [error, setError] = R.useState(null as unknown);\r\n\r\n // keep latest values without constantly re-resolving\r\n const latest = R.useRef({props, hostProps, overrides, onResolved});\r\n latest.current = {props, hostProps, overrides, onResolved};\r\n\r\n R.useEffect(() => {\r\n let cancelled = false;\r\n setRenderFn(null);\r\n setError(null);\r\n\r\n (async () => {\r\n try {\r\n // merge per-embed priority hostProps into per-call overrides\r\n const mergedOverrides: ResolveOverrides = {\r\n ...(latest.current.overrides ?? {}),\r\n hostProps: mergeRecord(\r\n (latest.current.overrides?.hostProps ?? {}),\r\n (latest.current.hostProps as any) ?? {}\r\n ),\r\n };\r\n\r\n const prepared = await resolve<P>(file, mergedOverrides);\r\n\r\n if (cancelled) return;\r\n\r\n setRenderFn(() => prepared);\r\n\r\n latest.current.onResolved?.({\r\n file: prepared.file,\r\n exportName: prepared.exportName,\r\n wasFactory: prepared.wasFactory,\r\n component: prepared.component,\r\n module: prepared.module,\r\n });\r\n } catch (e) {\r\n if (cancelled) return;\r\n setError(e);\r\n }\r\n })();\r\n\r\n return () => {\r\n cancelled = true;\r\n };\r\n }, [file]);\r\n\r\n if (error) {\r\n if (onErrorRender) return onErrorRender(error);\r\n const msg = String((error as any)?.stack ?? (error as any)?.message ?? error);\r\n return R.createElement(\"pre\", {style: {whiteSpace: \"pre-wrap\"}}, msg);\r\n }\r\n\r\n if (!renderFn) return fallback;\r\n\r\n // NOTE: createFactory() already merges render props + host props (host wins)\r\n return renderFn(latest.current.props);\r\n }\r\n\r\n return {\r\n resolve,\r\n with: withOverrides,\r\n Embed,\r\n defaults,\r\n };\r\n}"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import * as ReactNS from 'react';
|
|
2
|
+
import * as JsxRuntimeNS from 'react/jsx-runtime';
|
|
3
|
+
|
|
4
|
+
type ReactLike = typeof ReactNS;
|
|
5
|
+
type JsxRuntimeLike = typeof JsxRuntimeNS;
|
|
6
|
+
type ImportMap = Record<string, any>;
|
|
7
|
+
type CreateFactoryEnv = {
|
|
8
|
+
react: ReactLike;
|
|
9
|
+
jsxRuntime: JsxRuntimeLike;
|
|
10
|
+
/**
|
|
11
|
+
* Optional injected modules (merged into the import map).
|
|
12
|
+
* Example: { "@inertiajs/core": InertiaCore, "@host/ui": HostUI }
|
|
13
|
+
*/
|
|
14
|
+
imports?: ImportMap;
|
|
15
|
+
/**
|
|
16
|
+
* Optional mapping of virtual IDs to CORS-safe ESM URLs for local dev.
|
|
17
|
+
* These URLs will be dynamically imported and added into the import map.
|
|
18
|
+
*/
|
|
19
|
+
hostUrls?: Record<string, string>;
|
|
20
|
+
/**
|
|
21
|
+
* Optional base props coming from the host runtime / plugin caller.
|
|
22
|
+
* These props are **PRIORITY** and override any props passed to `render()`.
|
|
23
|
+
*/
|
|
24
|
+
hostProps?: Record<string, any>;
|
|
25
|
+
/**
|
|
26
|
+
* Extra arbitrary values the host wants to pass into the factory deps object.
|
|
27
|
+
*/
|
|
28
|
+
depsExtra?: Record<string, any>;
|
|
29
|
+
};
|
|
30
|
+
type CreateFactoryOptions = {
|
|
31
|
+
exportName?: string;
|
|
32
|
+
mode?: "auto" | "factory" | "component";
|
|
33
|
+
unwrapReturnedDefault?: boolean;
|
|
34
|
+
runtimeKey?: string;
|
|
35
|
+
tagKey?: string;
|
|
36
|
+
hostUrlsOverride?: boolean;
|
|
37
|
+
};
|
|
38
|
+
type PreparedRenderFactory<P = any> = ((props?: Partial<P>) => any) & {
|
|
39
|
+
component: any;
|
|
40
|
+
module: any;
|
|
41
|
+
exportName: string;
|
|
42
|
+
wasFactory: boolean;
|
|
43
|
+
file: string;
|
|
44
|
+
/**
|
|
45
|
+
* The final import map passed into the factory deps.
|
|
46
|
+
*/
|
|
47
|
+
imports: ImportMap;
|
|
48
|
+
/**
|
|
49
|
+
* Host/base props attached to the renderer (priority).
|
|
50
|
+
*/
|
|
51
|
+
hostProps: Record<string, any>;
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* Import `file` NOW, resolve the component export (default or named),
|
|
55
|
+
* then return a render factory you can call later with component props.
|
|
56
|
+
*/
|
|
57
|
+
declare function createFactory<P = any>(file: string, env: CreateFactoryEnv, opts?: CreateFactoryOptions, hostPropsOverride?: Partial<P>): Promise<PreparedRenderFactory<P>>;
|
|
58
|
+
|
|
59
|
+
type CreateResolverConfig = {
|
|
60
|
+
env: CreateFactoryEnv;
|
|
61
|
+
options?: CreateFactoryOptions;
|
|
62
|
+
/**
|
|
63
|
+
* Base host props (priority) that should always be applied.
|
|
64
|
+
* These override any props passed to render().
|
|
65
|
+
*/
|
|
66
|
+
hostProps?: Record<string, any>;
|
|
67
|
+
};
|
|
68
|
+
type ResolveOverrides = {
|
|
69
|
+
env?: Partial<CreateFactoryEnv>;
|
|
70
|
+
options?: Partial<CreateFactoryOptions>;
|
|
71
|
+
hostProps?: Record<string, any>;
|
|
72
|
+
};
|
|
73
|
+
type PluginResolver = {
|
|
74
|
+
/**
|
|
75
|
+
* Resolve a plugin entry (file URL/path) into a callable renderer.
|
|
76
|
+
* You can pass per-call overrides (e.g. inertia imports).
|
|
77
|
+
*/
|
|
78
|
+
resolve<P = any>(file: string, overrides?: ResolveOverrides): Promise<PreparedRenderFactory<P>>;
|
|
79
|
+
/**
|
|
80
|
+
* Create a new resolver inheriting this resolver, with extra defaults.
|
|
81
|
+
* Great for adding inertia / host UI / dev URLs once, then reusing everywhere.
|
|
82
|
+
*/
|
|
83
|
+
with(overrides: ResolveOverrides): PluginResolver;
|
|
84
|
+
/**
|
|
85
|
+
* A React component already bound to this resolver.
|
|
86
|
+
* Only needs `file` and props.
|
|
87
|
+
*/
|
|
88
|
+
Embed: <P extends Record<string, any> = Record<string, any>>(props: EmbedProps<P>) => any;
|
|
89
|
+
/**
|
|
90
|
+
* Expose effective defaults (handy for debugging).
|
|
91
|
+
*/
|
|
92
|
+
defaults: Required<CreateResolverConfig>;
|
|
93
|
+
};
|
|
94
|
+
type EmbedProps<P extends Record<string, any> = Record<string, any>> = {
|
|
95
|
+
file: string;
|
|
96
|
+
/**
|
|
97
|
+
* Default props (non-priority).
|
|
98
|
+
* Host props override these.
|
|
99
|
+
*/
|
|
100
|
+
props?: Partial<P>;
|
|
101
|
+
/**
|
|
102
|
+
* Per-embed host props (priority).
|
|
103
|
+
* These override `props`.
|
|
104
|
+
*/
|
|
105
|
+
hostProps?: Partial<P>;
|
|
106
|
+
/**
|
|
107
|
+
* Per-embed resolver overrides (env/options/hostProps).
|
|
108
|
+
* Useful when a specific plugin needs inertia, etc.
|
|
109
|
+
*/
|
|
110
|
+
overrides?: ResolveOverrides;
|
|
111
|
+
fallback?: any;
|
|
112
|
+
onErrorRender?: (error: unknown) => any;
|
|
113
|
+
onResolved?: (info: {
|
|
114
|
+
file: string;
|
|
115
|
+
exportName: string;
|
|
116
|
+
wasFactory: boolean;
|
|
117
|
+
component: any;
|
|
118
|
+
module: any;
|
|
119
|
+
}) => void;
|
|
120
|
+
};
|
|
121
|
+
declare function createPluginResolver(config: CreateResolverConfig): PluginResolver;
|
|
122
|
+
|
|
123
|
+
export { type CreateFactoryEnv, type CreateFactoryOptions, type CreateResolverConfig, type EmbedProps, type ImportMap, type JsxRuntimeLike, type PluginResolver, type PreparedRenderFactory, type ReactLike, type ResolveOverrides, createFactory, createPluginResolver };
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import * as ReactNS from 'react';
|
|
2
|
+
import * as JsxRuntimeNS from 'react/jsx-runtime';
|
|
3
|
+
|
|
4
|
+
type ReactLike = typeof ReactNS;
|
|
5
|
+
type JsxRuntimeLike = typeof JsxRuntimeNS;
|
|
6
|
+
type ImportMap = Record<string, any>;
|
|
7
|
+
type CreateFactoryEnv = {
|
|
8
|
+
react: ReactLike;
|
|
9
|
+
jsxRuntime: JsxRuntimeLike;
|
|
10
|
+
/**
|
|
11
|
+
* Optional injected modules (merged into the import map).
|
|
12
|
+
* Example: { "@inertiajs/core": InertiaCore, "@host/ui": HostUI }
|
|
13
|
+
*/
|
|
14
|
+
imports?: ImportMap;
|
|
15
|
+
/**
|
|
16
|
+
* Optional mapping of virtual IDs to CORS-safe ESM URLs for local dev.
|
|
17
|
+
* These URLs will be dynamically imported and added into the import map.
|
|
18
|
+
*/
|
|
19
|
+
hostUrls?: Record<string, string>;
|
|
20
|
+
/**
|
|
21
|
+
* Optional base props coming from the host runtime / plugin caller.
|
|
22
|
+
* These props are **PRIORITY** and override any props passed to `render()`.
|
|
23
|
+
*/
|
|
24
|
+
hostProps?: Record<string, any>;
|
|
25
|
+
/**
|
|
26
|
+
* Extra arbitrary values the host wants to pass into the factory deps object.
|
|
27
|
+
*/
|
|
28
|
+
depsExtra?: Record<string, any>;
|
|
29
|
+
};
|
|
30
|
+
type CreateFactoryOptions = {
|
|
31
|
+
exportName?: string;
|
|
32
|
+
mode?: "auto" | "factory" | "component";
|
|
33
|
+
unwrapReturnedDefault?: boolean;
|
|
34
|
+
runtimeKey?: string;
|
|
35
|
+
tagKey?: string;
|
|
36
|
+
hostUrlsOverride?: boolean;
|
|
37
|
+
};
|
|
38
|
+
type PreparedRenderFactory<P = any> = ((props?: Partial<P>) => any) & {
|
|
39
|
+
component: any;
|
|
40
|
+
module: any;
|
|
41
|
+
exportName: string;
|
|
42
|
+
wasFactory: boolean;
|
|
43
|
+
file: string;
|
|
44
|
+
/**
|
|
45
|
+
* The final import map passed into the factory deps.
|
|
46
|
+
*/
|
|
47
|
+
imports: ImportMap;
|
|
48
|
+
/**
|
|
49
|
+
* Host/base props attached to the renderer (priority).
|
|
50
|
+
*/
|
|
51
|
+
hostProps: Record<string, any>;
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* Import `file` NOW, resolve the component export (default or named),
|
|
55
|
+
* then return a render factory you can call later with component props.
|
|
56
|
+
*/
|
|
57
|
+
declare function createFactory<P = any>(file: string, env: CreateFactoryEnv, opts?: CreateFactoryOptions, hostPropsOverride?: Partial<P>): Promise<PreparedRenderFactory<P>>;
|
|
58
|
+
|
|
59
|
+
type CreateResolverConfig = {
|
|
60
|
+
env: CreateFactoryEnv;
|
|
61
|
+
options?: CreateFactoryOptions;
|
|
62
|
+
/**
|
|
63
|
+
* Base host props (priority) that should always be applied.
|
|
64
|
+
* These override any props passed to render().
|
|
65
|
+
*/
|
|
66
|
+
hostProps?: Record<string, any>;
|
|
67
|
+
};
|
|
68
|
+
type ResolveOverrides = {
|
|
69
|
+
env?: Partial<CreateFactoryEnv>;
|
|
70
|
+
options?: Partial<CreateFactoryOptions>;
|
|
71
|
+
hostProps?: Record<string, any>;
|
|
72
|
+
};
|
|
73
|
+
type PluginResolver = {
|
|
74
|
+
/**
|
|
75
|
+
* Resolve a plugin entry (file URL/path) into a callable renderer.
|
|
76
|
+
* You can pass per-call overrides (e.g. inertia imports).
|
|
77
|
+
*/
|
|
78
|
+
resolve<P = any>(file: string, overrides?: ResolveOverrides): Promise<PreparedRenderFactory<P>>;
|
|
79
|
+
/**
|
|
80
|
+
* Create a new resolver inheriting this resolver, with extra defaults.
|
|
81
|
+
* Great for adding inertia / host UI / dev URLs once, then reusing everywhere.
|
|
82
|
+
*/
|
|
83
|
+
with(overrides: ResolveOverrides): PluginResolver;
|
|
84
|
+
/**
|
|
85
|
+
* A React component already bound to this resolver.
|
|
86
|
+
* Only needs `file` and props.
|
|
87
|
+
*/
|
|
88
|
+
Embed: <P extends Record<string, any> = Record<string, any>>(props: EmbedProps<P>) => any;
|
|
89
|
+
/**
|
|
90
|
+
* Expose effective defaults (handy for debugging).
|
|
91
|
+
*/
|
|
92
|
+
defaults: Required<CreateResolverConfig>;
|
|
93
|
+
};
|
|
94
|
+
type EmbedProps<P extends Record<string, any> = Record<string, any>> = {
|
|
95
|
+
file: string;
|
|
96
|
+
/**
|
|
97
|
+
* Default props (non-priority).
|
|
98
|
+
* Host props override these.
|
|
99
|
+
*/
|
|
100
|
+
props?: Partial<P>;
|
|
101
|
+
/**
|
|
102
|
+
* Per-embed host props (priority).
|
|
103
|
+
* These override `props`.
|
|
104
|
+
*/
|
|
105
|
+
hostProps?: Partial<P>;
|
|
106
|
+
/**
|
|
107
|
+
* Per-embed resolver overrides (env/options/hostProps).
|
|
108
|
+
* Useful when a specific plugin needs inertia, etc.
|
|
109
|
+
*/
|
|
110
|
+
overrides?: ResolveOverrides;
|
|
111
|
+
fallback?: any;
|
|
112
|
+
onErrorRender?: (error: unknown) => any;
|
|
113
|
+
onResolved?: (info: {
|
|
114
|
+
file: string;
|
|
115
|
+
exportName: string;
|
|
116
|
+
wasFactory: boolean;
|
|
117
|
+
component: any;
|
|
118
|
+
module: any;
|
|
119
|
+
}) => void;
|
|
120
|
+
};
|
|
121
|
+
declare function createPluginResolver(config: CreateResolverConfig): PluginResolver;
|
|
122
|
+
|
|
123
|
+
export { type CreateFactoryEnv, type CreateFactoryOptions, type CreateResolverConfig, type EmbedProps, type ImportMap, type JsxRuntimeLike, type PluginResolver, type PreparedRenderFactory, type ReactLike, type ResolveOverrides, createFactory, createPluginResolver };
|