@zeropress/build-pages 0.6.1 → 0.6.3

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/action.js CHANGED
@@ -52317,7 +52317,9 @@ function validateSite(site, path4, errors) {
52317
52317
  "media_base_url",
52318
52318
  "media_delivery_mode",
52319
52319
  "favicon",
52320
+ "logo",
52320
52321
  "expose_generator",
52322
+ "search",
52321
52323
  "locale",
52322
52324
  "posts_per_page",
52323
52325
  "datetime_display",
@@ -52345,9 +52347,15 @@ function validateSite(site, path4, errors) {
52345
52347
  if (site.favicon !== void 0) {
52346
52348
  validateSiteFavicon(site.favicon, `${path4}.favicon`, errors);
52347
52349
  }
52350
+ if (site.logo !== void 0) {
52351
+ validateSiteLogo(site.logo, `${path4}.logo`, errors);
52352
+ }
52348
52353
  if (site.expose_generator !== void 0) {
52349
52354
  validateBoolean(site.expose_generator, `${path4}.expose_generator`, "INVALID_SITE_EXPOSE_GENERATOR", errors);
52350
52355
  }
52356
+ if (site.search !== void 0) {
52357
+ validateBoolean(site.search, `${path4}.search`, "INVALID_SITE_SEARCH", errors);
52358
+ }
52351
52359
  validateNonEmptyString(site.locale, `${path4}.locale`, "INVALID_SITE_LOCALE", errors);
52352
52360
  validateInteger(site.posts_per_page, `${path4}.posts_per_page`, "INVALID_SITE_POSTS_PER_PAGE", errors, { minimum: 1 });
52353
52361
  validateEnum(site.datetime_display, `${path4}.datetime_display`, "INVALID_SITE_DATETIME_DISPLAY", errors, PREVIEW_DATETIME_DISPLAY_MODES);
@@ -52621,6 +52629,16 @@ function validateSiteFavicon(favicon, path4, errors) {
52621
52629
  }
52622
52630
  }
52623
52631
  }
52632
+ function validateSiteLogo(logo, path4, errors) {
52633
+ validateClosedObject(logo, path4, errors, ["src", "alt"]);
52634
+ if (!isObject(logo)) {
52635
+ return;
52636
+ }
52637
+ validateUrlLike(logo.src, `${path4}.src`, "INVALID_SITE_LOGO_URL", errors);
52638
+ if (logo.alt !== void 0) {
52639
+ validateString(logo.alt, `${path4}.alt`, "INVALID_SITE_LOGO_ALT", errors);
52640
+ }
52641
+ }
52624
52642
  function validatePreviewMedia(media, path4, errors) {
52625
52643
  validateClosedObject(media, path4, errors, ["src", "width", "height", "alt"]);
52626
52644
  if (!isObject(media)) {
@@ -53010,11 +53028,14 @@ function isOptionalKey(path4, key) {
53010
53028
  return key === "head_end" || key === "body_end";
53011
53029
  }
53012
53030
  if (path4 === "site") {
53013
- return key === "media_delivery_mode" || key === "favicon" || key === "expose_generator" || key === "indexing" || key === "permalinks" || key === "front_page" || key === "post_index" || key === "footer" || key === "meta";
53031
+ return key === "media_delivery_mode" || key === "favicon" || key === "logo" || key === "expose_generator" || key === "search" || key === "indexing" || key === "permalinks" || key === "front_page" || key === "post_index" || key === "footer" || key === "meta";
53014
53032
  }
53015
53033
  if (path4 === "site.favicon") {
53016
53034
  return key === "icon" || key === "svg" || key === "png" || key === "apple_touch_icon";
53017
53035
  }
53036
+ if (path4 === "site.logo") {
53037
+ return key === "alt";
53038
+ }
53018
53039
  if (path4 === "site.footer") {
53019
53040
  return key === "copyright_text" || key === "attribution";
53020
53041
  }
@@ -53272,7 +53293,7 @@ var MENU_SLOT_ID_MAX_LENGTH = 32;
53272
53293
  var MENU_SLOT_COUNT_MAX = 12;
53273
53294
  var MENU_SLOT_TITLE_MAX_LENGTH = 80;
53274
53295
  var MENU_SLOT_DESCRIPTION_MAX_LENGTH = 160;
53275
- var SUPPORTED_THEME_FEATURES = /* @__PURE__ */ new Set(["comments", "newsletter", "post_index"]);
53296
+ var SUPPORTED_THEME_FEATURES = /* @__PURE__ */ new Set(["comments", "newsletter", "post_index", "search"]);
53276
53297
  var THEME_MANIFEST_KEYS = /* @__PURE__ */ new Set([
53277
53298
  "$schema",
53278
53299
  "name",
@@ -54587,6 +54608,7 @@ function escapeRegex(str) {
54587
54608
  var utils_exports = {};
54588
54609
  __export(utils_exports, {
54589
54610
  arrayReplaceAt: () => arrayReplaceAt,
54611
+ asciiTrim: () => asciiTrim,
54590
54612
  assign: () => assign,
54591
54613
  escapeHtml: () => escapeHtml,
54592
54614
  escapeRE: () => escapeRE,
@@ -54594,6 +54616,7 @@ __export(utils_exports, {
54594
54616
  has: () => has,
54595
54617
  isMdAsciiPunct: () => isMdAsciiPunct,
54596
54618
  isPunctChar: () => isPunctChar,
54619
+ isPunctCharCode: () => isPunctCharCode,
54597
54620
  isSpace: () => isSpace,
54598
54621
  isString: () => isString,
54599
54622
  isValidEntityCode: () => isValidEntityCode,
@@ -55421,6 +55444,9 @@ var xmlDecoder = getDecoder(decode_data_xml_default);
55421
55444
  function decodeHTML(str, mode = DecodingMode.Legacy) {
55422
55445
  return htmlDecoder(str, mode);
55423
55446
  }
55447
+ function decodeHTMLStrict(str) {
55448
+ return htmlDecoder(str, DecodingMode.Strict);
55449
+ }
55424
55450
 
55425
55451
  // node_modules/entities/lib/esm/generated/encode-html.js
55426
55452
  function restoreDiff(arr) {
@@ -55646,6 +55672,9 @@ function isWhiteSpace(code2) {
55646
55672
  function isPunctChar(ch) {
55647
55673
  return regex_default4.test(ch) || regex_default5.test(ch);
55648
55674
  }
55675
+ function isPunctCharCode(code2) {
55676
+ return isPunctChar(fromCodePoint2(code2));
55677
+ }
55649
55678
  function isMdAsciiPunct(ch) {
55650
55679
  switch (ch) {
55651
55680
  case 33:
@@ -55692,6 +55721,24 @@ function normalizeReference(str) {
55692
55721
  }
55693
55722
  return str.toLowerCase().toUpperCase();
55694
55723
  }
55724
+ function isAsciiTrimmable(c) {
55725
+ return c === 32 || c === 9 || c === 10 || c === 13;
55726
+ }
55727
+ function asciiTrim(str) {
55728
+ let start = 0;
55729
+ for (; start < str.length; start++) {
55730
+ if (!isAsciiTrimmable(str.charCodeAt(start))) {
55731
+ break;
55732
+ }
55733
+ }
55734
+ let end = str.length - 1;
55735
+ for (; end >= start; end--) {
55736
+ if (!isAsciiTrimmable(str.charCodeAt(end))) {
55737
+ break;
55738
+ }
55739
+ }
55740
+ return str.slice(start, end + 1);
55741
+ }
55695
55742
  var lib = { mdurl: mdurl_exports, ucmicro: uc_exports };
55696
55743
 
55697
55744
  // node_modules/markdown-it/lib/helpers/index.mjs
@@ -56444,12 +56491,27 @@ function replace(state) {
56444
56491
  var QUOTE_TEST_RE = /['"]/;
56445
56492
  var QUOTE_RE = /['"]/g;
56446
56493
  var APOSTROPHE = "\u2019";
56447
- function replaceAt(str, index, ch) {
56448
- return str.slice(0, index) + ch + str.slice(index + 1);
56494
+ function addReplacement(replacements, tokenIdx, pos, ch) {
56495
+ if (!replacements[tokenIdx]) {
56496
+ replacements[tokenIdx] = [];
56497
+ }
56498
+ replacements[tokenIdx].push({ pos, ch });
56499
+ }
56500
+ function applyReplacements(str, replacements) {
56501
+ let result = "";
56502
+ let lastPos = 0;
56503
+ replacements.sort((a, b) => a.pos - b.pos);
56504
+ for (let i = 0; i < replacements.length; i++) {
56505
+ const replacement = replacements[i];
56506
+ result += str.slice(lastPos, replacement.pos) + replacement.ch;
56507
+ lastPos = replacement.pos + 1;
56508
+ }
56509
+ return result + str.slice(lastPos);
56449
56510
  }
56450
56511
  function process_inlines(tokens, state) {
56451
56512
  let j;
56452
56513
  const stack = [];
56514
+ const replacements = {};
56453
56515
  for (let i = 0; i < tokens.length; i++) {
56454
56516
  const token = tokens[i];
56455
56517
  const thisLevel = tokens[i].level;
@@ -56462,9 +56524,9 @@ function process_inlines(tokens, state) {
56462
56524
  if (token.type !== "text") {
56463
56525
  continue;
56464
56526
  }
56465
- let text2 = token.content;
56527
+ const text2 = token.content;
56466
56528
  let pos = 0;
56467
- let max = text2.length;
56529
+ const max = text2.length;
56468
56530
  OUTER:
56469
56531
  while (pos < max) {
56470
56532
  QUOTE_RE.lastIndex = pos;
@@ -56498,8 +56560,8 @@ function process_inlines(tokens, state) {
56498
56560
  break;
56499
56561
  }
56500
56562
  }
56501
- const isLastPunctChar = isMdAsciiPunct(lastChar) || isPunctChar(String.fromCharCode(lastChar));
56502
- const isNextPunctChar = isMdAsciiPunct(nextChar) || isPunctChar(String.fromCharCode(nextChar));
56563
+ const isLastPunctChar = isMdAsciiPunct(lastChar) || isPunctCharCode(lastChar);
56564
+ const isNextPunctChar = isMdAsciiPunct(nextChar) || isPunctCharCode(nextChar);
56503
56565
  const isLastWhiteSpace = isWhiteSpace(lastChar);
56504
56566
  const isNextWhiteSpace = isWhiteSpace(nextChar);
56505
56567
  if (isNextWhiteSpace) {
@@ -56527,7 +56589,7 @@ function process_inlines(tokens, state) {
56527
56589
  }
56528
56590
  if (!canOpen && !canClose) {
56529
56591
  if (isSingle) {
56530
- token.content = replaceAt(token.content, t.index, APOSTROPHE);
56592
+ addReplacement(replacements, i, t.index, APOSTROPHE);
56531
56593
  }
56532
56594
  continue;
56533
56595
  }
@@ -56548,18 +56610,8 @@ function process_inlines(tokens, state) {
56548
56610
  openQuote = state.md.options.quotes[0];
56549
56611
  closeQuote = state.md.options.quotes[1];
56550
56612
  }
56551
- token.content = replaceAt(token.content, t.index, closeQuote);
56552
- tokens[item.token].content = replaceAt(
56553
- tokens[item.token].content,
56554
- item.pos,
56555
- openQuote
56556
- );
56557
- pos += closeQuote.length - 1;
56558
- if (item.token === i) {
56559
- pos += openQuote.length - 1;
56560
- }
56561
- text2 = token.content;
56562
- max = text2.length;
56613
+ addReplacement(replacements, i, t.index, closeQuote);
56614
+ addReplacement(replacements, item.token, item.pos, openQuote);
56563
56615
  stack.length = j;
56564
56616
  continue OUTER;
56565
56617
  }
@@ -56573,10 +56625,13 @@ function process_inlines(tokens, state) {
56573
56625
  level: thisLevel
56574
56626
  });
56575
56627
  } else if (canClose && isSingle) {
56576
- token.content = replaceAt(token.content, t.index, APOSTROPHE);
56628
+ addReplacement(replacements, i, t.index, APOSTROPHE);
56577
56629
  }
56578
56630
  }
56579
56631
  }
56632
+ Object.keys(replacements).forEach(function(tokenIdx) {
56633
+ tokens[tokenIdx].content = applyReplacements(tokens[tokenIdx].content, replacements[tokenIdx]);
56634
+ });
56580
56635
  }
56581
56636
  function smartquotes(state) {
56582
56637
  if (!state.md.options.typographer) {
@@ -57765,10 +57820,13 @@ function html_block(state, startLine, endLine, silent) {
57765
57820
  return HTML_SEQUENCES[i][2];
57766
57821
  }
57767
57822
  let nextLine = startLine + 1;
57823
+ const endsOnBlankLine = HTML_SEQUENCES[i][1].test("");
57768
57824
  if (!HTML_SEQUENCES[i][1].test(lineText)) {
57769
57825
  for (; nextLine < endLine; nextLine++) {
57770
57826
  if (state.sCount[nextLine] < state.blkIndent) {
57771
- break;
57827
+ if (endsOnBlankLine || !state.isEmpty(nextLine)) {
57828
+ break;
57829
+ }
57772
57830
  }
57773
57831
  pos = state.bMarks[nextLine] + state.tShift[nextLine];
57774
57832
  max = state.eMarks[nextLine];
@@ -57821,7 +57879,7 @@ function heading(state, startLine, endLine, silent) {
57821
57879
  token_o.markup = "########".slice(0, level);
57822
57880
  token_o.map = [startLine, state.line];
57823
57881
  const token_i = state.push("inline", "", 0);
57824
- token_i.content = state.src.slice(pos, max).trim();
57882
+ token_i.content = asciiTrim(state.src.slice(pos, max));
57825
57883
  token_i.map = [startLine, state.line];
57826
57884
  token_i.children = [];
57827
57885
  const token_c = state.push("heading_close", "h" + String(level), -1);
@@ -57874,9 +57932,10 @@ function lheading(state, startLine, endLine) {
57874
57932
  }
57875
57933
  }
57876
57934
  if (!level) {
57935
+ state.parentType = oldParentType;
57877
57936
  return false;
57878
57937
  }
57879
- const content = state.getLines(startLine, nextLine, state.blkIndent, false).trim();
57938
+ const content = asciiTrim(state.getLines(startLine, nextLine, state.blkIndent, false));
57880
57939
  state.line = nextLine + 1;
57881
57940
  const token_o = state.push("heading_open", "h" + String(level), 1);
57882
57941
  token_o.markup = String.fromCharCode(marker);
@@ -57915,7 +57974,7 @@ function paragraph(state, startLine, endLine) {
57915
57974
  break;
57916
57975
  }
57917
57976
  }
57918
- const content = state.getLines(startLine, nextLine, state.blkIndent, false).trim();
57977
+ const content = asciiTrim(state.getLines(startLine, nextLine, state.blkIndent, false));
57919
57978
  state.line = nextLine;
57920
57979
  const token_o = state.push("paragraph_open", "p", 1);
57921
57980
  token_o.map = [startLine, state.line];
@@ -58054,15 +58113,37 @@ StateInline.prototype.push = function(type, tag, nesting) {
58054
58113
  StateInline.prototype.scanDelims = function(start, canSplitWord) {
58055
58114
  const max = this.posMax;
58056
58115
  const marker = this.src.charCodeAt(start);
58057
- const lastChar = start > 0 ? this.src.charCodeAt(start - 1) : 32;
58116
+ let lastChar;
58117
+ if (start === 0) {
58118
+ lastChar = 32;
58119
+ } else if (start === 1) {
58120
+ lastChar = this.src.charCodeAt(0);
58121
+ if ((lastChar & 63488) === 55296) {
58122
+ lastChar = 65533;
58123
+ }
58124
+ } else {
58125
+ lastChar = this.src.charCodeAt(start - 1);
58126
+ if ((lastChar & 64512) === 56320) {
58127
+ const highSurr = this.src.charCodeAt(start - 2);
58128
+ lastChar = (highSurr & 64512) === 55296 ? 65536 + (highSurr - 55296 << 10) + (lastChar - 56320) : 65533;
58129
+ } else if ((lastChar & 64512) === 55296) {
58130
+ lastChar = 65533;
58131
+ }
58132
+ }
58058
58133
  let pos = start;
58059
58134
  while (pos < max && this.src.charCodeAt(pos) === marker) {
58060
58135
  pos++;
58061
58136
  }
58062
58137
  const count = pos - start;
58063
- const nextChar = pos < max ? this.src.charCodeAt(pos) : 32;
58064
- const isLastPunctChar = isMdAsciiPunct(lastChar) || isPunctChar(String.fromCharCode(lastChar));
58065
- const isNextPunctChar = isMdAsciiPunct(nextChar) || isPunctChar(String.fromCharCode(nextChar));
58138
+ let nextChar = pos < max ? this.src.charCodeAt(pos) : 32;
58139
+ if ((nextChar & 64512) === 55296) {
58140
+ const lowSurr = this.src.charCodeAt(pos + 1);
58141
+ nextChar = (lowSurr & 64512) === 56320 ? 65536 + (nextChar - 55296 << 10) + (lowSurr - 56320) : 65533;
58142
+ } else if ((nextChar & 64512) === 56320) {
58143
+ nextChar = 65533;
58144
+ }
58145
+ const isLastPunctChar = isMdAsciiPunct(lastChar) || isPunctCharCode(lastChar);
58146
+ const isNextPunctChar = isMdAsciiPunct(nextChar) || isPunctCharCode(nextChar);
58066
58147
  const isLastWhiteSpace = isWhiteSpace(lastChar);
58067
58148
  const isNextWhiteSpace = isWhiteSpace(nextChar);
58068
58149
  const left_flanking = !isNextWhiteSpace && (!isNextPunctChar || isLastWhiteSpace || isLastPunctChar);
@@ -58815,7 +58896,7 @@ function entity(state, silent) {
58815
58896
  } else {
58816
58897
  const match2 = state.src.slice(pos).match(NAMED_RE);
58817
58898
  if (match2) {
58818
- const decoded = decodeHTML(match2[0]);
58899
+ const decoded = decodeHTMLStrict(match2[0]);
58819
58900
  if (decoded !== match2[0]) {
58820
58901
  if (!silent) {
58821
58902
  const token = state.push("text_special", "", 0);
@@ -59168,10 +59249,6 @@ var defaultSchemas = {
59168
59249
  };
59169
59250
  var tlds_2ch_src_re = "a[cdefgilmnoqrstuwxz]|b[abdefghijmnorstvwyz]|c[acdfghiklmnoruvwxyz]|d[ejkmoz]|e[cegrstu]|f[ijkmor]|g[abdefghilmnpqrstuwy]|h[kmnrtu]|i[delmnoqrst]|j[emop]|k[eghimnprwyz]|l[abcikrstuvy]|m[acdeghklmnopqrstuvwxyz]|n[acefgilopruz]|om|p[aefghklmnrstwy]|qa|r[eosuw]|s[abcdeghijklmnortuvxyz]|t[cdfghjklmnortvwz]|u[agksyz]|v[aceginu]|w[fs]|y[et]|z[amw]";
59170
59251
  var tlds_default = "biz|com|edu|gov|net|org|pro|web|xxx|aero|asia|coop|info|museum|name|shop|\u0440\u0444".split("|");
59171
- function resetScanCache(self) {
59172
- self.__index__ = -1;
59173
- self.__text_cache__ = "";
59174
- }
59175
59252
  function createValidator(re) {
59176
59253
  return function(text2, pos) {
59177
59254
  const tail = text2.slice(pos);
@@ -59199,8 +59276,11 @@ function compile(self) {
59199
59276
  return tpl.replace("%TLDS%", re.src_tlds);
59200
59277
  }
59201
59278
  re.email_fuzzy = RegExp(untpl(re.tpl_email_fuzzy), "i");
59279
+ re.email_fuzzy_global = RegExp(untpl(re.tpl_email_fuzzy), "ig");
59202
59280
  re.link_fuzzy = RegExp(untpl(re.tpl_link_fuzzy), "i");
59281
+ re.link_fuzzy_global = RegExp(untpl(re.tpl_link_fuzzy), "ig");
59203
59282
  re.link_no_ip_fuzzy = RegExp(untpl(re.tpl_link_no_ip_fuzzy), "i");
59283
+ re.link_no_ip_fuzzy_global = RegExp(untpl(re.tpl_link_no_ip_fuzzy), "ig");
59204
59284
  re.host_fuzzy_test = RegExp(untpl(re.tpl_host_fuzzy_test), "i");
59205
59285
  const aliases = [];
59206
59286
  self.__compiled__ = {};
@@ -59255,23 +59335,15 @@ function compile(self) {
59255
59335
  "(" + self.re.schema_test.source + ")|(" + self.re.host_fuzzy_test.source + ")|@",
59256
59336
  "i"
59257
59337
  );
59258
- resetScanCache(self);
59259
- }
59260
- function Match(self, shift) {
59261
- const start = self.__index__;
59262
- const end = self.__last_index__;
59263
- const text2 = self.__text_cache__.slice(start, end);
59264
- this.schema = self.__schema__.toLowerCase();
59265
- this.index = start + shift;
59266
- this.lastIndex = end + shift;
59267
- this.raw = text2;
59268
- this.text = text2;
59269
- this.url = text2;
59270
- }
59271
- function createMatch(self, shift) {
59272
- const match2 = new Match(self, shift);
59273
- self.__compiled__[match2.schema].normalize(match2, self);
59274
- return match2;
59338
+ }
59339
+ function Match(text2, schema, index, lastIndex) {
59340
+ const raw = text2.slice(index, lastIndex);
59341
+ this.schema = schema.toLowerCase();
59342
+ this.index = index;
59343
+ this.lastIndex = lastIndex;
59344
+ this.raw = raw;
59345
+ this.text = raw;
59346
+ this.url = raw;
59275
59347
  }
59276
59348
  function LinkifyIt(schemas, options2) {
59277
59349
  if (!(this instanceof LinkifyIt)) {
@@ -59284,10 +59356,6 @@ function LinkifyIt(schemas, options2) {
59284
59356
  }
59285
59357
  }
59286
59358
  this.__opts__ = assign2({}, defaultOptions, options2);
59287
- this.__index__ = -1;
59288
- this.__last_index__ = -1;
59289
- this.__schema__ = "";
59290
- this.__text_cache__ = "";
59291
59359
  this.__schemas__ = assign2({}, defaultSchemas, schemas);
59292
59360
  this.__compiled__ = {};
59293
59361
  this.__tlds__ = tlds_default;
@@ -59305,55 +59373,34 @@ LinkifyIt.prototype.set = function set(options2) {
59305
59373
  return this;
59306
59374
  };
59307
59375
  LinkifyIt.prototype.test = function test(text2) {
59308
- this.__text_cache__ = text2;
59309
- this.__index__ = -1;
59310
59376
  if (!text2.length) {
59311
59377
  return false;
59312
59378
  }
59313
- let m, ml, me, len, shift, next, re, tld_pos, at_pos;
59379
+ let m, re;
59314
59380
  if (this.re.schema_test.test(text2)) {
59315
59381
  re = this.re.schema_search;
59316
59382
  re.lastIndex = 0;
59317
59383
  while ((m = re.exec(text2)) !== null) {
59318
- len = this.testSchemaAt(text2, m[2], re.lastIndex);
59319
- if (len) {
59320
- this.__schema__ = m[2];
59321
- this.__index__ = m.index + m[1].length;
59322
- this.__last_index__ = m.index + m[0].length + len;
59323
- break;
59384
+ if (this.testSchemaAt(text2, m[2], re.lastIndex)) {
59385
+ return true;
59324
59386
  }
59325
59387
  }
59326
59388
  }
59327
59389
  if (this.__opts__.fuzzyLink && this.__compiled__["http:"]) {
59328
- tld_pos = text2.search(this.re.host_fuzzy_test);
59329
- if (tld_pos >= 0) {
59330
- if (this.__index__ < 0 || tld_pos < this.__index__) {
59331
- if ((ml = text2.match(this.__opts__.fuzzyIP ? this.re.link_fuzzy : this.re.link_no_ip_fuzzy)) !== null) {
59332
- shift = ml.index + ml[1].length;
59333
- if (this.__index__ < 0 || shift < this.__index__) {
59334
- this.__schema__ = "";
59335
- this.__index__ = shift;
59336
- this.__last_index__ = ml.index + ml[0].length;
59337
- }
59338
- }
59390
+ if (text2.search(this.re.host_fuzzy_test) >= 0) {
59391
+ if (text2.match(this.__opts__.fuzzyIP ? this.re.link_fuzzy : this.re.link_no_ip_fuzzy) !== null) {
59392
+ return true;
59339
59393
  }
59340
59394
  }
59341
59395
  }
59342
59396
  if (this.__opts__.fuzzyEmail && this.__compiled__["mailto:"]) {
59343
- at_pos = text2.indexOf("@");
59344
- if (at_pos >= 0) {
59345
- if ((me = text2.match(this.re.email_fuzzy)) !== null) {
59346
- shift = me.index + me[1].length;
59347
- next = me.index + me[0].length;
59348
- if (this.__index__ < 0 || shift < this.__index__ || shift === this.__index__ && next > this.__last_index__) {
59349
- this.__schema__ = "mailto:";
59350
- this.__index__ = shift;
59351
- this.__last_index__ = next;
59352
- }
59397
+ if (text2.indexOf("@") >= 0) {
59398
+ if (text2.match(this.re.email_fuzzy) !== null) {
59399
+ return true;
59353
59400
  }
59354
59401
  }
59355
59402
  }
59356
- return this.__index__ >= 0;
59403
+ return false;
59357
59404
  };
59358
59405
  LinkifyIt.prototype.pretest = function pretest(text2) {
59359
59406
  return this.re.pretest.test(text2);
@@ -59366,16 +59413,87 @@ LinkifyIt.prototype.testSchemaAt = function testSchemaAt(text2, schema, pos) {
59366
59413
  };
59367
59414
  LinkifyIt.prototype.match = function match(text2) {
59368
59415
  const result = [];
59369
- let shift = 0;
59370
- if (this.__index__ >= 0 && this.__text_cache__ === text2) {
59371
- result.push(createMatch(this, shift));
59372
- shift = this.__last_index__;
59416
+ const type_schemed = [];
59417
+ const type_fuzzy_link = [];
59418
+ const type_fuzzy_email = [];
59419
+ let m, len, re;
59420
+ function choose(a, b) {
59421
+ if (!a) {
59422
+ return b;
59423
+ }
59424
+ if (!b) {
59425
+ return a;
59426
+ }
59427
+ if (a.index !== b.index) {
59428
+ return a.index < b.index ? a : b;
59429
+ }
59430
+ return a.lastIndex >= b.lastIndex ? a : b;
59373
59431
  }
59374
- let tail = shift ? text2.slice(shift) : text2;
59375
- while (this.test(tail)) {
59376
- result.push(createMatch(this, shift));
59377
- tail = tail.slice(this.__last_index__);
59378
- shift += this.__last_index__;
59432
+ if (!text2.length) {
59433
+ return null;
59434
+ }
59435
+ if (this.re.schema_test.test(text2)) {
59436
+ re = this.re.schema_search;
59437
+ re.lastIndex = 0;
59438
+ while ((m = re.exec(text2)) !== null) {
59439
+ len = this.testSchemaAt(text2, m[2], re.lastIndex);
59440
+ if (len) {
59441
+ type_schemed.push({
59442
+ schema: m[2],
59443
+ index: m.index + m[1].length,
59444
+ lastIndex: m.index + m[0].length + len
59445
+ });
59446
+ }
59447
+ }
59448
+ }
59449
+ if (this.__opts__.fuzzyLink && this.__compiled__["http:"]) {
59450
+ re = this.__opts__.fuzzyIP ? this.re.link_fuzzy_global : this.re.link_no_ip_fuzzy_global;
59451
+ re.lastIndex = 0;
59452
+ while ((m = re.exec(text2)) !== null) {
59453
+ type_fuzzy_link.push({
59454
+ schema: "",
59455
+ index: m.index + m[1].length,
59456
+ lastIndex: m.index + m[0].length
59457
+ });
59458
+ }
59459
+ }
59460
+ if (this.__opts__.fuzzyEmail && this.__compiled__["mailto:"]) {
59461
+ re = this.re.email_fuzzy_global;
59462
+ re.lastIndex = 0;
59463
+ while ((m = re.exec(text2)) !== null) {
59464
+ type_fuzzy_email.push({
59465
+ schema: "mailto:",
59466
+ index: m.index + m[1].length,
59467
+ lastIndex: m.index + m[0].length
59468
+ });
59469
+ }
59470
+ }
59471
+ const indexes = [0, 0, 0];
59472
+ let lastIndex = 0;
59473
+ for (; ; ) {
59474
+ const candidates = [
59475
+ type_schemed[indexes[0]],
59476
+ type_fuzzy_email[indexes[1]],
59477
+ type_fuzzy_link[indexes[2]]
59478
+ ];
59479
+ const candidate = choose(choose(candidates[0], candidates[1]), candidates[2]);
59480
+ if (!candidate) {
59481
+ break;
59482
+ }
59483
+ if (candidate === candidates[0]) {
59484
+ indexes[0]++;
59485
+ } else if (candidate === candidates[1]) {
59486
+ indexes[1]++;
59487
+ } else {
59488
+ indexes[2]++;
59489
+ }
59490
+ if (candidate.index < lastIndex) {
59491
+ continue;
59492
+ }
59493
+ const match2 = new Match(text2, candidate.schema, candidate.index, candidate.lastIndex);
59494
+ this.__compiled__[match2.schema].normalize(match2, this);
59495
+ result.push(match2);
59496
+ lastIndex = candidate.lastIndex;
59379
59497
  }
59380
59498
  if (result.length) {
59381
59499
  return result;
@@ -59383,17 +59501,14 @@ LinkifyIt.prototype.match = function match(text2) {
59383
59501
  return null;
59384
59502
  };
59385
59503
  LinkifyIt.prototype.matchAtStart = function matchAtStart(text2) {
59386
- this.__text_cache__ = text2;
59387
- this.__index__ = -1;
59388
59504
  if (!text2.length) return null;
59389
59505
  const m = this.re.schema_at_start.exec(text2);
59390
59506
  if (!m) return null;
59391
59507
  const len = this.testSchemaAt(text2, m[2], m[0].length);
59392
59508
  if (!len) return null;
59393
- this.__schema__ = m[2];
59394
- this.__index__ = m.index + m[1].length;
59395
- this.__last_index__ = m.index + m[0].length + len;
59396
- return createMatch(this, 0);
59509
+ const match2 = new Match(text2, m[2], m.index + m[1].length, m.index + m[0].length + len);
59510
+ this.__compiled__[match2.schema].normalize(match2, this);
59511
+ return match2;
59397
59512
  };
59398
59513
  LinkifyIt.prototype.tlds = function tlds(list2, keepOld) {
59399
59514
  list2 = Array.isArray(list2) ? list2 : [list2];
@@ -60904,9 +61019,9 @@ var DEFAULT_POST_INDEX = Object.freeze({
60904
61019
  paginate: true
60905
61020
  });
60906
61021
  var PERMALINK_OUTPUT_STYLES = /* @__PURE__ */ new Set(["directory", "html-extension"]);
60907
- var COMMENT_POLICY_OUTPUT_PATH = "_zeropress/comment-policy.json";
60908
61022
  var SEARCH_INDEX_OUTPUT_PATH = "_zeropress/search.json";
60909
61023
  var SEARCH_ADAPTER_OUTPUT_PATH = "_zeropress/search.js";
61024
+ var SEARCH_PAGEFIND_ADAPTER_OUTPUT_PATH = "_zeropress/search_pagefind.js";
60910
61025
  var OUTPUT_PATH_CONTROL_CHAR_PATTERN = /[\u0000-\u001F\u007F]/;
60911
61026
  var SAFE_MEDIA_PROTOCOLS = /* @__PURE__ */ new Set(["http:", "https:"]);
60912
61027
  var SAFE_LINK_PROTOCOLS = /* @__PURE__ */ new Set(["http:", "https:", "mailto:", "tel:"]);
@@ -60957,16 +61072,12 @@ async function buildSite(input2) {
60957
61072
  for (const assetOutput of state.assetOutputs) {
60958
61073
  await writeOutput(state.writer, state.summaries, assetOutput.path, assetOutput.content, assetOutput.contentType);
60959
61074
  }
60960
- await writeOutput(
60961
- state.writer,
60962
- state.summaries,
60963
- COMMENT_POLICY_OUTPUT_PATH,
60964
- state.commentPolicyContent,
60965
- "application/json"
60966
- );
60967
- if (options2.generateSpecialFiles) {
61075
+ if (shouldGenerateSearchArtifacts(state, options2)) {
60968
61076
  await writeOutput(state.writer, state.summaries, SEARCH_INDEX_OUTPUT_PATH, buildSearchIndexJson(state), "application/json");
60969
61077
  await writeOutput(state.writer, state.summaries, SEARCH_ADAPTER_OUTPUT_PATH, buildSearchAdapterJs(), "application/javascript");
61078
+ await writeOutput(state.writer, state.summaries, SEARCH_PAGEFIND_ADAPTER_OUTPUT_PATH, buildSearchPagefindAdapterJs(), "application/javascript");
61079
+ }
61080
+ if (options2.generateSpecialFiles) {
60970
61081
  await maybeRenderNotFoundPage(state);
60971
61082
  if (hasCanonicalSiteUrl(state.previewData.site.url)) {
60972
61083
  await writeOutput(
@@ -61018,7 +61129,6 @@ async function createBuildState(input2, options2) {
61018
61129
  customHtml: previewData.custom_html,
61019
61130
  favicon: previewData.site.favicon,
61020
61131
  exposeGenerator: previewData.site.expose_generator !== false,
61021
- commentPolicyContent: buildCommentPolicyManifest(renderData.posts),
61022
61132
  options: options2,
61023
61133
  generatedAt: /* @__PURE__ */ new Date(),
61024
61134
  emitted: {
@@ -61080,7 +61190,7 @@ async function renderRoute(state, templateName, route) {
61080
61190
  route: routeContext,
61081
61191
  meta: buildPageMeta(state.previewData.site, {
61082
61192
  currentUrl,
61083
- title: state.previewData.site.title,
61193
+ title: route.is_front_page === true ? buildFrontPageTitle(state.previewData.site) : state.previewData.site.title,
61084
61194
  description: state.previewData.site.description,
61085
61195
  ogType: "website"
61086
61196
  })
@@ -61124,7 +61234,7 @@ async function renderFrontPage(state, route) {
61124
61234
  route: routeContext,
61125
61235
  meta: buildPageMeta(state.previewData.site, {
61126
61236
  currentUrl,
61127
- title: buildDocumentTitle(page.title, state.previewData.site.title),
61237
+ title: buildFrontPageTitle(state.previewData.site),
61128
61238
  description: page.excerpt,
61129
61239
  ogType: "website",
61130
61240
  image: page.featured_image,
@@ -61156,7 +61266,7 @@ async function renderFrontPage(state, route) {
61156
61266
  route: routeContext,
61157
61267
  meta: buildPageMeta(state.previewData.site, {
61158
61268
  currentUrl,
61159
- title: state.previewData.site.title,
61269
+ title: buildFrontPageTitle(state.previewData.site),
61160
61270
  description: state.previewData.site.description,
61161
61271
  ogType: "website"
61162
61272
  })
@@ -61273,11 +61383,13 @@ async function maybeRenderNotFoundPage(state) {
61273
61383
  await writeOutput(state.writer, state.summaries, "404.html", html, "text/html");
61274
61384
  }
61275
61385
  function normalizePreviewData(previewData, options2 = {}) {
61386
+ const media_base_url = normalizeOptionalString(previewData.site.media_base_url);
61276
61387
  const normalizedSite = {
61277
61388
  ...previewData.site,
61278
- media_base_url: normalizeOptionalString(previewData.site.media_base_url),
61389
+ media_base_url,
61279
61390
  media_delivery_mode: MEDIA_DELIVERY_MODES.has(previewData.site.media_delivery_mode) ? previewData.site.media_delivery_mode : "none",
61280
- favicon: normalizeSiteFavicon(previewData.site.favicon || options2.favicon),
61391
+ favicon: previewData.site.favicon ? normalizeSiteFavicon(previewData.site.favicon, media_base_url) : normalizeSiteFavicon(options2.favicon, ""),
61392
+ logo: normalizeSiteLogo(previewData.site.logo, media_base_url),
61281
61393
  posts_per_page: Number.isInteger(previewData.site.posts_per_page) && previewData.site.posts_per_page > 0 ? previewData.site.posts_per_page : DEFAULT_POSTS_PER_PAGE,
61282
61394
  datetime_display: DATETIME_DISPLAY_MODES.has(previewData.site.datetime_display) ? previewData.site.datetime_display : DEFAULT_DATETIME_DISPLAY,
61283
61395
  date_style: DATETIME_STYLES.has(previewData.site.date_style) ? previewData.site.date_style : DEFAULT_DATE_STYLE,
@@ -61286,6 +61398,7 @@ function normalizePreviewData(previewData, options2 = {}) {
61286
61398
  locale: normalizeLocale(previewData.site.locale || DEFAULT_LOCALE),
61287
61399
  disallow_comments: previewData.site.disallow_comments === true,
61288
61400
  expose_generator: previewData.site.expose_generator !== false,
61401
+ search: previewData.site.search !== false,
61289
61402
  indexing: previewData.site.indexing !== false,
61290
61403
  permalinks: normalizePermalinks(previewData.site.permalinks),
61291
61404
  front_page: normalizeFrontPage(previewData.site.front_page),
@@ -61519,7 +61632,7 @@ function normalizeCustomHtml(customHtml) {
61519
61632
  ...bodyEnd ? { body_end: { content: bodyEnd } } : {}
61520
61633
  };
61521
61634
  }
61522
- function normalizeSiteFavicon(favicon) {
61635
+ function normalizeSiteFavicon(favicon, media_base_url) {
61523
61636
  if (!favicon || typeof favicon !== "object") {
61524
61637
  return void 0;
61525
61638
  }
@@ -61527,11 +61640,25 @@ function normalizeSiteFavicon(favicon) {
61527
61640
  for (const key of ["icon", "svg", "png", "apple_touch_icon"]) {
61528
61641
  const value = normalizeOptionalString(favicon[key]);
61529
61642
  if (value) {
61530
- normalized[key] = value;
61643
+ normalized[key] = normalizeMediaField(value, media_base_url);
61531
61644
  }
61532
61645
  }
61533
61646
  return Object.keys(normalized).length ? normalized : void 0;
61534
61647
  }
61648
+ function normalizeSiteLogo(logo, media_base_url) {
61649
+ if (!logo || typeof logo !== "object") {
61650
+ return void 0;
61651
+ }
61652
+ const src = normalizeMediaField(logo.src, media_base_url);
61653
+ if (!src) {
61654
+ return void 0;
61655
+ }
61656
+ const alt = normalizeOptionalString(logo.alt);
61657
+ return {
61658
+ src,
61659
+ ...alt ? { alt } : {}
61660
+ };
61661
+ }
61535
61662
  function normalizePermalinks(permalinks) {
61536
61663
  const source = permalinks && typeof permalinks === "object" ? permalinks : {};
61537
61664
  const outputStyle = typeof source.output_style === "string" && PERMALINK_OUTPUT_STYLES.has(source.output_style) ? source.output_style : DEFAULT_PERMALINKS.output_style;
@@ -61567,6 +61694,8 @@ function normalizePostIndex(post_index) {
61567
61694
  function createRenderData(previewData, themeMetadata = {}) {
61568
61695
  const themeSupportsComments = themeMetadata?.features?.comments === true;
61569
61696
  const themeSupportsPostIndex = themeMetadata?.features?.post_index !== false;
61697
+ const themeSupportsSearch = themeMetadata?.features?.search === true;
61698
+ previewData.site.search = previewData.site.search !== false && themeSupportsSearch;
61570
61699
  const authorsById = new Map(previewData.content.authors.map((author) => [author.id, author]));
61571
61700
  const categoriesBySlug = new Map(previewData.content.categories.map((category) => [category.slug, category]));
61572
61701
  const tagsBySlug = new Map(previewData.content.tags.map((tag) => [tag.slug, tag]));
@@ -62103,13 +62232,6 @@ function preparePost(post, site, authorsById, categoriesBySlug, tagsBySlug, them
62103
62232
  comments_enabled: themeSupportsComments && site.disallow_comments !== true && post.allow_comments === true
62104
62233
  };
62105
62234
  }
62106
- function buildCommentPolicyManifest(posts) {
62107
- const commentablePosts = posts.filter((post) => post.status === "published" && post.comments_enabled === true).map((post) => post.public_id).filter((value) => Number.isInteger(value) && value > 0);
62108
- return JSON.stringify({
62109
- version: 1,
62110
- commentable_posts: commentablePosts
62111
- }, null, 2);
62112
- }
62113
62235
  function buildTaxonomyRoutes(options2) {
62114
62236
  const routes = [];
62115
62237
  for (const item of options2.items) {
@@ -62658,6 +62780,11 @@ function buildDocumentTitle(contentTitle, siteTitle) {
62658
62780
  const resolvedSiteTitle = normalizeNonEmptyString(siteTitle, resolvedContentTitle);
62659
62781
  return `${resolvedContentTitle} - ${resolvedSiteTitle}`;
62660
62782
  }
62783
+ function buildFrontPageTitle(site) {
62784
+ const resolvedSiteTitle = normalizeNonEmptyString(site.title, "");
62785
+ const resolvedDescription = normalizeOptionalString(site.description);
62786
+ return resolvedDescription ? `${resolvedSiteTitle} - ${resolvedDescription}` : resolvedSiteTitle;
62787
+ }
62661
62788
  function buildMetaHeadTags(meta) {
62662
62789
  const tags = [];
62663
62790
  if (meta.description) {
@@ -62919,11 +63046,12 @@ function assertPlannedOutputPathsSafe(state) {
62919
63046
  assertUniqueRoutes(routeEntries);
62920
63047
  const plannedPaths = [
62921
63048
  ...routeEntries.map((entry) => entry.outputPath),
62922
- ...state.assetOutputs.map((assetOutput) => assetOutput.path),
62923
- COMMENT_POLICY_OUTPUT_PATH
63049
+ ...state.assetOutputs.map((assetOutput) => assetOutput.path)
62924
63050
  ];
63051
+ if (shouldGenerateSearchArtifacts(state, state.options)) {
63052
+ plannedPaths.push(SEARCH_INDEX_OUTPUT_PATH, SEARCH_ADAPTER_OUTPUT_PATH, SEARCH_PAGEFIND_ADAPTER_OUTPUT_PATH);
63053
+ }
62925
63054
  if (state.options.generateSpecialFiles) {
62926
- plannedPaths.push(SEARCH_INDEX_OUTPUT_PATH, SEARCH_ADAPTER_OUTPUT_PATH);
62927
63055
  plannedPaths.push("404.html");
62928
63056
  if (shouldGenerateRobotsTxt(state.options)) {
62929
63057
  plannedPaths.push("robots.txt");
@@ -63436,6 +63564,87 @@ function normalizeLimit(value) {
63436
63564
  }
63437
63565
  `;
63438
63566
  }
63567
+ function buildSearchPagefindAdapterJs() {
63568
+ return `let pagefindPromise;
63569
+
63570
+ export async function preload() {
63571
+ if (!pagefindPromise) {
63572
+ pagefindPromise = import(new URL('./pagefind/pagefind.js', import.meta.url).href).then(async (pagefind) => {
63573
+ if (typeof pagefind.options === 'function') {
63574
+ await pagefind.options({ baseUrl: '/' });
63575
+ }
63576
+ return pagefind;
63577
+ });
63578
+ }
63579
+
63580
+ return pagefindPromise;
63581
+ }
63582
+
63583
+ export async function search(query, options = {}) {
63584
+ const pagefind = await preload();
63585
+ const result = await pagefind.search(query, options);
63586
+ const limit = normalizeLimit(options.limit);
63587
+ if (!Array.isArray(result?.results)) {
63588
+ return result;
63589
+ }
63590
+
63591
+ const results = result.results.map(normalizeResult);
63592
+ return {
63593
+ ...result,
63594
+ results: limit ? results.slice(0, limit) : results,
63595
+ };
63596
+ }
63597
+
63598
+ function normalizeResult(result) {
63599
+ if (!result || typeof result.data !== 'function') {
63600
+ return result;
63601
+ }
63602
+
63603
+ return {
63604
+ ...result,
63605
+ data: async () => normalizeResultData(await result.data()),
63606
+ };
63607
+ }
63608
+
63609
+ function normalizeResultData(data) {
63610
+ if (!data || typeof data !== 'object') {
63611
+ return data;
63612
+ }
63613
+
63614
+ return {
63615
+ ...data,
63616
+ url: normalizeUrl(data.url),
63617
+ sub_results: Array.isArray(data.sub_results)
63618
+ ? data.sub_results.map((item) => ({ ...item, url: normalizeUrl(item.url) }))
63619
+ : data.sub_results,
63620
+ };
63621
+ }
63622
+
63623
+ function normalizeUrl(value) {
63624
+ const url = String(value || '');
63625
+ if (url.startsWith('/_zeropress/') && !url.startsWith('/_zeropress/pagefind/')) {
63626
+ return url.replace(/^\\/_zeropress/, '') || '/';
63627
+ }
63628
+ if (url.startsWith('_zeropress/') && !url.startsWith('_zeropress/pagefind/')) {
63629
+ return url.replace(/^_zeropress/, '') || '/';
63630
+ }
63631
+ return url;
63632
+ }
63633
+
63634
+ function normalizeLimit(value) {
63635
+ if (value === undefined || value === null) {
63636
+ return null;
63637
+ }
63638
+
63639
+ const limit = Number(value);
63640
+ if (!Number.isFinite(limit) || limit <= 0) {
63641
+ return null;
63642
+ }
63643
+
63644
+ return Math.floor(limit);
63645
+ }
63646
+ `;
63647
+ }
63439
63648
  function buildSitemapXml(site, emitted, generatedAt, stylesheetHref = "") {
63440
63649
  const entries = [
63441
63650
  ...emitted.frontPage && emitted.frontPage.includeInSitemap !== false ? [{
@@ -63521,6 +63730,9 @@ function buildRobotsTxt(site) {
63521
63730
  function shouldGenerateRobotsTxt(options2) {
63522
63731
  return options2.generateSpecialFiles && options2.generateRobotsTxt !== false;
63523
63732
  }
63733
+ function shouldGenerateSearchArtifacts(state, options2) {
63734
+ return options2.generateSpecialFiles && state.previewData.site.search === true;
63735
+ }
63524
63736
  function getContentType(assetPath) {
63525
63737
  const ext = assetPath.split(".").pop()?.toLowerCase();
63526
63738
  const contentTypes = {
@@ -64017,6 +64229,8 @@ async function runBuildPages(options2) {
64017
64229
  const cwd = path3.resolve(options2.cwd || process.cwd());
64018
64230
  const copyMarkdownSource = options2.copyMarkdownSource !== false;
64019
64231
  const sourceDir = path3.resolve(cwd, options2.source);
64232
+ const publicDirExplicit = hasExplicitPublicDir(options2);
64233
+ const publicDir = publicDirExplicit ? path3.resolve(cwd, options2.publicDir) : sourceDir;
64020
64234
  const destinationDir = path3.resolve(cwd, options2.destination);
64021
64235
  const generatedDir = path3.join(cwd, ".zeropress");
64022
64236
  const stagingDir = path3.join(cwd, STAGING_DIR);
@@ -64025,17 +64239,22 @@ async function runBuildPages(options2) {
64025
64239
  assertBuildPagesPathLayout({
64026
64240
  cwd,
64027
64241
  sourceDir,
64242
+ publicDir,
64243
+ publicDirExplicit,
64028
64244
  destinationDir,
64029
64245
  themeDir,
64030
64246
  generatedDir
64031
64247
  });
64032
64248
  await assertDirectory(sourceDir, "Source directory");
64249
+ await assertPublicDirectory(publicDir, publicDirExplicit);
64250
+ await assertDestinationPath(destinationDir);
64033
64251
  await fs3.rm(generatedDir, { recursive: true, force: true });
64034
64252
  await fs3.mkdir(generatedDir, { recursive: true });
64035
64253
  const env = {
64036
64254
  ...process.env,
64037
64255
  ZEROPRESS_BUILD_PAGES_SOURCE: sourceDir,
64038
- ZEROPRESS_PUBLIC_DIR: sourceDir,
64256
+ ZEROPRESS_BUILD_PAGES_PUBLIC_DIR: publicDir,
64257
+ ZEROPRESS_PUBLIC_DIR: publicDir,
64039
64258
  ZEROPRESS_SKIP_UNTITLED_MARKDOWN: String(Boolean(options2.skipUntitledMarkdown)),
64040
64259
  ZEROPRESS_COPY_MARKDOWN_SOURCE: String(copyMarkdownSource)
64041
64260
  };
@@ -64059,10 +64278,13 @@ async function runBuildPages(options2) {
64059
64278
  await fs3.rm(destinationDir, { recursive: true, force: true });
64060
64279
  await fs3.rm(stagingDir, { recursive: true, force: true });
64061
64280
  await fs3.mkdir(stagingDir, { recursive: true });
64062
- await copyPublicStaging(sourceDir, stagingDir, {
64281
+ await copyPublicStaging(publicDir, stagingDir, {
64063
64282
  excludePaths: [destinationDir, themeDir, generatedDir],
64064
64283
  copyMarkdownSource
64065
64284
  });
64285
+ if (copyMarkdownSource) {
64286
+ await copySourceMarkdownFiles(sourceDir, stagingDir, previewData);
64287
+ }
64066
64288
  const previousPublicDir = process.env.ZEROPRESS_PUBLIC_DIR;
64067
64289
  process.env.ZEROPRESS_PUBLIC_DIR = stagingDir;
64068
64290
  try {
@@ -64097,6 +64319,9 @@ function resolveThemeDir(cwd, options2) {
64097
64319
  }
64098
64320
  throw new Error(`Unknown bundled theme: ${options2.theme}`);
64099
64321
  }
64322
+ function hasExplicitPublicDir(options2) {
64323
+ return typeof options2.publicDir === "string" && Boolean(options2.publicDir.trim());
64324
+ }
64100
64325
  async function assertDirectory(dir, label) {
64101
64326
  let stat;
64102
64327
  try {
@@ -64111,17 +64336,78 @@ async function assertDirectory(dir, label) {
64111
64336
  throw new Error(`${label} is not a directory: ${dir}`);
64112
64337
  }
64113
64338
  }
64114
- function assertBuildPagesPathLayout({ cwd, sourceDir, destinationDir, themeDir, generatedDir }) {
64339
+ async function assertPublicDirectory(publicDir, explicit) {
64340
+ if (!explicit) {
64341
+ return;
64342
+ }
64343
+ let stat;
64344
+ try {
64345
+ stat = await fs3.lstat(publicDir);
64346
+ } catch (error) {
64347
+ if (error?.code === "ENOENT") {
64348
+ throw new Error(`Public directory not found: ${publicDir}`);
64349
+ }
64350
+ throw error;
64351
+ }
64352
+ if (stat.isSymbolicLink()) {
64353
+ throw new Error(`Public directory must not be a symbolic link: ${publicDir}`);
64354
+ }
64355
+ if (!stat.isDirectory()) {
64356
+ throw new Error(`Public path is not a directory: ${publicDir}`);
64357
+ }
64358
+ }
64359
+ async function assertDestinationPath(destinationDir) {
64360
+ let stat;
64361
+ try {
64362
+ stat = await fs3.lstat(destinationDir);
64363
+ } catch (error) {
64364
+ if (error?.code === "ENOENT") {
64365
+ return;
64366
+ }
64367
+ throw error;
64368
+ }
64369
+ if (!stat.isDirectory()) {
64370
+ throw new Error(`Destination path is not a directory: ${destinationDir}`);
64371
+ }
64372
+ }
64373
+ function assertBuildPagesPathLayout({
64374
+ cwd,
64375
+ sourceDir,
64376
+ publicDir,
64377
+ publicDirExplicit,
64378
+ destinationDir,
64379
+ themeDir,
64380
+ generatedDir
64381
+ }) {
64115
64382
  if (samePath(sourceDir, cwd)) {
64116
64383
  throw new Error(
64117
64384
  `Source directory must be a dedicated content directory, not the current working directory. Received: ${formatPath(cwd, sourceDir)}`
64118
64385
  );
64119
64386
  }
64387
+ if (publicDirExplicit && samePath(publicDir, cwd)) {
64388
+ throw new Error(
64389
+ `Public directory must be a dedicated asset directory, not the current working directory. Received: ${formatPath(cwd, publicDir)}`
64390
+ );
64391
+ }
64120
64392
  assertNoPathOverlap(cwd, "Source directory", sourceDir, "internal .zeropress working directory", generatedDir);
64121
64393
  assertNoPathOverlap(cwd, "Destination directory", destinationDir, "internal .zeropress working directory", generatedDir);
64122
64394
  assertNoPathOverlap(cwd, "Theme directory", themeDir, "internal .zeropress working directory", generatedDir);
64395
+ if (!samePath(publicDir, sourceDir)) {
64396
+ assertNoPathOverlap(cwd, "Public directory", publicDir, "internal .zeropress working directory", generatedDir);
64397
+ assertNoPathOverlap(cwd, "Public directory", publicDir, "destination directory", destinationDir);
64398
+ assertNoPathOverlap(cwd, "Public directory", publicDir, "theme directory", themeDir);
64399
+ }
64123
64400
  assertNoPathOverlap(cwd, "Source directory", sourceDir, "destination directory", destinationDir);
64124
64401
  assertNoPathOverlap(cwd, "Source directory", sourceDir, "theme directory", themeDir);
64402
+ assertSourceIsNotInsidePublicDirectory(cwd, sourceDir, publicDir);
64403
+ }
64404
+ function assertSourceIsNotInsidePublicDirectory(cwd, sourceDir, publicDir) {
64405
+ if (samePath(sourceDir, publicDir) || !isPathInside2(publicDir, sourceDir)) {
64406
+ return;
64407
+ }
64408
+ throw new Error(
64409
+ `Source directory must not be inside the public directory. Source directory: ${formatPath(cwd, sourceDir)}; Public directory: ${formatPath(cwd, publicDir)}`
64410
+ );
64125
64411
  }
64126
64412
  function assertNoPathOverlap(cwd, firstLabel, firstPath, secondLabel, secondPath) {
64127
64413
  if (!pathsOverlap2(firstPath, secondPath)) {
@@ -64157,6 +64443,52 @@ async function copyPublicStaging(sourceDir, targetDir, options2) {
64157
64443
  await fs3.copyFile(sourcePath, targetPath);
64158
64444
  }
64159
64445
  }
64446
+ async function copySourceMarkdownFiles(sourceDir, targetDir, previewData) {
64447
+ const markdownUrls = /* @__PURE__ */ new Set();
64448
+ for (const page of previewData?.content?.pages || []) {
64449
+ const sourceMarkdownUrl = page?.meta?.source_markdown_url;
64450
+ if (typeof sourceMarkdownUrl === "string" && sourceMarkdownUrl) {
64451
+ markdownUrls.add(sourceMarkdownUrl);
64452
+ }
64453
+ }
64454
+ for (const sourceMarkdownUrl of markdownUrls) {
64455
+ const relativePath = sourceMarkdownUrlToRelativePath(sourceMarkdownUrl);
64456
+ if (!relativePath) {
64457
+ continue;
64458
+ }
64459
+ const sourcePath = path3.join(sourceDir, relativePath);
64460
+ if (!isPathInside2(sourceDir, sourcePath)) {
64461
+ continue;
64462
+ }
64463
+ const targetPath = path3.join(targetDir, relativePath);
64464
+ await fs3.mkdir(path3.dirname(targetPath), { recursive: true });
64465
+ await fs3.copyFile(sourcePath, targetPath);
64466
+ }
64467
+ }
64468
+ function sourceMarkdownUrlToRelativePath(sourceMarkdownUrl) {
64469
+ if (!sourceMarkdownUrl.startsWith("/") || sourceMarkdownUrl.includes("?") || sourceMarkdownUrl.includes("#")) {
64470
+ return "";
64471
+ }
64472
+ const rawSegments = sourceMarkdownUrl.slice(1).split("/");
64473
+ const segments = [];
64474
+ for (const rawSegment of rawSegments) {
64475
+ if (!rawSegment) {
64476
+ return "";
64477
+ }
64478
+ let segment;
64479
+ try {
64480
+ segment = decodeURIComponent(rawSegment);
64481
+ } catch {
64482
+ return "";
64483
+ }
64484
+ if (!segment || segment === "." || segment === ".." || segment.includes("/") || segment.includes("\\")) {
64485
+ return "";
64486
+ }
64487
+ segments.push(segment);
64488
+ }
64489
+ const relativePath = segments.join("/");
64490
+ return relativePath.toLowerCase().endsWith(".md") ? relativePath : "";
64491
+ }
64160
64492
  function shouldIgnorePublicEntry2(name) {
64161
64493
  const basename = String(name || "");
64162
64494
  const lowerName = basename.toLowerCase();
@@ -64185,6 +64517,7 @@ function formatPath(cwd, targetPath) {
64185
64517
  // src/action.js
64186
64518
  var options = {
64187
64519
  source: input("source") || "./docs",
64520
+ publicDir: input("public-dir"),
64188
64521
  destination: input("destination") || "./_site",
64189
64522
  theme: input("theme") || "docs",
64190
64523
  themePath: input("theme-path"),