@mints-cloud/cxf-codegen 1.0.2 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/README.md +40 -1
  2. package/dist/components/ApiCall.d.ts +5 -0
  3. package/dist/components/ApiCall.d.ts.map +1 -1
  4. package/dist/components/ApiCall.js +18 -3
  5. package/dist/components/JsonLdSchemas.d.ts +104 -0
  6. package/dist/components/JsonLdSchemas.d.ts.map +1 -0
  7. package/dist/components/JsonLdSchemas.js +380 -0
  8. package/dist/components/MetadataOverrides.d.ts +84 -0
  9. package/dist/components/MetadataOverrides.d.ts.map +1 -0
  10. package/dist/components/MetadataOverrides.js +270 -0
  11. package/dist/index.d.ts +3 -0
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +14 -1
  14. package/dist/lib/api-call-hooks.d.ts +2 -1
  15. package/dist/lib/api-call-hooks.d.ts.map +1 -1
  16. package/dist/lib/api-call-hooks.js +64 -11
  17. package/dist/lib/api-route-helpers.d.ts +1 -0
  18. package/dist/lib/api-route-helpers.d.ts.map +1 -1
  19. package/dist/lib/api-route-helpers.js +13 -0
  20. package/dist/lib/assets-query-params.d.ts +11 -0
  21. package/dist/lib/assets-query-params.d.ts.map +1 -0
  22. package/dist/lib/assets-query-params.js +130 -0
  23. package/dist/lib/cxf-auth.d.ts +7 -3
  24. package/dist/lib/cxf-auth.d.ts.map +1 -1
  25. package/dist/lib/cxf-auth.js +17 -6
  26. package/dist/lib/seo-utils.d.ts +22 -0
  27. package/dist/lib/seo-utils.d.ts.map +1 -0
  28. package/dist/lib/seo-utils.js +228 -0
  29. package/dist/lib/server-props.d.ts.map +1 -1
  30. package/dist/lib/server-props.js +46 -4
  31. package/dist/pages/api/assets.d.ts.map +1 -1
  32. package/dist/pages/api/assets.js +27 -1
  33. package/dist/pages/api/cxf.d.ts +5 -0
  34. package/dist/pages/api/cxf.d.ts.map +1 -1
  35. package/dist/pages/api/cxf.js +37 -4
  36. package/dist/pages/app.d.ts +4 -1
  37. package/dist/pages/app.d.ts.map +1 -1
  38. package/dist/pages/app.js +11 -6
  39. package/dist/register.d.ts.map +1 -1
  40. package/dist/register.js +193 -2
  41. package/package.json +13 -1
@@ -1,8 +1,24 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.config = void 0;
3
4
  exports.cxfApiHandler = cxfApiHandler;
4
5
  const cxf_auth_1 = require("../../lib/cxf-auth");
5
6
  const api_route_helpers_1 = require("../../lib/api-route-helpers");
7
+ // Disable Next.js body parser to support multipart/binary requests
8
+ exports.config = {
9
+ api: { bodyParser: false },
10
+ };
11
+ /**
12
+ * Reads the raw body from a Next.js request as a Buffer.
13
+ */
14
+ function getRawBody(req) {
15
+ return new Promise((resolve, reject) => {
16
+ const chunks = [];
17
+ req.on("data", (chunk) => chunks.push(chunk));
18
+ req.on("end", () => resolve(Buffer.concat(chunks)));
19
+ req.on("error", reject);
20
+ });
21
+ }
6
22
  async function cxfApiHandler(req, res) {
7
23
  const allowedMethods = ["GET", "POST", "PATCH", "PUT", "DELETE"];
8
24
  if (!allowedMethods.includes(req.method || "")) {
@@ -25,20 +41,37 @@ async function cxfApiHandler(req, res) {
25
41
  ? normalizedPath
26
42
  : `v1/endpoints/${normalizedPath}`;
27
43
  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
44
  const retryOnAuthError = !normalizedPath.match(/^(v1\/(login|register)|dev\/v1\/)/);
30
- const { response, newTokens } = await (0, cxf_auth_1.makeAuthenticatedRequest)(targetUrl, {
45
+ const isGet = req.method === "GET" || req.method === "HEAD";
46
+ const requestOptions = {
31
47
  method: req.method || "GET",
32
- body,
33
48
  apiKey,
34
49
  userToken: null,
35
50
  cookieHeader: req.headers.cookie || null,
36
51
  retryOnAuthError,
37
- });
52
+ };
53
+ if (!isGet) {
54
+ const rawBody = await getRawBody(req);
55
+ const contentType = req.headers["content-type"] || "";
56
+ const isMultipart = contentType.includes("multipart/form-data");
57
+ if (rawBody.length > 0) {
58
+ if (isMultipart) {
59
+ // Forward raw body preserving multipart boundaries
60
+ requestOptions.rawBody = rawBody;
61
+ requestOptions.contentType = contentType;
62
+ }
63
+ else {
64
+ // JSON/text body
65
+ requestOptions.body = rawBody.toString("utf-8");
66
+ }
67
+ }
68
+ }
69
+ const { response, newTokens } = await (0, cxf_auth_1.makeAuthenticatedRequest)(targetUrl, requestOptions);
38
70
  const setCookieHeaders = (0, cxf_auth_1.extractSetCookieHeaders)(response);
39
71
  const tokens = (0, cxf_auth_1.extractTokensFromSetCookie)(setCookieHeaders);
40
72
  const finalTokens = tokens.accessToken || tokens.refreshToken ? tokens : newTokens;
41
73
  (0, api_route_helpers_1.setAuthCookies)(res, finalTokens);
74
+ (0, api_route_helpers_1.forwardExtraCookies)(res, setCookieHeaders);
42
75
  return (0, api_route_helpers_1.sendResponse)(res, response);
43
76
  }
44
77
  catch (err) {
@@ -1,8 +1,11 @@
1
1
  import type { AppProps } from "next/app";
2
+ import * as React from "react";
3
+ import { type AssetQueryParams } from "../lib/assets-query-params";
2
4
  type CxfAppProps = AppProps & {
3
5
  tokenClass?: string;
4
6
  appRootId?: string;
7
+ assetsQueryParams?: AssetQueryParams;
5
8
  };
6
- export declare function CxfApp({ Component, pageProps, tokenClass, appRootId }: CxfAppProps): import("react/jsx-runtime").JSX.Element;
9
+ export declare function CxfApp({ Component, pageProps, tokenClass, appRootId, assetsQueryParams, }: CxfAppProps): string | number | bigint | boolean | Iterable<React.ReactNode> | Promise<React.AwaitedReactNode> | import("react/jsx-runtime").JSX.Element | null | undefined;
7
10
  export default CxfApp;
8
11
  //# sourceMappingURL=app.d.ts.map
@@ -1 +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;AAMzC,KAAK,WAAW,GAAG,QAAQ,GAAG;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAYF,wBAAgB,MAAM,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,SAAyB,EAAE,EAAE,WAAW,2CA+KlG;AAED,eAAe,MAAM,CAAC"}
1
+ {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../../src/pages/app.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAGzC,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EAAE,KAAK,gBAAgB,EAA2B,MAAM,4BAA4B,CAAC;AAE5F,KAAK,WAAW,GAAG,QAAQ,GAAG;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE,gBAAgB,CAAC;CACtC,CAAC;AAYF,wBAAgB,MAAM,CAAC,EACrB,SAAS,EACT,SAAS,EACT,UAAU,EACV,SAAyB,EACzB,iBAAiB,GAClB,EAAE,WAAW,iKAoLb;AAED,eAAe,MAAM,CAAC"}
package/dist/pages/app.js CHANGED
@@ -43,15 +43,17 @@ const query_1 = require("@plasmicapp/react-web/lib/query");
43
43
  const head_1 = __importDefault(require("next/head"));
44
44
  const link_1 = __importDefault(require("next/link"));
45
45
  const React = __importStar(require("react"));
46
+ const assets_query_params_1 = require("../lib/assets-query-params");
46
47
  function isNonEmptyObject(value) {
47
48
  return !!value && typeof value === "object" && !Array.isArray(value) && Object.keys(value).length > 0;
48
49
  }
49
- function CxfApp({ Component, pageProps, tokenClass, appRootId = "plasmic-app" }) {
50
+ function CxfApp({ Component, pageProps, tokenClass, appRootId = "plasmic-app", assetsQueryParams, }) {
50
51
  const storeRef = React.useRef({
51
52
  endpointData: {},
52
53
  queryCache: {},
53
54
  meta: {},
54
55
  });
56
+ (0, assets_query_params_1.useSyncAssetQueryParams)(assetsQueryParams);
55
57
  // Merge page props from hard loads / direct SSR navigation.
56
58
  const incoming = pageProps;
57
59
  if (isNonEmptyObject(incoming.endpointData)) {
@@ -173,15 +175,18 @@ function CxfApp({ Component, pageProps, tokenClass, appRootId = "plasmic-app" })
173
175
  Component.isrEnabled ||
174
176
  serverPageProps.queryCache ||
175
177
  serverPageProps.endpointData);
178
+ const wrapWithTokenClass = (node) => {
179
+ if (!tokenClass) {
180
+ return node;
181
+ }
182
+ return (0, jsx_runtime_1.jsx)("div", { className: tokenClass, children: node });
183
+ };
176
184
  // Fast path: minimal server-side rendering for ISR pages.
177
185
  if (typeof window === "undefined" && isServerPage) {
178
- 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, { ...safePageProps }) }));
186
+ return wrapWithTokenClass((0, jsx_runtime_1.jsx)(react_web_1.PlasmicRootProvider, { Head: head_1.default, Link: link_1.default, children: (0, jsx_runtime_1.jsx)(Component, { ...safePageProps }) }));
179
187
  }
180
188
  // Regular path: full initialization for client-side and non-ISR pages.
181
189
  const content = ((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, { ...safePageProps }) }) }));
182
- if (tokenClass) {
183
- return (0, jsx_runtime_1.jsx)("div", { className: tokenClass, children: content });
184
- }
185
- return content;
190
+ return wrapWithTokenClass(content);
186
191
  }
187
192
  exports.default = CxfApp;
@@ -1 +1 @@
1
- {"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../src/register.ts"],"names":[],"mappings":"AAGA,wBAAgB,sBAAsB,SAmFrC"}
1
+ {"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../src/register.ts"],"names":[],"mappings":"AAKA,wBAAgB,sBAAsB,SA6RrC"}
package/dist/register.js CHANGED
@@ -3,6 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.registerCodeComponents = registerCodeComponents;
4
4
  const host_1 = require("@plasmicapp/host");
5
5
  const ApiCall_1 = require("./components/ApiCall");
6
+ const MetadataOverrides_1 = require("./components/MetadataOverrides");
7
+ const JsonLdSchemas_1 = require("./components/JsonLdSchemas");
6
8
  function registerCodeComponents() {
7
9
  (0, host_1.registerComponent)(ApiCall_1.ApiCall, {
8
10
  name: "ApiCall",
@@ -17,14 +19,13 @@ function registerCodeComponents() {
17
19
  type: "choice",
18
20
  displayName: "API",
19
21
  options: ["endpoint", "contact", "dev", "user"],
20
- defaultValue: "contact",
22
+ defaultValue: "endpoint",
21
23
  description: "Select which API to use. Path should exclude leading version segments.",
22
24
  },
23
25
  path: {
24
26
  type: "string",
25
27
  displayName: "Path",
26
28
  description: "Short path. Example: 'me' or 'blog-posts'.",
27
- defaultValue: "me",
28
29
  },
29
30
  method: {
30
31
  type: "choice",
@@ -49,7 +50,15 @@ function registerCodeComponents() {
49
50
  type: "boolean",
50
51
  displayName: "Auto Fetch",
51
52
  description: "Automatically fetch on mount (default: true for GET, false for others).",
53
+ defaultValue: true,
54
+ },
55
+ canvasAutoFetchCooldownMs: {
56
+ type: "number",
57
+ displayName: "Canvas refresh interval (ms)",
58
+ description: "In Plasmic Studio only, identical GET requests are throttled to this interval (default: 300000). Runtime pages are unaffected.",
59
+ defaultValue: 300000,
52
60
  advanced: true,
61
+ hidden: (props) => props.method && props.method !== "GET",
53
62
  },
54
63
  trigger: {
55
64
  type: "number",
@@ -85,6 +94,188 @@ function registerCodeComponents() {
85
94
  },
86
95
  },
87
96
  },
97
+ actions: [
98
+ {
99
+ type: "button-action",
100
+ label: "Refetch now",
101
+ hidden: (props) => props.method && props.method !== "GET",
102
+ onClick: ({ componentProps, studioOps }) => {
103
+ const nextTrigger = Number(componentProps?.trigger ?? 0) + 1;
104
+ if (typeof studioOps?.updateProps === "function") {
105
+ studioOps.updateProps({ trigger: nextTrigger });
106
+ return;
107
+ }
108
+ if (typeof studioOps?.updateStates === "function") {
109
+ studioOps.updateStates({ trigger: nextTrigger });
110
+ }
111
+ },
112
+ },
113
+ ],
114
+ });
115
+ (0, host_1.registerComponent)(MetadataOverrides_1.MetadataOverrides, {
116
+ name: "MetadataOverrides",
117
+ displayName: "Metadata Overrides",
118
+ importName: "MetadataOverrides",
119
+ importPath: "@mints-cloud/cxf-codegen/components/MetadataOverrides",
120
+ section: "SEO",
121
+ description: "Merges Site Settings defaults with Page Meta overrides, writes head metadata, and emits Organization JSON-LD.",
122
+ props: {
123
+ siteSettings: {
124
+ type: "object",
125
+ displayName: "Site Settings",
126
+ description: "Site-level defaults. Asset paths can be relative and are converted to absolute URLs.",
127
+ defaultValue: {
128
+ identity_and_branding: {
129
+ site_name: "Site Name",
130
+ primary_color: "#FFFFFF",
131
+ },
132
+ domains_and_locales: {
133
+ primary_domain: "https://www.example.com",
134
+ additional_domains: [],
135
+ },
136
+ seo_defaults: {
137
+ seo_title_template: "%pageTitle% | %siteName%",
138
+ canonical_base: "https://www.example.com",
139
+ robots_indexing: "noindex",
140
+ robots_follow: "nofollow",
141
+ default_seo_title: "Site Name",
142
+ default_meta_description: "Default site description",
143
+ },
144
+ },
145
+ },
146
+ pageMeta: {
147
+ type: "object",
148
+ displayName: "Page Meta",
149
+ description: "Page-specific overrides for title, description, keywords, robots, canonical and social metadata.",
150
+ defaultValue: {
151
+ default: {
152
+ page_title: "Home",
153
+ permalink: "/",
154
+ },
155
+ seo_per_page: {
156
+ keywords: ["example keyword", "another keyword"],
157
+ },
158
+ social_and_sharing: {},
159
+ },
160
+ },
161
+ },
162
+ });
163
+ (0, host_1.registerComponent)(JsonLdSchemas_1.FaqJsonLd, {
164
+ name: "FaqJsonLd",
165
+ displayName: "FAQ JSON-LD",
166
+ importName: "FaqJsonLd",
167
+ importPath: "@mints-cloud/cxf-codegen/components/JsonLdSchemas",
168
+ section: "SEO",
169
+ description: "Outputs schema.org FAQPage JSON-LD from question/answer entries.",
170
+ props: {
171
+ items: {
172
+ type: "object",
173
+ displayName: "FAQ Items",
174
+ description: "Array with shape: [{ question, answer }]. answer supports HTML; raw inner quotes are auto-handled.",
175
+ defaultValue: [
176
+ {
177
+ question: "What documents do I need for a loan?",
178
+ answer: "A valid ID and your collateral item.",
179
+ },
180
+ ],
181
+ },
182
+ metadataSource: {
183
+ type: "object",
184
+ displayName: "Metadata Source",
185
+ description: "Object with { siteSettings, pageMeta } from MetadataOverrides. Provides URL and language.",
186
+ defaultValue: { siteSettings: {}, pageMeta: {} },
187
+ advanced: true,
188
+ },
189
+ schemaId: {
190
+ type: "string",
191
+ displayName: "Schema ID",
192
+ advanced: true,
193
+ },
194
+ scriptKey: {
195
+ type: "string",
196
+ displayName: "Script Key",
197
+ description: "Use when rendering multiple FAQ schemas on the same page.",
198
+ advanced: true,
199
+ },
200
+ },
201
+ });
202
+ (0, host_1.registerComponent)(JsonLdSchemas_1.BlogPostingJsonLd, {
203
+ name: "BlogPostingJsonLd",
204
+ displayName: "Blog Posting JSON-LD",
205
+ importName: "BlogPostingJsonLd",
206
+ importPath: "@mints-cloud/cxf-codegen/components/JsonLdSchemas",
207
+ section: "SEO",
208
+ description: "Outputs schema.org BlogPosting JSON-LD from CMS blog payload. Uses seo_per_page.keywords and references publisher from MetadataOverrides Organization JSON-LD.",
209
+ props: {
210
+ metadataSource: {
211
+ type: "object",
212
+ displayName: "Metadata Source",
213
+ description: "Object with { siteSettings, pageMeta } from MetadataOverrides. Provides URL and language.",
214
+ defaultValue: { siteSettings: {}, pageMeta: {} },
215
+ advanced: true,
216
+ },
217
+ blog: {
218
+ type: "object",
219
+ displayName: "Blog",
220
+ description: "Supports CMS shape with version.default/page_meta/seo_per_page/social_and_sharing.",
221
+ defaultValue: {
222
+ id: "blog-id",
223
+ version: {
224
+ created_at: "2026-02-15T10:00:00Z",
225
+ updated_at: "2026-02-15T10:00:00Z",
226
+ title: "Article title",
227
+ slug: "article-slug",
228
+ seo_per_page: {
229
+ page_meta_title: "Article SEO title",
230
+ page_meta_description: "Article SEO description",
231
+ keywords: ["pawn loans", "finance", "tips"],
232
+ },
233
+ default: {
234
+ cover_image: {
235
+ public_path: "/assets/cover-image",
236
+ },
237
+ blurb: "<p>Article summary</p>",
238
+ body: "<p>Article body</p>",
239
+ },
240
+ },
241
+ },
242
+ },
243
+ author: {
244
+ type: "object",
245
+ displayName: "Author",
246
+ description: "Primary author (name/url/type) and optional authors array [{ name, url, type }].",
247
+ },
248
+ scriptKey: {
249
+ type: "string",
250
+ displayName: "Script Key",
251
+ advanced: true,
252
+ },
253
+ },
254
+ });
255
+ (0, host_1.registerComponent)(JsonLdSchemas_1.CustomJsonLd, {
256
+ name: "CustomJsonLd",
257
+ displayName: "Custom JSON-LD",
258
+ importName: "CustomJsonLd",
259
+ importPath: "@mints-cloud/cxf-codegen/components/JsonLdSchemas",
260
+ section: "SEO",
261
+ description: "Outputs any custom JSON-LD payload when you need a schema type not covered by presets.",
262
+ props: {
263
+ schema: {
264
+ type: "object",
265
+ displayName: "Schema Object",
266
+ defaultValue: {
267
+ "@context": "https://schema.org",
268
+ "@type": "WebSite",
269
+ name: "Site Name",
270
+ url: "/",
271
+ },
272
+ },
273
+ scriptKey: {
274
+ type: "string",
275
+ displayName: "Script Key",
276
+ advanced: true,
277
+ },
278
+ },
88
279
  });
89
280
  }
90
281
  // Auto-register when imported
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mints-cloud/cxf-codegen",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "description": "Plasmic CXF codegen library for Next.js applications",
5
5
  "author": "Ruben Gomez",
6
6
  "license": "MIT",
@@ -31,6 +31,14 @@
31
31
  "types": "./dist/components/ApiCall.d.ts",
32
32
  "default": "./dist/components/ApiCall.js"
33
33
  },
34
+ "./components/MetadataOverrides": {
35
+ "types": "./dist/components/MetadataOverrides.d.ts",
36
+ "default": "./dist/components/MetadataOverrides.js"
37
+ },
38
+ "./components/JsonLdSchemas": {
39
+ "types": "./dist/components/JsonLdSchemas.d.ts",
40
+ "default": "./dist/components/JsonLdSchemas.js"
41
+ },
34
42
  "./lib/api-call-hooks": {
35
43
  "types": "./dist/lib/api-call-hooks.d.ts",
36
44
  "default": "./dist/lib/api-call-hooks.js"
@@ -39,6 +47,10 @@
39
47
  "types": "./dist/lib/api-route-helpers.d.ts",
40
48
  "default": "./dist/lib/api-route-helpers.js"
41
49
  },
50
+ "./lib/assets-query-params": {
51
+ "types": "./dist/lib/assets-query-params.d.ts",
52
+ "default": "./dist/lib/assets-query-params.js"
53
+ },
42
54
  "./lib/cxf-auth": {
43
55
  "types": "./dist/lib/cxf-auth.d.ts",
44
56
  "default": "./dist/lib/cxf-auth.js"