@paroicms/site-generator-plugin 0.20.0 → 0.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/{gen-backend → backend}/dist/commands/generator-session.js +13 -4
  2. package/backend/dist/commands/validate-recaptcha-response.js +20 -0
  3. package/backend/dist/context.js +5 -0
  4. package/{gen-backend → backend}/dist/data-format.js +2 -1
  5. package/{gen-backend → backend}/dist/generator/fake-content-generator/generate-fake-content.js +1 -1
  6. package/{gen-backend/dist/plugin.js → backend/dist/index.js} +10 -5
  7. package/{gen-backend → backend}/prompts/predefined-fields.json +9 -2
  8. package/frontend/dist/frontend.mjs +122 -0
  9. package/package.json +20 -40
  10. package/gen-backend/dist/context.js +0 -8
  11. package/gen-backend/dist/generator/helpers/esm-module.helper.js +0 -6
  12. package/gen-front/dist/gen-front.mjs +0 -166
  13. /package/{gen-backend → backend}/ddl/site-generator.ddl.sql +0 -0
  14. /package/{gen-backend → backend}/dist/commands/execute-command.js +0 -0
  15. /package/{gen-backend → backend}/dist/db/db-init.js +0 -0
  16. /package/{gen-backend → backend}/dist/db/db-read.queries.js +0 -0
  17. /package/{gen-backend → backend}/dist/db/db-write.queries.js +0 -0
  18. /package/{gen-backend → backend}/dist/db/ddl-migration.js +0 -0
  19. /package/{gen-backend → backend}/dist/db/formatters.js +0 -0
  20. /package/{gen-backend → backend}/dist/generator/fake-content-generator/content-helpers.js +0 -0
  21. /package/{gen-backend → backend}/dist/generator/fake-content-generator/content-report.js +0 -0
  22. /package/{gen-backend → backend}/dist/generator/fake-content-generator/create-database-with-fake-content.js +0 -0
  23. /package/{gen-backend → backend}/dist/generator/fake-content-generator/create-node-contents.js +0 -0
  24. /package/{gen-backend → backend}/dist/generator/fake-content-generator/fake-content-types.js +0 -0
  25. /package/{gen-backend → backend}/dist/generator/fake-content-generator/fill-lnodes.js +0 -0
  26. /package/{gen-backend → backend}/dist/generator/fake-content-generator/fill-site-fields.js +0 -0
  27. /package/{gen-backend → backend}/dist/generator/fake-content-generator/fill-taxonomy-fields.js +0 -0
  28. /package/{gen-backend → backend}/dist/generator/fake-content-generator/invoke-generate-fake-content.js +0 -0
  29. /package/{gen-backend → backend}/dist/generator/helpers/js-utils.js +0 -0
  30. /package/{gen-backend → backend}/dist/generator/lib/calling-llm-anthropic.js +0 -0
  31. /package/{gen-backend → backend}/dist/generator/lib/calling-llm-mistral.js +0 -0
  32. /package/{gen-backend → backend}/dist/generator/lib/common-types.js +0 -0
  33. /package/{gen-backend → backend}/dist/generator/lib/create-prompt.js +0 -0
  34. /package/{gen-backend → backend}/dist/generator/lib/debug-utils.js +0 -0
  35. /package/{gen-backend → backend}/dist/generator/lib/images-lib.js +0 -0
  36. /package/{gen-backend → backend}/dist/generator/lib/llm-invoke-types.js +0 -0
  37. /package/{gen-backend → backend}/dist/generator/lib/llm-tokens.js +0 -0
  38. /package/{gen-backend → backend}/dist/generator/lib/llm-utils.js +0 -0
  39. /package/{gen-backend → backend}/dist/generator/lib/markdown-bulleted-list-parser.js +0 -0
  40. /package/{gen-backend → backend}/dist/generator/lib/parse-llm-response.js +0 -0
  41. /package/{gen-backend → backend}/dist/generator/lib/prompt-template.js +0 -0
  42. /package/{gen-backend → backend}/dist/generator/lib/session-utils.js +0 -0
  43. /package/{gen-backend → backend}/dist/generator/lib/tasks.js +0 -0
  44. /package/{gen-backend → backend}/dist/generator/lib/utils.js +0 -0
  45. /package/{gen-backend → backend}/dist/generator/llm-queries/invoke-message-guard.js +0 -0
  46. /package/{gen-backend → backend}/dist/generator/llm-queries/invoke-new-site-analysis.js +0 -0
  47. /package/{gen-backend → backend}/dist/generator/llm-queries/invoke-update-site-schema.js +0 -0
  48. /package/{gen-backend → backend}/dist/generator/site-generator/common-template-creator.js +0 -0
  49. /package/{gen-backend → backend}/dist/generator/site-generator/document-template-creator.js +0 -0
  50. /package/{gen-backend → backend}/dist/generator/site-generator/id-key-provider.js +0 -0
  51. /package/{gen-backend → backend}/dist/generator/site-generator/jt-site-schema-helpers.js +0 -0
  52. /package/{gen-backend → backend}/dist/generator/site-generator/site-generator.js +0 -0
  53. /package/{gen-backend → backend}/dist/generator/site-generator/template-creator-types.js +0 -0
  54. /package/{gen-backend → backend}/dist/generator/site-generator/template-helpers.js +0 -0
  55. /package/{gen-backend → backend}/dist/generator/site-generator/theme-creator.js +0 -0
  56. /package/{gen-backend → backend}/dist/generator/site-generator/theme-css.js +0 -0
  57. /package/{gen-backend → backend}/dist/generator/site-schema-generator/analysis-types.js +0 -0
  58. /package/{gen-backend → backend}/dist/generator/site-schema-generator/create-l10n.js +0 -0
  59. /package/{gen-backend → backend}/dist/generator/site-schema-generator/create-site-schema.js +0 -0
  60. /package/{gen-backend → backend}/dist/generator/site-schema-generator/default-pages.js +0 -0
  61. /package/{gen-backend → backend}/dist/lib/create-raw-context.js +0 -0
  62. /package/{gen-backend → backend}/dist/lib/internal-types.js +0 -0
  63. /package/{gen-backend → backend}/dist/lib/site-remover.js +0 -0
  64. /package/{gen-backend → backend}/images/im01.webp +0 -0
  65. /package/{gen-backend → backend}/images/im02.webp +0 -0
  66. /package/{gen-backend → backend}/images/im03.webp +0 -0
  67. /package/{gen-backend → backend}/images/im04.webp +0 -0
  68. /package/{gen-backend → backend}/images/im05.webp +0 -0
  69. /package/{gen-backend → backend}/images/im06.webp +0 -0
  70. /package/{gen-backend → backend}/images/im07.webp +0 -0
  71. /package/{gen-backend → backend}/images/im08.webp +0 -0
  72. /package/{gen-backend → backend}/images/im09.webp +0 -0
  73. /package/{gen-backend → backend}/images/im10.webp +0 -0
  74. /package/{gen-backend → backend}/images/im11.webp +0 -0
  75. /package/{gen-backend → backend}/images/im12.webp +0 -0
  76. /package/{gen-backend → backend}/prompts/0-context.md +0 -0
  77. /package/{gen-backend → backend}/prompts/generate-fake-content-multiple-documents.md +0 -0
  78. /package/{gen-backend → backend}/prompts/generate-fake-content-multiple-parts.md +0 -0
  79. /package/{gen-backend → backend}/prompts/generate-fake-content-single.md +0 -0
  80. /package/{gen-backend → backend}/prompts/initial-1-analysis.md +0 -0
  81. /package/{gen-backend → backend}/prompts/initial-2-fields.md +0 -0
  82. /package/{gen-backend → backend}/prompts/message-guard.md +0 -0
  83. /package/{gen-backend → backend}/prompts/update-site-schema-1-write-details.md +0 -0
  84. /package/{gen-backend → backend}/prompts/update-site-schema-2-execute.md +0 -0
  85. /package/{gen-front/dist/gen-front.css → frontend/dist/frontend.css} +0 -0
@@ -3,11 +3,16 @@ import { ApiError } from "@paroicms/public-server-lib";
3
3
  import { nanoid } from "nanoid";
4
4
  import { getInvalidSessionError } from "../db/db-read.queries.js";
5
5
  import { insertSession, updateSession } from "../db/db-write.queries.js";
6
+ import { validateRecaptchaResponse } from "./validate-recaptcha-response.js";
6
7
  const { sign, verify } = (await import("jsonwebtoken")).default;
7
8
  export async function newSessionCommand(ctx, command) {
8
- const { service } = ctx;
9
+ const { service, pluginConf } = ctx;
9
10
  const { recaptchaToken, language } = command;
10
- const isValid = await service.validateRecaptchaResponse(recaptchaToken);
11
+ const isValid = !pluginConf.googleRecaptchaSecretKey ||
12
+ (await validateRecaptchaResponse(service, {
13
+ gRecaptchaResponse: recaptchaToken,
14
+ secretKey: pluginConf.googleRecaptchaSecretKey,
15
+ }));
11
16
  if (!isValid)
12
17
  throw new ApiError("Invalid reCAPTCHA token", 400);
13
18
  const date = new Date();
@@ -22,9 +27,13 @@ export async function newSessionCommand(ctx, command) {
22
27
  * Renews a session token and extends its expiration time
23
28
  */
24
29
  export async function renewSessionCommand(ctx, command) {
25
- const { service } = ctx;
30
+ const { service, pluginConf } = ctx;
26
31
  const { recaptchaToken } = command;
27
- const isValid = await service.validateRecaptchaResponse(recaptchaToken);
32
+ const isValid = !pluginConf.googleRecaptchaSecretKey ||
33
+ (await validateRecaptchaResponse(service, {
34
+ gRecaptchaResponse: recaptchaToken,
35
+ secretKey: pluginConf.googleRecaptchaSecretKey,
36
+ }));
28
37
  if (!isValid)
29
38
  throw new ApiError("Invalid reCAPTCHA token", 400);
30
39
  let payload;
@@ -0,0 +1,20 @@
1
+ import { ApiError } from "@paroicms/public-server-lib";
2
+ export async function validateRecaptchaResponse(service, { gRecaptchaResponse, secretKey, }) {
3
+ if (!gRecaptchaResponse)
4
+ throw new ApiError("Missing gRecaptchaResponse", 400);
5
+ if (!secretKey) {
6
+ throw new Error("Invalid configuration, missing 'recaptchaPrivateKey'");
7
+ }
8
+ const url = `https://www.google.com/recaptcha/api/siteverify?secret=${secretKey}&response=${gRecaptchaResponse}`;
9
+ const response = await fetch(url, {
10
+ method: "post",
11
+ });
12
+ if (response.status < 200 || response.status >= 300) {
13
+ throw new Error("Failed to call the Google Recaptcha API");
14
+ }
15
+ const result = (await response.json());
16
+ if (result.hostname !== service.fqdn) {
17
+ throw new ApiError("Unauthorized", 401);
18
+ }
19
+ return result.success;
20
+ }
@@ -0,0 +1,5 @@
1
+ import { esmDirName, extractPackageNameAndVersionSync } from "@paroicms/script-lib";
2
+ import { dirname } from "node:path";
3
+ export const projectDir = dirname(esmDirName(import.meta.url));
4
+ export const packageDir = dirname(projectDir);
5
+ export const { version: pluginVersion } = extractPackageNameAndVersionSync(packageDir);
@@ -5,8 +5,9 @@ export const GeneratorPluginConfigurationAT = type({
5
5
  anthropicApiKey: "string",
6
6
  mistralApiKey: "string",
7
7
  packName: "string",
8
- "googleRecaptchaSiteKey?": "string|undefined",
9
8
  "debugDir?": "string|undefined",
9
+ "googleRecaptchaSiteKey?": "string|undefined",
10
+ "googleRecaptchaSecretKey?": "string|undefined",
10
11
  "+": "reject",
11
12
  }).pipe((data) => data);
12
13
  const BaseCommandAT = type({
@@ -134,7 +134,7 @@ function toFakeContentOutputTag(fieldNameOrType) {
134
134
  tagDescription: "Write a title here in plain text",
135
135
  };
136
136
  }
137
- if (key === "shortTitle") {
137
+ if (key === "buttonLabel") {
138
138
  return {
139
139
  tagName: camelToKebabCase(key),
140
140
  key,
@@ -3,7 +3,7 @@ import { messageOf } from "@paroicms/public-anywhere-lib";
3
3
  import { ApiError, escapeHtml, makeStylesheetLinkAsyncTag, } from "@paroicms/public-server-lib";
4
4
  import { join } from "node:path";
5
5
  import { executeCommand } from "./commands/execute-command.js";
6
- import { packageDir, pluginVersion, SLUG } from "./context.js";
6
+ import { packageDir, pluginVersion } from "./context.js";
7
7
  import { formatGeneratorCommand, GeneratorPluginConfigurationAT } from "./data-format.js";
8
8
  import { createOrOpenSiteGeneratorConnection } from "./db/db-init.js";
9
9
  import { initializeImageNames } from "./generator/lib/images-lib.js";
@@ -12,7 +12,6 @@ import { startSiteRemover } from "./lib/site-remover.js";
12
12
  await initializeImageNames();
13
13
  const plugin = {
14
14
  version: pluginVersion,
15
- slug: SLUG,
16
15
  async siteInit(service) {
17
16
  const { cn, logNextQuery } = await createOrOpenSiteGeneratorConnection({
18
17
  sqliteFile: join(service.registeredSite.dataDir, "site-generator.sqlite"),
@@ -20,6 +19,12 @@ const plugin = {
20
19
  logger: service.logger,
21
20
  });
22
21
  const pluginConf = GeneratorPluginConfigurationAT.assert(service.configuration);
22
+ if (!!pluginConf.googleRecaptchaSecretKey !== !!pluginConf.googleRecaptchaSiteKey) {
23
+ throw new Error("[Site Generator] Invalid Google reCAPTCHA configuration");
24
+ }
25
+ if (!pluginConf.googleRecaptchaSiteKey) {
26
+ service.logger.warn("[Site Generator] Google reCAPTCHA keys are not set. The site generator will not be protected.");
27
+ }
23
28
  let debugDir = pluginConf.debugDir;
24
29
  if (debugDir) {
25
30
  if (!(await pathExists(debugDir))) {
@@ -37,7 +42,7 @@ const plugin = {
37
42
  });
38
43
  startSiteRemover(rawContext);
39
44
  });
40
- service.setPublicAssetsDirectory(join(packageDir, "gen-front", "dist"));
45
+ service.setPublicAssetsDirectory(join(packageDir, "frontend", "dist"));
41
46
  service.registerLiquidTag("siteGeneratorApp", "injectHtml", (service) => {
42
47
  service.setRenderState("paSiteGeneratorApp", true);
43
48
  return `<div id="site-generator-app"></div>`;
@@ -46,8 +51,8 @@ const plugin = {
46
51
  if (!state.get("paSiteGeneratorApp"))
47
52
  return;
48
53
  return [
49
- makeStylesheetLinkAsyncTag(`${service.pluginAssetsUrl}/gen-front.css`),
50
- `<script type="module" src="${escapeHtml(`${service.pluginAssetsUrl}/gen-front.mjs`)}" class="js-script-${SLUG}" data-google-recaptcha-site-key="${escapeHtml(pluginConf.googleRecaptchaSiteKey)}" async></script>`,
54
+ makeStylesheetLinkAsyncTag(`${service.pluginAssetsUrl}/frontend.css`),
55
+ `<script type="module" src="${escapeHtml(`${service.pluginAssetsUrl}/frontend.mjs`)}" class="js-script-site-generator" data-google-recaptcha-site-key="${escapeHtml(pluginConf.googleRecaptchaSiteKey ?? "")}" async></script>`,
51
56
  ];
52
57
  });
53
58
  service.setPublicApiHandler(async (service, httpContext, relativePath) => {
@@ -4,6 +4,7 @@
4
4
  "localized": true,
5
5
  "dataType": "json",
6
6
  "renderAs": "html",
7
+ "normalizeTypography": true,
7
8
  "description": "Lead paragraph, or \"chapo\", of a post (HTML)"
8
9
  },
9
10
  {
@@ -11,6 +12,7 @@
11
12
  "localized": true,
12
13
  "dataType": "json",
13
14
  "renderAs": "html",
15
+ "normalizeTypography": true,
14
16
  "description": "HTML Content"
15
17
  },
16
18
  {
@@ -18,12 +20,14 @@
18
20
  "localized": true,
19
21
  "dataType": "json",
20
22
  "renderAs": "html",
23
+ "normalizeTypography": true,
21
24
  "description": "A short introduction (HTML)"
22
25
  },
23
26
  {
24
27
  "fieldName": "footerMention",
25
28
  "dataType": "json",
26
29
  "renderAs": "html",
30
+ "normalizeTypography": true,
27
31
  "localized": true,
28
32
  "description": "The footer mention is used to display a legal notice or a disclaimer (HTML). Usually included as a site field."
29
33
  },
@@ -37,6 +41,7 @@
37
41
  "fieldName": "slogan",
38
42
  "localized": true,
39
43
  "dataType": "string",
44
+ "normalizeTypography": true,
40
45
  "description": "A slogan is a memorable motto or phrase as a repetitive expression of an idea or purpose"
41
46
  },
42
47
  {
@@ -55,13 +60,15 @@
55
60
  "fieldName": "title",
56
61
  "localized": true,
57
62
  "dataType": "string",
63
+ "normalizeTypography": true,
58
64
  "description": "Store a title"
59
65
  },
60
66
  {
61
- "fieldName": "shortTitle",
67
+ "fieldName": "buttonLabel",
62
68
  "localized": true,
63
69
  "dataType": "string",
64
- "description": "A short title can be useful for buttons or menu items"
70
+ "normalizeTypography": true,
71
+ "description": "This short label can be used in the theme for buttons or menu items"
65
72
  },
66
73
  {
67
74
  "fieldName": "gallery",