@mints-cloud/cxf-codegen 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +117 -0
- package/dist/components/ApiCall.d.ts +19 -0
- package/dist/components/ApiCall.d.ts.map +1 -0
- package/dist/components/ApiCall.js +92 -0
- package/dist/components/IsrPageWrapper.d.ts +1 -0
- package/dist/components/IsrPageWrapper.d.ts.map +1 -0
- package/dist/components/IsrPageWrapper.js +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +53 -0
- package/dist/lib/api-call-hooks.d.ts +25 -0
- package/dist/lib/api-call-hooks.d.ts.map +1 -0
- package/dist/lib/api-call-hooks.js +267 -0
- package/dist/lib/api-route-helpers.d.ts +10 -0
- package/dist/lib/api-route-helpers.d.ts.map +1 -0
- package/dist/lib/api-route-helpers.js +73 -0
- package/dist/lib/cxf-auth.d.ts +43 -0
- package/dist/lib/cxf-auth.d.ts.map +1 -0
- package/dist/lib/cxf-auth.js +189 -0
- package/dist/lib/server-props.d.ts +77 -0
- package/dist/lib/server-props.d.ts.map +1 -0
- package/dist/lib/server-props.js +353 -0
- package/dist/next.config.d.ts +9 -0
- package/dist/next.config.d.ts.map +1 -0
- package/dist/next.config.js +19 -0
- package/dist/pages/api/assets.d.ts +4 -0
- package/dist/pages/api/assets.d.ts.map +1 -0
- package/dist/pages/api/assets.js +30 -0
- package/dist/pages/api/cxf.d.ts +4 -0
- package/dist/pages/api/cxf.d.ts.map +1 -0
- package/dist/pages/api/cxf.js +48 -0
- package/dist/pages/app.d.ts +4 -0
- package/dist/pages/app.d.ts.map +1 -0
- package/dist/pages/app.js +28 -0
- package/dist/pages/plasmic-host.d.ts +3 -0
- package/dist/pages/plasmic-host.d.ts.map +1 -0
- package/dist/pages/plasmic-host.js +15 -0
- package/dist/register.d.ts +2 -0
- package/dist/register.d.ts.map +1 -0
- package/dist/register.js +91 -0
- package/package.json +100 -0
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.PrefetchCollectorContext = exports.EndpointDataContext = void 0;
|
|
37
|
+
exports.normalizeEndpointPath = normalizeEndpointPath;
|
|
38
|
+
exports.buildQueryString = buildQueryString;
|
|
39
|
+
exports.buildEndpointKey = buildEndpointKey;
|
|
40
|
+
exports.PrefetchCollectorProvider = PrefetchCollectorProvider;
|
|
41
|
+
exports.ServerPageWrapper = ServerPageWrapper;
|
|
42
|
+
exports.createServerProps = createServerProps;
|
|
43
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
44
|
+
const React = __importStar(require("react"));
|
|
45
|
+
const query_1 = require("@plasmicapp/react-web/lib/query");
|
|
46
|
+
const prepass_1 = require("@plasmicapp/react-web/lib/prepass");
|
|
47
|
+
const cxf_auth_1 = require("./cxf-auth");
|
|
48
|
+
const loggedBuildIds = new Set();
|
|
49
|
+
// Context that provides pre-fetched endpoint data to ApiCall components
|
|
50
|
+
// This allows components to skip client-side fetching when data is already available from server-side prefetching
|
|
51
|
+
exports.EndpointDataContext = React.createContext({});
|
|
52
|
+
function normalizeEndpointPath(endpointPath) {
|
|
53
|
+
const trimmed = String(endpointPath || "").replace(/^\/+|\/+$/g, "");
|
|
54
|
+
return trimmed || "";
|
|
55
|
+
}
|
|
56
|
+
// Builds a stable, sorted query string from params for consistent cache keys
|
|
57
|
+
function buildQueryString(params) {
|
|
58
|
+
if (!params || typeof params !== "object" || Array.isArray(params))
|
|
59
|
+
return "";
|
|
60
|
+
const usp = new URLSearchParams();
|
|
61
|
+
Object.keys(params).sort().forEach((k) => {
|
|
62
|
+
const v = params[k];
|
|
63
|
+
if (v == null)
|
|
64
|
+
return;
|
|
65
|
+
if (Array.isArray(v)) {
|
|
66
|
+
v.forEach((item) => usp.append(k, String(item)));
|
|
67
|
+
}
|
|
68
|
+
else if (typeof v === "object") {
|
|
69
|
+
usp.append(k, JSON.stringify(v));
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
usp.append(k, String(v));
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
const qs = usp.toString();
|
|
76
|
+
return qs ? `?${qs}` : "";
|
|
77
|
+
}
|
|
78
|
+
// Creates a stable cache key from endpoint path + params
|
|
79
|
+
// Used to match pre-fetched data with component requests
|
|
80
|
+
function buildEndpointKey(endpointPath, params) {
|
|
81
|
+
const normalizedPath = normalizeEndpointPath(endpointPath);
|
|
82
|
+
const qs = buildQueryString(params);
|
|
83
|
+
return qs ? `${normalizedPath}${qs}` : normalizedPath;
|
|
84
|
+
}
|
|
85
|
+
function extractUtmParamsFromQuery(query) {
|
|
86
|
+
const result = {};
|
|
87
|
+
if (!query || typeof query !== "object")
|
|
88
|
+
return result;
|
|
89
|
+
for (const key of Object.keys(query)) {
|
|
90
|
+
if (key.toLowerCase().startsWith("utm_")) {
|
|
91
|
+
result[key] = query[key];
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return result;
|
|
95
|
+
}
|
|
96
|
+
exports.PrefetchCollectorContext = React.createContext(null);
|
|
97
|
+
// Provider that collects prefetch requests during component rendering
|
|
98
|
+
// Used during build-time prepass to discover all API calls
|
|
99
|
+
function PrefetchCollectorProvider({ children, collector, }) {
|
|
100
|
+
const value = React.useMemo(() => ({ register: (req) => collector.push(req) }), [collector]);
|
|
101
|
+
return ((0, jsx_runtime_1.jsx)(exports.PrefetchCollectorContext.Provider, { value: value, children: children }));
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Wrapper component that provides pre-fetched data to child components.
|
|
105
|
+
*
|
|
106
|
+
* CACHING STRATEGY:
|
|
107
|
+
* - queryCache: Pre-fetched Plasmic query data (from extractPlasmicQueryData)
|
|
108
|
+
* - endpointData: Pre-fetched custom endpoint data (from ApiCall)
|
|
109
|
+
*
|
|
110
|
+
* Components receive data via React Context, eliminating client-side loading states.
|
|
111
|
+
* This enables instant page loads with zero API calls on initial render.
|
|
112
|
+
*/
|
|
113
|
+
function ServerPageWrapper({ children, queryCache, endpointData, buildId, buildTimestamp, queriesFound, }) {
|
|
114
|
+
if (process.env.NODE_ENV !== "production" &&
|
|
115
|
+
typeof window === "undefined" &&
|
|
116
|
+
buildId &&
|
|
117
|
+
!loggedBuildIds.has(buildId)) {
|
|
118
|
+
loggedBuildIds.add(buildId);
|
|
119
|
+
console.log("Server Props Debug:", {
|
|
120
|
+
buildId,
|
|
121
|
+
buildTime: buildTimestamp,
|
|
122
|
+
queriesFound,
|
|
123
|
+
hasCache: !!queryCache,
|
|
124
|
+
endpointsPreFetched: endpointData ? Object.keys(endpointData).length : 0,
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
const hasPrefetchData = !!queryCache && Object.keys(queryCache).length > 0;
|
|
128
|
+
const hasEndpointData = !!endpointData && Object.keys(endpointData).length > 0;
|
|
129
|
+
// Provide endpoint data via Context so ApiCall can consume it
|
|
130
|
+
const wrappedChildren = hasEndpointData ? ((0, jsx_runtime_1.jsx)(exports.EndpointDataContext.Provider, { value: endpointData, children: children })) : (children);
|
|
131
|
+
// Provide Plasmic query cache for Plasmic components
|
|
132
|
+
if (hasPrefetchData) {
|
|
133
|
+
return ((0, jsx_runtime_1.jsx)(query_1.PlasmicQueryDataProvider, { prefetchedCache: queryCache, children: wrappedChildren }));
|
|
134
|
+
}
|
|
135
|
+
// Fallback: render without cache (local dev only)
|
|
136
|
+
return (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: wrappedChildren });
|
|
137
|
+
}
|
|
138
|
+
// Unwraps nested { data: {...} } responses from CXF APIs
|
|
139
|
+
function unwrapData(data) {
|
|
140
|
+
if (data &&
|
|
141
|
+
typeof data === "object" &&
|
|
142
|
+
!Array.isArray(data) &&
|
|
143
|
+
"data" in data &&
|
|
144
|
+
Object.keys(data).length === 1) {
|
|
145
|
+
return data.data;
|
|
146
|
+
}
|
|
147
|
+
return data;
|
|
148
|
+
}
|
|
149
|
+
// Checks if response indicates auth is required
|
|
150
|
+
function isAuthError(status, error) {
|
|
151
|
+
return status === 401 || status === 419 ||
|
|
152
|
+
error?.message?.includes("401") ||
|
|
153
|
+
error?.message?.includes("419");
|
|
154
|
+
}
|
|
155
|
+
// Fetches data from a URL during build time or SSR
|
|
156
|
+
// Returns null for auth errors (401/419) when cookies aren't available during build
|
|
157
|
+
// Uses makeAuthenticatedRequest when cookies are available (SSR scenarios)
|
|
158
|
+
async function fetchFromUrl(url, options = {}) {
|
|
159
|
+
const { headers = {}, cookieHeader, apiKey, useAuth = false } = options;
|
|
160
|
+
try {
|
|
161
|
+
let resp;
|
|
162
|
+
// Use authenticated request if cookies are available (SSR scenario)
|
|
163
|
+
if (useAuth && cookieHeader && apiKey) {
|
|
164
|
+
try {
|
|
165
|
+
const { response } = await (0, cxf_auth_1.makeAuthenticatedRequest)(url, {
|
|
166
|
+
method: "GET",
|
|
167
|
+
cookieHeader,
|
|
168
|
+
apiKey,
|
|
169
|
+
retryOnAuthError: true,
|
|
170
|
+
});
|
|
171
|
+
resp = response;
|
|
172
|
+
}
|
|
173
|
+
catch (error) {
|
|
174
|
+
if (isAuthError(0, error))
|
|
175
|
+
return null;
|
|
176
|
+
throw error;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
resp = await fetch(url, { method: "GET", headers });
|
|
181
|
+
}
|
|
182
|
+
if (!resp.ok) {
|
|
183
|
+
if (isAuthError(resp.status))
|
|
184
|
+
return null;
|
|
185
|
+
throw new Error(`Request failed (${resp.status})`);
|
|
186
|
+
}
|
|
187
|
+
const contentType = resp.headers.get("content-type") || "";
|
|
188
|
+
const data = contentType.includes("application/json")
|
|
189
|
+
? await resp.json()
|
|
190
|
+
: await resp.text();
|
|
191
|
+
return unwrapData(data);
|
|
192
|
+
}
|
|
193
|
+
catch (error) {
|
|
194
|
+
if (isAuthError(0, error))
|
|
195
|
+
return null;
|
|
196
|
+
throw error;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Fetches endpoint data during build time for ISR prerendering or during SSR.
|
|
201
|
+
*
|
|
202
|
+
* PREFETCHING STRATEGY:
|
|
203
|
+
* - Tries upstream CXF API first (using CXF_BASE_URL + API key)
|
|
204
|
+
* - Falls back to local dev server if upstream unavailable
|
|
205
|
+
* - When cookies are available (SSR), uses authenticated requests with Contact Auth
|
|
206
|
+
* - Silently skips auth-protected endpoints (401/419) during build - these fetch at runtime
|
|
207
|
+
* - Returns null on errors to allow graceful degradation
|
|
208
|
+
*/
|
|
209
|
+
async function fetchEndpointData(endpointPath, params, cookieHeader) {
|
|
210
|
+
try {
|
|
211
|
+
const normalizedPath = normalizeEndpointPath(endpointPath);
|
|
212
|
+
const queryString = buildQueryString(params);
|
|
213
|
+
// Determine API key type from path
|
|
214
|
+
const apiKeyType = normalizedPath.startsWith("dev/v1/") ? "dev" :
|
|
215
|
+
normalizedPath.startsWith("user/v1/") ? "user" : "public";
|
|
216
|
+
const isCxfApiPath = normalizedPath.startsWith("v1/") ||
|
|
217
|
+
normalizedPath.startsWith("dev/v1/") ||
|
|
218
|
+
normalizedPath.startsWith("user/v1/");
|
|
219
|
+
// Check if we have Contact Auth cookies available
|
|
220
|
+
const tokens = cookieHeader ? (0, cxf_auth_1.getTokensFromCookies)(cookieHeader) : null;
|
|
221
|
+
const hasContactAuth = !!(tokens?.accessToken || tokens?.refreshToken);
|
|
222
|
+
const baseUrl = (0, cxf_auth_1.getCxfBaseUrl)();
|
|
223
|
+
const apiKey = (0, cxf_auth_1.getCxfApiKey)(apiKeyType);
|
|
224
|
+
// Build target URL
|
|
225
|
+
const targetPath = isCxfApiPath ? normalizedPath : `v1/endpoints/${normalizedPath}`;
|
|
226
|
+
const targetUrl = baseUrl && apiKey
|
|
227
|
+
? `${baseUrl.replace(/\/+$/, "")}/api/${targetPath}${queryString}`
|
|
228
|
+
: `http://localhost:3000/api/${normalizedPath}${queryString}`;
|
|
229
|
+
// Determine fetch options
|
|
230
|
+
if (hasContactAuth && apiKey) {
|
|
231
|
+
return fetchFromUrl(targetUrl, { cookieHeader, apiKey, useAuth: true });
|
|
232
|
+
}
|
|
233
|
+
else {
|
|
234
|
+
const headers = { Accept: "application/json" };
|
|
235
|
+
if (apiKey)
|
|
236
|
+
headers["api-key"] = apiKey;
|
|
237
|
+
return fetchFromUrl(targetUrl, { headers });
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
catch (error) {
|
|
241
|
+
const errorMessage = error?.message || String(error);
|
|
242
|
+
if (!isAuthError(0, error)) {
|
|
243
|
+
console.error(`Error fetching endpoint data for ${endpointPath}:`, errorMessage);
|
|
244
|
+
}
|
|
245
|
+
return null;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Create Next.js data fetching functions with ISR/SSR support.
|
|
250
|
+
*
|
|
251
|
+
* PRERENDERING PROCESS:
|
|
252
|
+
* 1. Renders the Plasmic component to discover all API calls
|
|
253
|
+
* - extractPlasmicQueryData: Discovers Plasmic queries
|
|
254
|
+
* - PrefetchCollectorProvider: Collects ApiCall requests
|
|
255
|
+
*
|
|
256
|
+
* 2. Prefetches all discovered data in parallel
|
|
257
|
+
* - Fetches Plasmic query data
|
|
258
|
+
* - Fetches custom endpoint data (with Contact Auth when available)
|
|
259
|
+
* - Deduplicates requests by cache key
|
|
260
|
+
*
|
|
261
|
+
* 3. Returns props with data
|
|
262
|
+
* - ISR mode: Caches data with revalidate period (stale-while-revalidate)
|
|
263
|
+
* - SSR mode: Returns fresh data on every request
|
|
264
|
+
*
|
|
265
|
+
* CACHING BEHAVIOR:
|
|
266
|
+
* - ISR: Data cached at build time, regenerates in background after revalidate
|
|
267
|
+
* - SSR: Fresh data on every request, always has access to request cookies
|
|
268
|
+
*/
|
|
269
|
+
function createServerProps(path, PlasmicComponent, options = {}) {
|
|
270
|
+
const { mode = "isr", revalidate = 60, endpoints = [] } = options;
|
|
271
|
+
const finalRevalidate = process.env.NODE_ENV === "production" ? revalidate : 60;
|
|
272
|
+
const isSSR = mode === "ssr";
|
|
273
|
+
const isDev = process.env.NODE_ENV !== "production";
|
|
274
|
+
const handler = async (context) => {
|
|
275
|
+
const buildId = `${isSSR ? "ssr" : "build"}-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
276
|
+
const buildTimestamp = new Date().toISOString();
|
|
277
|
+
// Helper to build error props
|
|
278
|
+
const buildErrorProps = () => ({
|
|
279
|
+
queryCache: {},
|
|
280
|
+
buildId,
|
|
281
|
+
buildTimestamp,
|
|
282
|
+
queriesFound: 0,
|
|
283
|
+
_prefetchEnabled: true,
|
|
284
|
+
});
|
|
285
|
+
// Helper to build success props
|
|
286
|
+
const buildProps = (queryCache, endpointData) => {
|
|
287
|
+
const props = {
|
|
288
|
+
queryCache: queryCache || {},
|
|
289
|
+
buildId,
|
|
290
|
+
buildTimestamp,
|
|
291
|
+
queriesFound: queryCache ? Object.keys(queryCache).length : 0,
|
|
292
|
+
_prefetchEnabled: true,
|
|
293
|
+
};
|
|
294
|
+
if (Object.keys(endpointData).length > 0) {
|
|
295
|
+
props.endpointData = endpointData;
|
|
296
|
+
}
|
|
297
|
+
return props;
|
|
298
|
+
};
|
|
299
|
+
// Helper to return result based on mode
|
|
300
|
+
const returnResult = (props) => isSSR ? { props } : { props, revalidate: finalRevalidate };
|
|
301
|
+
try {
|
|
302
|
+
// Discover API calls by rendering component
|
|
303
|
+
const collected = [];
|
|
304
|
+
const element = ((0, jsx_runtime_1.jsx)(PrefetchCollectorProvider, { collector: collected, children: (0, jsx_runtime_1.jsx)(PlasmicComponent, {}) }));
|
|
305
|
+
const queryCache = await (0, prepass_1.extractPlasmicQueryData)(element);
|
|
306
|
+
// Debug logging
|
|
307
|
+
if (isDev) {
|
|
308
|
+
console.log(`[${isSSR ? "SSR" : "ISR"}] ${path}: Collected ${collected.length} endpoint requests:`, collected.map(c => buildEndpointKey(c.endpointPath, c.params)));
|
|
309
|
+
}
|
|
310
|
+
// Merge collected and configured endpoints, then fetch in parallel
|
|
311
|
+
const merged = [...collected, ...endpoints];
|
|
312
|
+
const cookieHeader = isSSR
|
|
313
|
+
? context.req?.headers?.cookie || null
|
|
314
|
+
: context.req?.headers?.cookie || null;
|
|
315
|
+
const utmFromRequest = isSSR ? extractUtmParamsFromQuery(context?.query) : {};
|
|
316
|
+
const endpointData = {};
|
|
317
|
+
if (merged.length > 0) {
|
|
318
|
+
const seen = new Set();
|
|
319
|
+
const fetchPromises = merged.map(async (cfg) => {
|
|
320
|
+
// Merge UTM params from the incoming request; explicit params override UTM values.
|
|
321
|
+
const paramsWithUtm = { ...(utmFromRequest || {}), ...(cfg.params || {}) };
|
|
322
|
+
const key = buildEndpointKey(cfg.endpointPath, paramsWithUtm);
|
|
323
|
+
if (seen.has(key))
|
|
324
|
+
return; // Deduplicate
|
|
325
|
+
seen.add(key);
|
|
326
|
+
const data = await fetchEndpointData(cfg.endpointPath, paramsWithUtm, cookieHeader);
|
|
327
|
+
if (data !== null) {
|
|
328
|
+
endpointData[key] = data;
|
|
329
|
+
}
|
|
330
|
+
});
|
|
331
|
+
await Promise.all(fetchPromises);
|
|
332
|
+
}
|
|
333
|
+
// Additional debug logging for SSR
|
|
334
|
+
if (isSSR && isDev) {
|
|
335
|
+
console.log(`[SSR] ${path}:`, {
|
|
336
|
+
endpointsRequested: merged.length,
|
|
337
|
+
endpointsFetched: Object.keys(endpointData).length,
|
|
338
|
+
hasCookies: !!cookieHeader,
|
|
339
|
+
queriesFound: queryCache ? Object.keys(queryCache).length : 0,
|
|
340
|
+
});
|
|
341
|
+
}
|
|
342
|
+
return returnResult(buildProps(queryCache || {}, endpointData));
|
|
343
|
+
}
|
|
344
|
+
catch (error) {
|
|
345
|
+
console.error(`Error extracting Plasmic queries for ${path}:`, error);
|
|
346
|
+
return returnResult(buildErrorProps());
|
|
347
|
+
}
|
|
348
|
+
};
|
|
349
|
+
// Return object with the appropriate property based on mode
|
|
350
|
+
return isSSR
|
|
351
|
+
? { getServerSideProps: handler }
|
|
352
|
+
: { getStaticProps: handler };
|
|
353
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"next.config.d.ts","sourceRoot":"","sources":["../src/next.config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAEvC,KAAK,aAAa,GAAG,UAAU,GAAG;IAChC,MAAM,CAAC,EAAE;QAAE,kBAAkB,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;CAC3C,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,aAc3B,CAAC;AAEF,eAAe,aAAa,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.cxfNextConfig = void 0;
|
|
4
|
+
exports.cxfNextConfig = {
|
|
5
|
+
eslint: {
|
|
6
|
+
ignoreDuringBuilds: true,
|
|
7
|
+
},
|
|
8
|
+
trailingSlash: false,
|
|
9
|
+
reactStrictMode: true,
|
|
10
|
+
async rewrites() {
|
|
11
|
+
return [
|
|
12
|
+
{
|
|
13
|
+
source: "/assets/:path*",
|
|
14
|
+
destination: "/api/assets/:path*",
|
|
15
|
+
},
|
|
16
|
+
];
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
exports.default = exports.cxfNextConfig;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assets.d.ts","sourceRoot":"","sources":["../../../src/pages/api/assets.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,MAAM,CAAC;AAI5D,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,cAAc,EAAE,GAAG,EAAE,eAAe,iBA0B/E;AAED,eAAe,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.assetsApiHandler = assetsApiHandler;
|
|
4
|
+
const cxf_auth_1 = require("../../lib/cxf-auth");
|
|
5
|
+
const api_route_helpers_1 = require("../../lib/api-route-helpers");
|
|
6
|
+
async function assetsApiHandler(req, res) {
|
|
7
|
+
if (req.method !== "GET") {
|
|
8
|
+
res.setHeader("Allow", "GET");
|
|
9
|
+
return res.status(405).json({ error: "Method not allowed" });
|
|
10
|
+
}
|
|
11
|
+
try {
|
|
12
|
+
const baseUrl = (0, cxf_auth_1.getCxfBaseUrl)();
|
|
13
|
+
const normalizedPath = (0, api_route_helpers_1.normalizePath)(req.query.path);
|
|
14
|
+
const targetUrl = `${baseUrl}/assets/${normalizedPath}${(0, api_route_helpers_1.buildQueryString)(req.query)}`;
|
|
15
|
+
const { response, newTokens } = await (0, cxf_auth_1.makeAuthenticatedRequest)(targetUrl, {
|
|
16
|
+
method: "GET",
|
|
17
|
+
cookieHeader: req.headers.cookie || null,
|
|
18
|
+
retryOnAuthError: false,
|
|
19
|
+
});
|
|
20
|
+
const setCookieHeaders = (0, cxf_auth_1.extractSetCookieHeaders)(response);
|
|
21
|
+
const tokens = (0, cxf_auth_1.extractTokensFromSetCookie)(setCookieHeaders);
|
|
22
|
+
const finalTokens = tokens.accessToken || tokens.refreshToken ? tokens : newTokens;
|
|
23
|
+
(0, api_route_helpers_1.setAuthCookies)(res, finalTokens);
|
|
24
|
+
return (0, api_route_helpers_1.sendResponse)(res, response);
|
|
25
|
+
}
|
|
26
|
+
catch (err) {
|
|
27
|
+
return (0, api_route_helpers_1.handleError)(res, err);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
exports.default = assetsApiHandler;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cxf.d.ts","sourceRoot":"","sources":["../../../src/pages/api/cxf.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,MAAM,CAAC;AAI5D,wBAAsB,aAAa,CAAC,GAAG,EAAE,cAAc,EAAE,GAAG,EAAE,eAAe,iBAmD5E;AAED,eAAe,aAAa,CAAC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.cxfApiHandler = cxfApiHandler;
|
|
4
|
+
const cxf_auth_1 = require("../../lib/cxf-auth");
|
|
5
|
+
const api_route_helpers_1 = require("../../lib/api-route-helpers");
|
|
6
|
+
async function cxfApiHandler(req, res) {
|
|
7
|
+
const allowedMethods = ["GET", "POST", "PATCH", "PUT", "DELETE"];
|
|
8
|
+
if (!allowedMethods.includes(req.method || "")) {
|
|
9
|
+
res.setHeader("Allow", allowedMethods.join(", "));
|
|
10
|
+
return res.status(405).json({ error: "Method not allowed" });
|
|
11
|
+
}
|
|
12
|
+
try {
|
|
13
|
+
const baseUrl = (0, cxf_auth_1.getCxfBaseUrl)();
|
|
14
|
+
const normalizedPath = (0, api_route_helpers_1.normalizePath)(req.query.path);
|
|
15
|
+
const apiKeyType = normalizedPath.startsWith("dev/v1/") ? "dev" :
|
|
16
|
+
normalizedPath.startsWith("user/v1/") ? "user" : "public";
|
|
17
|
+
const apiKey = (0, cxf_auth_1.getCxfApiKey)(apiKeyType);
|
|
18
|
+
if (!apiKey) {
|
|
19
|
+
const keyNames = { dev: "CXF_DEV_API_KEY", user: "CXF_USER_API_KEY", public: "CXF_API_KEY/API_KEY" };
|
|
20
|
+
return res.status(500).json({ error: `Missing ${keyNames[apiKeyType]} env var` });
|
|
21
|
+
}
|
|
22
|
+
const targetPath = normalizedPath.startsWith("v1/") ||
|
|
23
|
+
normalizedPath.startsWith("dev/v1/") ||
|
|
24
|
+
normalizedPath.startsWith("user/v1/")
|
|
25
|
+
? normalizedPath
|
|
26
|
+
: `v1/endpoints/${normalizedPath}`;
|
|
27
|
+
const targetUrl = `${baseUrl}/api/${targetPath}${(0, api_route_helpers_1.buildQueryString)(req.query)}`;
|
|
28
|
+
const body = req.method !== "GET" && req.method !== "HEAD" && req.body ? req.body : undefined;
|
|
29
|
+
const retryOnAuthError = !normalizedPath.match(/^(v1\/(login|register)|dev\/v1\/)/);
|
|
30
|
+
const { response, newTokens } = await (0, cxf_auth_1.makeAuthenticatedRequest)(targetUrl, {
|
|
31
|
+
method: req.method || "GET",
|
|
32
|
+
body,
|
|
33
|
+
apiKey,
|
|
34
|
+
userToken: null,
|
|
35
|
+
cookieHeader: req.headers.cookie || null,
|
|
36
|
+
retryOnAuthError,
|
|
37
|
+
});
|
|
38
|
+
const setCookieHeaders = (0, cxf_auth_1.extractSetCookieHeaders)(response);
|
|
39
|
+
const tokens = (0, cxf_auth_1.extractTokensFromSetCookie)(setCookieHeaders);
|
|
40
|
+
const finalTokens = tokens.accessToken || tokens.refreshToken ? tokens : newTokens;
|
|
41
|
+
(0, api_route_helpers_1.setAuthCookies)(res, finalTokens);
|
|
42
|
+
return (0, api_route_helpers_1.sendResponse)(res, response);
|
|
43
|
+
}
|
|
44
|
+
catch (err) {
|
|
45
|
+
return (0, api_route_helpers_1.handleError)(res, err);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
exports.default = cxfApiHandler;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../../src/pages/app.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAKzC,wBAAgB,MAAM,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,EAAE,QAAQ,2CA6BxD;AAED,eAAe,MAAM,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.CxfApp = CxfApp;
|
|
7
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
8
|
+
const react_web_1 = require("@plasmicapp/react-web");
|
|
9
|
+
const query_1 = require("@plasmicapp/react-web/lib/query");
|
|
10
|
+
const head_1 = __importDefault(require("next/head"));
|
|
11
|
+
const link_1 = __importDefault(require("next/link"));
|
|
12
|
+
function CxfApp({ Component, pageProps }) {
|
|
13
|
+
// Detect ISR pages using explicit markers
|
|
14
|
+
const serverPageProps = pageProps;
|
|
15
|
+
const isServerPage = Boolean(serverPageProps._prefetchEnabled ||
|
|
16
|
+
Component.isrEnabled ||
|
|
17
|
+
serverPageProps.queryCache ||
|
|
18
|
+
serverPageProps.endpointData);
|
|
19
|
+
// Fast path: minimal server-side rendering for ISR pages
|
|
20
|
+
// This bypasses heavy client-side initialization during build time
|
|
21
|
+
if (typeof window === 'undefined' && isServerPage) {
|
|
22
|
+
return ((0, jsx_runtime_1.jsx)(react_web_1.PlasmicRootProvider, { Head: head_1.default, Link: link_1.default, children: (0, jsx_runtime_1.jsx)(Component, { ...pageProps }) }));
|
|
23
|
+
}
|
|
24
|
+
// Regular path: full initialization for client-side and non-ISR pages
|
|
25
|
+
// This preserves all functionality for interactive pages
|
|
26
|
+
return ((0, jsx_runtime_1.jsx)(react_web_1.PlasmicRootProvider, { Head: head_1.default, Link: link_1.default, children: (0, jsx_runtime_1.jsx)(query_1.PlasmicQueryDataProvider, { suspense: true, children: (0, jsx_runtime_1.jsx)(Component, { ...pageProps }) }) }));
|
|
27
|
+
}
|
|
28
|
+
exports.default = CxfApp;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plasmic-host.d.ts","sourceRoot":"","sources":["../../src/pages/plasmic-host.tsx"],"names":[],"mappings":"AAUA,wBAAgB,WAAW,4CAE1B;AAED,eAAe,WAAW,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PlasmicHost = PlasmicHost;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const host_1 = require("@plasmicapp/host");
|
|
6
|
+
// You can register any code components that you want to use here; see
|
|
7
|
+
// https://docs.plasmic.app/learn/code-components-ref/
|
|
8
|
+
// And configure your Plasmic project to use the host url pointing at
|
|
9
|
+
// the /plasmic-host page of your nextjs app (for example,
|
|
10
|
+
// http://localhost:3000/plasmic-host). See
|
|
11
|
+
// https://docs.plasmic.app/learn/app-hosting/#set-a-plasmic-project-to-use-your-app-host
|
|
12
|
+
function PlasmicHost() {
|
|
13
|
+
return (0, jsx_runtime_1.jsx)(host_1.PlasmicCanvasHost, {});
|
|
14
|
+
}
|
|
15
|
+
exports.default = PlasmicHost;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../src/register.ts"],"names":[],"mappings":"AAGA,wBAAgB,sBAAsB,SAmFrC"}
|
package/dist/register.js
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerCodeComponents = registerCodeComponents;
|
|
4
|
+
const host_1 = require("@plasmicapp/host");
|
|
5
|
+
const ApiCall_1 = require("./components/ApiCall");
|
|
6
|
+
function registerCodeComponents() {
|
|
7
|
+
(0, host_1.registerComponent)(ApiCall_1.ApiCall, {
|
|
8
|
+
name: "ApiCall",
|
|
9
|
+
displayName: "API Call",
|
|
10
|
+
importName: "ApiCall",
|
|
11
|
+
importPath: "cxf-codegen/components/ApiCall",
|
|
12
|
+
section: "CXF",
|
|
13
|
+
description: "API caller for CXF. Auto-handles path prefixes and auth; provides data via $ctx.response.*. GET auto-fetches; other methods trigger via 'trigger'. If no children, no loading UI.",
|
|
14
|
+
providesData: true,
|
|
15
|
+
props: {
|
|
16
|
+
apiType: {
|
|
17
|
+
type: "choice",
|
|
18
|
+
displayName: "API",
|
|
19
|
+
options: ["endpoint", "contact", "dev", "user"],
|
|
20
|
+
defaultValue: "contact",
|
|
21
|
+
description: "Select which API to use. Path should exclude leading version segments.",
|
|
22
|
+
},
|
|
23
|
+
path: {
|
|
24
|
+
type: "string",
|
|
25
|
+
displayName: "Path",
|
|
26
|
+
description: "Short path. Example: 'me' or 'blog-posts'.",
|
|
27
|
+
defaultValue: "me",
|
|
28
|
+
},
|
|
29
|
+
method: {
|
|
30
|
+
type: "choice",
|
|
31
|
+
displayName: "HTTP Method",
|
|
32
|
+
options: ["GET", "POST", "PATCH", "PUT", "DELETE"],
|
|
33
|
+
defaultValue: "GET",
|
|
34
|
+
description: "GET auto-fetches on mount. POST/PATCH/PUT/DELETE: increment 'trigger' to call.",
|
|
35
|
+
},
|
|
36
|
+
params: {
|
|
37
|
+
type: "object",
|
|
38
|
+
displayName: "Query Params",
|
|
39
|
+
description: "Query parameters for GET requests.",
|
|
40
|
+
defaultValue: {},
|
|
41
|
+
},
|
|
42
|
+
body: {
|
|
43
|
+
type: "object",
|
|
44
|
+
displayName: "Request Body",
|
|
45
|
+
description: "Body for POST, PATCH, PUT, DELETE. Can bind form data.",
|
|
46
|
+
defaultValue: {},
|
|
47
|
+
},
|
|
48
|
+
autoFetch: {
|
|
49
|
+
type: "boolean",
|
|
50
|
+
displayName: "Auto Fetch",
|
|
51
|
+
description: "Automatically fetch on mount (default: true for GET, false for others).",
|
|
52
|
+
advanced: true,
|
|
53
|
+
},
|
|
54
|
+
trigger: {
|
|
55
|
+
type: "number",
|
|
56
|
+
displayName: "Trigger",
|
|
57
|
+
description: "Increment this number to trigger non-GET calls.",
|
|
58
|
+
defaultValue: 0,
|
|
59
|
+
advanced: false,
|
|
60
|
+
},
|
|
61
|
+
onSuccess: {
|
|
62
|
+
type: "eventHandler",
|
|
63
|
+
displayName: "On Success",
|
|
64
|
+
description: "Called when the API call succeeds.",
|
|
65
|
+
argTypes: [{ name: "data", type: "object" }],
|
|
66
|
+
},
|
|
67
|
+
onError: {
|
|
68
|
+
type: "eventHandler",
|
|
69
|
+
displayName: "On Error",
|
|
70
|
+
description: "Called when the API call fails.",
|
|
71
|
+
argTypes: [{ name: "error", type: "string" }],
|
|
72
|
+
},
|
|
73
|
+
loadingContent: {
|
|
74
|
+
type: "slot",
|
|
75
|
+
displayName: "Loading content",
|
|
76
|
+
defaultValue: { type: "text", value: "Loading…" },
|
|
77
|
+
},
|
|
78
|
+
children: {
|
|
79
|
+
type: "slot",
|
|
80
|
+
displayName: "Content",
|
|
81
|
+
description: "Content can access $ctx.response.* (data, error, loading, success, failed). If omitted, no loading UI is rendered.",
|
|
82
|
+
defaultValue: {
|
|
83
|
+
type: "text",
|
|
84
|
+
value: "Access data via $ctx.response.*",
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
// Auto-register when imported
|
|
91
|
+
registerCodeComponents();
|