fix(patches): rewrite micropub self-fetch to localhost for jailed setup
Node can't reach its own public HTTPS URL (ECONNREFUSED 127.0.0.1:443) because port 443 only exists on the nginx jail. Rewrite self-referential fetch URLs to http://localhost:3000 in endpoint-posts, endpoint-syndicate, and endpoint-share. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -4,8 +4,8 @@
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"postinstall": "xattr -w com.apple.fileprovider.ignore#P 1 node_modules 2>/dev/null || true && node scripts/patch-lightningcss.mjs && node scripts/patch-endpoint-media-scope.mjs && node scripts/patch-endpoint-media-sharp-runtime.mjs && node scripts/patch-frontend-sharp-runtime.mjs && node scripts/patch-endpoint-files-upload-route.mjs && node scripts/patch-endpoint-files-upload-locales.mjs && node scripts/patch-endpoint-activitypub-locales.mjs && node scripts/patch-endpoint-homepage-locales.mjs && node scripts/patch-endpoint-homepage-identity-defaults.mjs && node scripts/patch-federation-unlisted-guards.mjs && node scripts/patch-endpoint-micropub-where-note-visibility.mjs && node scripts/patch-endpoint-posts-ai-fields.mjs && node scripts/patch-endpoint-posts-ai-cleanup.mjs && node scripts/patch-endpoint-podroll-opml-upload.mjs && node scripts/patch-preset-eleventy-ai-frontmatter.mjs && node scripts/patch-micropub-ai-block-resync.mjs && node scripts/patch-frontend-serviceworker-file.mjs && node scripts/patch-endpoint-comments-locales.mjs && node scripts/patch-endpoint-posts-locales.mjs && node scripts/patch-endpoint-conversations-locales.mjs && node scripts/patch-conversations-collection-guards.mjs && node scripts/patch-indiekit-routes-rate-limits.mjs && node scripts/patch-indiekit-error-production-stack.mjs && node scripts/patch-indieauth-devmode-guard.mjs && node scripts/patch-listening-endpoint-runtime-guards.mjs && node scripts/patch-endpoint-github-changelog-categories.mjs && node scripts/patch-endpoint-blogroll-feeds-alias.mjs && node scripts/patch-endpoint-posts-uid-lookup.mjs && node scripts/patch-endpoint-posts-prefill-url.mjs && node scripts/patch-conversations-bluesky-self-filter.mjs && node scripts/patch-conversations-bluesky-cursor-fix.mjs && node scripts/patch-endpoint-micropub-source-filter.mjs && node scripts/patch-endpoint-posts-search-tags.mjs && node scripts/patch-syndicate-force-checked-default.mjs && node scripts/patch-ap-url-lookup-api.mjs && node scripts/patch-ap-allow-private-address.mjs && node scripts/patch-inbox-skip-view-activity-parse.mjs && node scripts/patch-inbox-ignore-view-activity.mjs && node scripts/patch-endpoint-posts-fetch-diagnostic.mjs && node scripts/patch-ap-normalize-nested-tags.mjs",
|
||||
"serve":"export NODE_ENV=${NODE_ENV:-production} INDIEKIT_DEBUG=${INDIEKIT_DEBUG:-0} && node scripts/preflight-production-security.mjs && node scripts/preflight-mongo-connection.mjs && node scripts/preflight-activitypub-rsa-key.mjs && node scripts/preflight-activitypub-profile-urls.mjs && node scripts/patch-lightningcss.mjs && node scripts/patch-endpoint-media-scope.mjs && node scripts/patch-endpoint-media-sharp-runtime.mjs && node scripts/patch-frontend-sharp-runtime.mjs && node scripts/patch-endpoint-files-upload-route.mjs && node scripts/patch-endpoint-files-upload-locales.mjs && node scripts/patch-endpoint-activitypub-locales.mjs && node scripts/patch-endpoint-homepage-locales.mjs && node scripts/patch-endpoint-homepage-identity-defaults.mjs && node scripts/patch-federation-unlisted-guards.mjs && node scripts/patch-endpoint-micropub-where-note-visibility.mjs && node scripts/patch-endpoint-posts-ai-fields.mjs && node scripts/patch-endpoint-posts-ai-cleanup.mjs && node scripts/patch-endpoint-podroll-opml-upload.mjs && node scripts/patch-preset-eleventy-ai-frontmatter.mjs && node scripts/patch-micropub-ai-block-resync.mjs && node scripts/patch-frontend-serviceworker-file.mjs && node scripts/patch-endpoint-comments-locales.mjs && node scripts/patch-endpoint-posts-locales.mjs && node scripts/patch-endpoint-conversations-locales.mjs && node scripts/patch-conversations-collection-guards.mjs && node scripts/patch-indiekit-routes-rate-limits.mjs && node scripts/patch-indiekit-error-production-stack.mjs && node scripts/patch-indieauth-devmode-guard.mjs && node scripts/patch-listening-endpoint-runtime-guards.mjs && node scripts/patch-endpoint-github-changelog-categories.mjs && node scripts/patch-microsub-reader-ap-dispatch.mjs && node scripts/patch-endpoint-blogroll-feeds-alias.mjs && node scripts/patch-endpoint-posts-uid-lookup.mjs && node scripts/patch-endpoint-posts-prefill-url.mjs && node scripts/patch-conversations-bluesky-self-filter.mjs && node scripts/patch-conversations-bluesky-cursor-fix.mjs && node scripts/patch-endpoint-micropub-source-filter.mjs && node scripts/patch-endpoint-posts-search-tags.mjs && node scripts/patch-syndicate-force-checked-default.mjs && node scripts/patch-ap-url-lookup-api.mjs && node scripts/patch-ap-allow-private-address.mjs && node scripts/patch-inbox-skip-view-activity-parse.mjs && node scripts/patch-inbox-ignore-view-activity.mjs && node scripts/patch-endpoint-posts-fetch-diagnostic.mjs && node scripts/patch-ap-normalize-nested-tags.mjs && node node_modules/@indiekit/indiekit/bin/cli.js serve --config indiekit.config.mjs",
|
||||
"postinstall": "xattr -w com.apple.fileprovider.ignore#P 1 node_modules 2>/dev/null || true && node scripts/patch-lightningcss.mjs && node scripts/patch-endpoint-media-scope.mjs && node scripts/patch-endpoint-media-sharp-runtime.mjs && node scripts/patch-frontend-sharp-runtime.mjs && node scripts/patch-endpoint-files-upload-route.mjs && node scripts/patch-endpoint-files-upload-locales.mjs && node scripts/patch-endpoint-activitypub-locales.mjs && node scripts/patch-endpoint-homepage-locales.mjs && node scripts/patch-endpoint-homepage-identity-defaults.mjs && node scripts/patch-federation-unlisted-guards.mjs && node scripts/patch-endpoint-micropub-where-note-visibility.mjs && node scripts/patch-endpoint-posts-ai-fields.mjs && node scripts/patch-endpoint-posts-ai-cleanup.mjs && node scripts/patch-endpoint-podroll-opml-upload.mjs && node scripts/patch-preset-eleventy-ai-frontmatter.mjs && node scripts/patch-micropub-ai-block-resync.mjs && node scripts/patch-frontend-serviceworker-file.mjs && node scripts/patch-endpoint-comments-locales.mjs && node scripts/patch-endpoint-posts-locales.mjs && node scripts/patch-endpoint-conversations-locales.mjs && node scripts/patch-conversations-collection-guards.mjs && node scripts/patch-indiekit-routes-rate-limits.mjs && node scripts/patch-indiekit-error-production-stack.mjs && node scripts/patch-indieauth-devmode-guard.mjs && node scripts/patch-listening-endpoint-runtime-guards.mjs && node scripts/patch-endpoint-github-changelog-categories.mjs && node scripts/patch-endpoint-blogroll-feeds-alias.mjs && node scripts/patch-endpoint-posts-uid-lookup.mjs && node scripts/patch-endpoint-posts-prefill-url.mjs && node scripts/patch-conversations-bluesky-self-filter.mjs && node scripts/patch-conversations-bluesky-cursor-fix.mjs && node scripts/patch-endpoint-micropub-source-filter.mjs && node scripts/patch-endpoint-posts-search-tags.mjs && node scripts/patch-syndicate-force-checked-default.mjs && node scripts/patch-ap-url-lookup-api.mjs && node scripts/patch-ap-allow-private-address.mjs && node scripts/patch-inbox-skip-view-activity-parse.mjs && node scripts/patch-inbox-ignore-view-activity.mjs && node scripts/patch-endpoint-posts-fetch-diagnostic.mjs && node scripts/patch-micropub-fetch-internal-url.mjs && node scripts/patch-ap-normalize-nested-tags.mjs",
|
||||
"serve":"export NODE_ENV=${NODE_ENV:-production} INDIEKIT_DEBUG=${INDIEKIT_DEBUG:-0} && node scripts/preflight-production-security.mjs && node scripts/preflight-mongo-connection.mjs && node scripts/preflight-activitypub-rsa-key.mjs && node scripts/preflight-activitypub-profile-urls.mjs && node scripts/patch-lightningcss.mjs && node scripts/patch-endpoint-media-scope.mjs && node scripts/patch-endpoint-media-sharp-runtime.mjs && node scripts/patch-frontend-sharp-runtime.mjs && node scripts/patch-endpoint-files-upload-route.mjs && node scripts/patch-endpoint-files-upload-locales.mjs && node scripts/patch-endpoint-activitypub-locales.mjs && node scripts/patch-endpoint-homepage-locales.mjs && node scripts/patch-endpoint-homepage-identity-defaults.mjs && node scripts/patch-federation-unlisted-guards.mjs && node scripts/patch-endpoint-micropub-where-note-visibility.mjs && node scripts/patch-endpoint-posts-ai-fields.mjs && node scripts/patch-endpoint-posts-ai-cleanup.mjs && node scripts/patch-endpoint-podroll-opml-upload.mjs && node scripts/patch-preset-eleventy-ai-frontmatter.mjs && node scripts/patch-micropub-ai-block-resync.mjs && node scripts/patch-frontend-serviceworker-file.mjs && node scripts/patch-endpoint-comments-locales.mjs && node scripts/patch-endpoint-posts-locales.mjs && node scripts/patch-endpoint-conversations-locales.mjs && node scripts/patch-conversations-collection-guards.mjs && node scripts/patch-indiekit-routes-rate-limits.mjs && node scripts/patch-indiekit-error-production-stack.mjs && node scripts/patch-indieauth-devmode-guard.mjs && node scripts/patch-listening-endpoint-runtime-guards.mjs && node scripts/patch-endpoint-github-changelog-categories.mjs && node scripts/patch-microsub-reader-ap-dispatch.mjs && node scripts/patch-endpoint-blogroll-feeds-alias.mjs && node scripts/patch-endpoint-posts-uid-lookup.mjs && node scripts/patch-endpoint-posts-prefill-url.mjs && node scripts/patch-conversations-bluesky-self-filter.mjs && node scripts/patch-conversations-bluesky-cursor-fix.mjs && node scripts/patch-endpoint-micropub-source-filter.mjs && node scripts/patch-endpoint-posts-search-tags.mjs && node scripts/patch-syndicate-force-checked-default.mjs && node scripts/patch-ap-url-lookup-api.mjs && node scripts/patch-ap-allow-private-address.mjs && node scripts/patch-inbox-skip-view-activity-parse.mjs && node scripts/patch-inbox-ignore-view-activity.mjs && node scripts/patch-endpoint-posts-fetch-diagnostic.mjs && node scripts/patch-micropub-fetch-internal-url.mjs && node scripts/patch-ap-normalize-nested-tags.mjs && node node_modules/@indiekit/indiekit/bin/cli.js serve --config indiekit.config.mjs",
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"keywords": [],
|
||||
|
||||
@@ -1,8 +1,25 @@
|
||||
/**
|
||||
* Patch: rewrite self-referential fetch URLs to use localhost and add
|
||||
* diagnostic logging for fetch failures.
|
||||
*
|
||||
* When behind a reverse proxy (e.g. nginx in a separate FreeBSD jail),
|
||||
* the endpoint-posts form controller fetches the micropub endpoint via
|
||||
* the public URL (https://...). But the Node process doesn't listen on
|
||||
* 443 — only nginx does. This causes ECONNREFUSED on the Node jail.
|
||||
*
|
||||
* Fix: rewrite the URL to http://localhost:<PORT> before fetching, so
|
||||
* the request stays inside the Node jail. The public URL is preserved
|
||||
* for everything else (HTML link headers, external clients, etc.).
|
||||
*
|
||||
* Controlled by INTERNAL_FETCH_URL env var (e.g. "http://localhost:3000").
|
||||
* Falls back to http://localhost:${PORT || 3000} automatically.
|
||||
*/
|
||||
|
||||
import { access, readFile, writeFile } from "node:fs/promises";
|
||||
|
||||
const filePath = "node_modules/@indiekit/endpoint-posts/lib/endpoint.js";
|
||||
|
||||
const marker = "// [patch] fetch-diagnostic";
|
||||
const marker = "// [patch] fetch-internal-rewrite";
|
||||
|
||||
async function exists(p) {
|
||||
try {
|
||||
@@ -14,28 +31,71 @@ async function exists(p) {
|
||||
}
|
||||
|
||||
if (!(await exists(filePath))) {
|
||||
console.log("[postinstall] endpoint-posts endpoint.js not found — skipping fetch-diagnostic patch");
|
||||
console.log("[postinstall] endpoint-posts endpoint.js not found — skipping fetch-rewrite patch");
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
const source = await readFile(filePath, "utf8");
|
||||
|
||||
if (source.includes(marker)) {
|
||||
console.log("[postinstall] endpoint-posts fetch-diagnostic patch already applied");
|
||||
console.log("[postinstall] endpoint-posts fetch-rewrite patch already applied");
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
// Wrap the fetch calls to log the underlying cause on failure
|
||||
const oldPost = ` async post(url, accessToken, jsonBody = false) {
|
||||
const endpointResponse = await fetch(url, {`;
|
||||
// Also handle the case where the old diagnostic-only patch was applied
|
||||
const oldMarker = "// [patch] fetch-diagnostic";
|
||||
let cleanSource = source;
|
||||
if (cleanSource.includes(oldMarker)) {
|
||||
// Strip old patch — we'll re-apply from scratch on the original structure.
|
||||
// Safest approach: bail and let the user re-run after npm install.
|
||||
console.log("[postinstall] Old fetch-diagnostic patch detected — stripping before re-patching");
|
||||
// We can't cleanly reverse the old patch, so we need to check if the
|
||||
// original structure is still recognisable. If not, warn and skip.
|
||||
}
|
||||
|
||||
const newPost = ` ${marker}
|
||||
const original = `import { IndiekitError } from "@indiekit/error";
|
||||
|
||||
export const endpoint = {
|
||||
/**
|
||||
* Micropub query
|
||||
* @param {string} url - URL
|
||||
* @param {string} accessToken - Access token
|
||||
* @returns {Promise<object>} Response data
|
||||
*/
|
||||
async get(url, accessToken) {
|
||||
const endpointResponse = await fetch(url, {
|
||||
headers: {
|
||||
accept: "application/json",
|
||||
authorization: \`Bearer \${accessToken}\`,
|
||||
},
|
||||
});
|
||||
|
||||
if (!endpointResponse.ok) {
|
||||
throw await IndiekitError.fromFetch(endpointResponse);
|
||||
}
|
||||
|
||||
const body = await endpointResponse.json();
|
||||
|
||||
return body;
|
||||
},
|
||||
|
||||
/**
|
||||
* Micropub action
|
||||
* @param {string} url - URL
|
||||
* @param {string} accessToken - Access token
|
||||
* @param {object} [jsonBody] - JSON body
|
||||
* @returns {Promise<object>} Response data
|
||||
*/
|
||||
async post(url, accessToken, jsonBody = false) {
|
||||
let endpointResponse;
|
||||
try {
|
||||
endpointResponse = await fetch(url, {`;
|
||||
|
||||
const oldPostEnd = ` });
|
||||
const endpointResponse = await fetch(url, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
accept: "application/json",
|
||||
authorization: \`Bearer \${accessToken}\`,
|
||||
...(jsonBody && { "content-type": "application/json" }),
|
||||
},
|
||||
...(jsonBody && { body: JSON.stringify(jsonBody) }),
|
||||
});
|
||||
|
||||
if (!endpointResponse.ok) {
|
||||
throw await IndiekitError.fromFetch(endpointResponse);
|
||||
@@ -47,11 +107,78 @@ const oldPostEnd = ` });
|
||||
},
|
||||
};`;
|
||||
|
||||
const newPostEnd = ` });
|
||||
const patched = `import { IndiekitError } from "@indiekit/error";
|
||||
|
||||
${marker}
|
||||
const _internalBase = (() => {
|
||||
if (process.env.INTERNAL_FETCH_URL) return process.env.INTERNAL_FETCH_URL.replace(/\\/+$/, "");
|
||||
const port = process.env.PORT || "3000";
|
||||
return \`http://localhost:\${port}\`;
|
||||
})();
|
||||
const _publicBase = (
|
||||
process.env.PUBLICATION_URL || process.env.SITE_URL || ""
|
||||
).replace(/\\/+$/, "");
|
||||
|
||||
function _toInternalUrl(url) {
|
||||
if (!_publicBase || !url.startsWith(_publicBase)) return url;
|
||||
return _internalBase + url.slice(_publicBase.length);
|
||||
}
|
||||
|
||||
export const endpoint = {
|
||||
/**
|
||||
* Micropub query
|
||||
* @param {string} url - URL
|
||||
* @param {string} accessToken - Access token
|
||||
* @returns {Promise<object>} Response data
|
||||
*/
|
||||
async get(url, accessToken) {
|
||||
const fetchUrl = _toInternalUrl(url);
|
||||
let endpointResponse;
|
||||
try {
|
||||
endpointResponse = await fetch(fetchUrl, {
|
||||
headers: {
|
||||
accept: "application/json",
|
||||
authorization: \`Bearer \${accessToken}\`,
|
||||
},
|
||||
});
|
||||
} catch (fetchError) {
|
||||
const cause = fetchError.cause || fetchError;
|
||||
console.error("[endpoint-posts] fetch failed for POST %s — %s: %s", url, cause.code || cause.name, cause.message);
|
||||
if (cause.cause) console.error("[endpoint-posts] nested cause: %s", cause.cause.message || cause.cause);
|
||||
console.error("[endpoint-posts] fetch failed for GET %s (internal: %s) — %s: %s", url, fetchUrl, cause.code || cause.name, cause.message);
|
||||
throw fetchError;
|
||||
}
|
||||
|
||||
if (!endpointResponse.ok) {
|
||||
throw await IndiekitError.fromFetch(endpointResponse);
|
||||
}
|
||||
|
||||
const body = await endpointResponse.json();
|
||||
|
||||
return body;
|
||||
},
|
||||
|
||||
/**
|
||||
* Micropub action
|
||||
* @param {string} url - URL
|
||||
* @param {string} accessToken - Access token
|
||||
* @param {object} [jsonBody] - JSON body
|
||||
* @returns {Promise<object>} Response data
|
||||
*/
|
||||
async post(url, accessToken, jsonBody = false) {
|
||||
const fetchUrl = _toInternalUrl(url);
|
||||
let endpointResponse;
|
||||
try {
|
||||
endpointResponse = await fetch(fetchUrl, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
accept: "application/json",
|
||||
authorization: \`Bearer \${accessToken}\`,
|
||||
...(jsonBody && { "content-type": "application/json" }),
|
||||
},
|
||||
...(jsonBody && { body: JSON.stringify(jsonBody) }),
|
||||
});
|
||||
} catch (fetchError) {
|
||||
const cause = fetchError.cause || fetchError;
|
||||
console.error("[endpoint-posts] fetch failed for POST %s (internal: %s) — %s: %s", url, fetchUrl, cause.code || cause.name, cause.message);
|
||||
throw fetchError;
|
||||
}
|
||||
|
||||
@@ -65,52 +192,20 @@ const newPostEnd = ` });
|
||||
},
|
||||
};`;
|
||||
|
||||
const oldGet = ` async get(url, accessToken) {
|
||||
const endpointResponse = await fetch(url, {`;
|
||||
|
||||
const newGet = ` async get(url, accessToken) {
|
||||
let endpointResponse;
|
||||
try {
|
||||
endpointResponse = await fetch(url, {`;
|
||||
|
||||
const oldGetEnd = ` });
|
||||
|
||||
if (!endpointResponse.ok) {
|
||||
throw await IndiekitError.fromFetch(endpointResponse);
|
||||
}
|
||||
|
||||
const body = await endpointResponse.json();
|
||||
|
||||
return body;
|
||||
},`;
|
||||
|
||||
const newGetEnd = ` });
|
||||
} catch (fetchError) {
|
||||
const cause = fetchError.cause || fetchError;
|
||||
console.error("[endpoint-posts] fetch failed for GET %s — %s: %s", url, cause.code || cause.name, cause.message);
|
||||
if (cause.cause) console.error("[endpoint-posts] nested cause: %s", cause.cause.message || cause.cause);
|
||||
throw fetchError;
|
||||
}
|
||||
|
||||
if (!endpointResponse.ok) {
|
||||
throw await IndiekitError.fromFetch(endpointResponse);
|
||||
}
|
||||
|
||||
const body = await endpointResponse.json();
|
||||
|
||||
return body;
|
||||
},`;
|
||||
|
||||
let updated = source;
|
||||
updated = updated.replace(oldPost, newPost);
|
||||
updated = updated.replace(oldPostEnd, newPostEnd);
|
||||
updated = updated.replace(oldGet, newGet);
|
||||
updated = updated.replace(oldGetEnd, newGetEnd);
|
||||
|
||||
if (!updated.includes(marker)) {
|
||||
console.warn("[postinstall] Skipping endpoint-posts fetch-diagnostic patch: upstream format changed");
|
||||
// Try matching the original (unpatched) file first
|
||||
if (cleanSource.includes(original.trim())) {
|
||||
const updated = cleanSource.replace(original.trim(), patched.trim());
|
||||
await writeFile(filePath, updated, "utf8");
|
||||
console.log("[postinstall] Patched endpoint-posts: fetch URL rewrite + diagnostic logging");
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
await writeFile(filePath, updated, "utf8");
|
||||
console.log("[postinstall] Patched endpoint-posts with fetch diagnostic logging");
|
||||
// If old diagnostic patch was applied, try matching that version
|
||||
if (cleanSource.includes(oldMarker)) {
|
||||
// Overwrite the whole file with the new patched version
|
||||
await writeFile(filePath, patched + "\n", "utf8");
|
||||
console.log("[postinstall] Replaced old fetch-diagnostic patch with fetch-rewrite + diagnostic");
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
console.warn("[postinstall] Skipping endpoint-posts fetch-rewrite patch: upstream format changed");
|
||||
|
||||
113
scripts/patch-micropub-fetch-internal-url.mjs
Normal file
113
scripts/patch-micropub-fetch-internal-url.mjs
Normal file
@@ -0,0 +1,113 @@
|
||||
/**
|
||||
* Patch: rewrite micropub self-fetch URLs to localhost in endpoint-syndicate
|
||||
* and endpoint-share.
|
||||
*
|
||||
* Same issue as endpoint-posts: behind a reverse proxy (nginx in a separate
|
||||
* FreeBSD jail), Node can't reach its own public HTTPS URL because port 443
|
||||
* only exists on the nginx jail.
|
||||
*
|
||||
* Rewrites fetch(application.micropubEndpoint, ...) to use
|
||||
* http://localhost:<PORT> instead.
|
||||
*/
|
||||
|
||||
import { access, readFile, writeFile } from "node:fs/promises";
|
||||
|
||||
const marker = "// [patch] micropub-fetch-internal-url";
|
||||
|
||||
const helperBlock = `${marker}
|
||||
const _mpInternalBase = (() => {
|
||||
if (process.env.INTERNAL_FETCH_URL) return process.env.INTERNAL_FETCH_URL.replace(/\\/+$/, "");
|
||||
const port = process.env.PORT || "3000";
|
||||
return \`http://localhost:\${port}\`;
|
||||
})();
|
||||
const _mpPublicBase = (
|
||||
process.env.PUBLICATION_URL || process.env.SITE_URL || ""
|
||||
).replace(/\\/+$/, "");
|
||||
function _toInternalUrl(url) {
|
||||
if (!_mpPublicBase || !url.startsWith(_mpPublicBase)) return url;
|
||||
return _mpInternalBase + url.slice(_mpPublicBase.length);
|
||||
}
|
||||
`;
|
||||
|
||||
const targets = [
|
||||
{
|
||||
paths: [
|
||||
"node_modules/@indiekit/endpoint-syndicate/lib/controllers/syndicate.js",
|
||||
],
|
||||
oldSnippet: ` const micropubResponse = await fetch(application.micropubEndpoint, {`,
|
||||
newSnippet: ` const micropubResponse = await fetch(_toInternalUrl(application.micropubEndpoint), {`,
|
||||
},
|
||||
{
|
||||
paths: [
|
||||
"node_modules/@indiekit/endpoint-share/lib/controllers/share.js",
|
||||
],
|
||||
oldSnippet: ` const micropubResponse = await fetch(application.micropubEndpoint, {`,
|
||||
newSnippet: ` const micropubResponse = await fetch(_toInternalUrl(application.micropubEndpoint), {`,
|
||||
},
|
||||
];
|
||||
|
||||
async function exists(filePath) {
|
||||
try {
|
||||
await access(filePath);
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
let totalPatched = 0;
|
||||
|
||||
for (const target of targets) {
|
||||
for (const filePath of target.paths) {
|
||||
if (!(await exists(filePath))) continue;
|
||||
|
||||
const source = await readFile(filePath, "utf8");
|
||||
|
||||
if (source.includes(marker)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!source.includes(target.oldSnippet)) {
|
||||
console.warn(`[postinstall] micropub-fetch-internal-url: snippet not found in ${filePath} — skipping`);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Insert helper block after the last import statement.
|
||||
// Find the last "from" keyword followed by a string and semicolon,
|
||||
// which marks the end of the last import.
|
||||
const importEndPattern = /;\s*\n/g;
|
||||
const allImportMatches = [...source.matchAll(/^import\s/gm)];
|
||||
if (allImportMatches.length === 0) {
|
||||
console.warn(`[postinstall] micropub-fetch-internal-url: no imports found in ${filePath} — skipping`);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Find the semicolon+newline that ends the last import block
|
||||
const lastImportStart = allImportMatches.at(-1).index;
|
||||
const afterLastImport = source.slice(lastImportStart);
|
||||
const fromMatch = afterLastImport.match(/from\s+["'][^"']+["']\s*;\s*\n/);
|
||||
if (!fromMatch) {
|
||||
console.warn(`[postinstall] micropub-fetch-internal-url: can't find end of last import in ${filePath} — skipping`);
|
||||
continue;
|
||||
}
|
||||
|
||||
const insertAt = lastImportStart + fromMatch.index + fromMatch[0].length;
|
||||
const beforeHelper = source.slice(0, insertAt);
|
||||
const afterHelper = source.slice(insertAt);
|
||||
|
||||
let updated = beforeHelper + "\n" + helperBlock + "\n" + afterHelper;
|
||||
|
||||
// Now replace the fetch call
|
||||
updated = updated.replace(target.oldSnippet, target.newSnippet);
|
||||
|
||||
await writeFile(filePath, updated, "utf8");
|
||||
console.log(`[postinstall] Patched micropub-fetch-internal-url in ${filePath}`);
|
||||
totalPatched++;
|
||||
}
|
||||
}
|
||||
|
||||
if (totalPatched === 0) {
|
||||
console.log("[postinstall] micropub-fetch-internal-url patches already applied or no targets found");
|
||||
} else {
|
||||
console.log(`[postinstall] micropub-fetch-internal-url: patched ${totalPatched} file(s)`);
|
||||
}
|
||||
Reference in New Issue
Block a user