@stack-mode/site-manager-kit 0.0.0-stage → 1.44.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +605 -2
- package/audit/ts-hooks.mjs +68 -0
- package/audit/wiring-audit.d.mts +37 -0
- package/audit/wiring-audit.mjs +604 -0
- package/bin/site-manager-kit.mjs +10 -0
- package/package.json +70 -4
- package/src/analytics.tsx +23 -0
- package/src/announcements.ts +13 -0
- package/src/attribution-fields.ts +52 -0
- package/src/attribution.tsx +47 -0
- package/src/blog.ts +122 -0
- package/src/chat-route.ts +136 -0
- package/src/chat-types.ts +76 -0
- package/src/client.ts +116 -0
- package/src/config.ts +78 -0
- package/src/copy-keys-route.ts +21 -0
- package/src/copy-keys.ts +77 -0
- package/src/data.ts +189 -0
- package/src/downloads.ts +7 -0
- package/src/faq.ts +21 -0
- package/src/floor-plans.ts +45 -0
- package/src/form-guard.tsx +37 -0
- package/src/form-token.ts +33 -0
- package/src/form-types.ts +13 -0
- package/src/forms.ts +76 -0
- package/src/glossary.ts +19 -0
- package/src/health-route.ts +34 -0
- package/src/image.ts +12 -0
- package/src/index.ts +36 -0
- package/src/indexnow.ts +40 -0
- package/src/listings.ts +38 -0
- package/src/metadata.ts +55 -0
- package/src/money.ts +10 -0
- package/src/not-found-reporter.tsx +16 -0
- package/src/not-found.ts +53 -0
- package/src/payment.ts +70 -0
- package/src/phone-input.tsx +26 -0
- package/src/phone.ts +37 -0
- package/src/preview-banner.tsx +49 -0
- package/src/preview-route.ts +48 -0
- package/src/preview.ts +94 -0
- package/src/redirects.ts +57 -0
- package/src/residents.ts +23 -0
- package/src/revalidate-route.ts +34 -0
- package/src/robots.ts +26 -0
- package/src/rss-route.ts +26 -0
- package/src/services.ts +52 -0
- package/src/signature.ts +23 -0
- package/src/site-chat-panel.tsx +537 -0
- package/src/site-chat.tsx +26 -0
- package/src/sitemap.ts +26 -0
- package/src/structured-data.tsx +207 -0
- package/src/types.ts +580 -0
- package/src/version.ts +1 -0
- package/src/visual-accents.ts +126 -0
- package/src/visual-bridge-client.tsx +1070 -0
- package/src/visual-bridge.tsx +30 -0
- package/src/visual-clicks.ts +13 -0
- package/src/visual-lists.ts +37 -0
- package/src/visual-match.ts +77 -0
- package/src/visual-messages.ts +160 -0
- package/src/visual-mode.ts +18 -0
- package/src/visual-preview.ts +69 -0
- package/src/visual-tags.ts +90 -0
- package/src/visual.ts +59 -0
- package/src/waitlist-form.ts +39 -0
- package/src/waitlist.ts +48 -0
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
// Module hooks that let the wiring audit import a site's src/copy-keys.ts in plain Node, with the TypeScript the site
|
|
2
|
+
// already has (every Next.js site does). Handles the site's tsconfig `paths` (such as "@/*"), imports without an
|
|
3
|
+
// extension, JSON imports and server-only markers. Registered by wiring-audit.mjs; nothing else uses it.
|
|
4
|
+
|
|
5
|
+
import { readFileSync, existsSync, statSync } from "node:fs";
|
|
6
|
+
import { pathToFileURL, fileURLToPath } from "node:url";
|
|
7
|
+
import path from "node:path";
|
|
8
|
+
import { createRequire } from "node:module";
|
|
9
|
+
|
|
10
|
+
let ts = null;
|
|
11
|
+
let aliases = [];
|
|
12
|
+
|
|
13
|
+
/** data: { siteDir, aliases: [{ prefix, targets: [absolute dir prefix] }] } */
|
|
14
|
+
export async function initialize(data) {
|
|
15
|
+
const require = createRequire(path.join(data.siteDir, "package.json"));
|
|
16
|
+
ts = require("typescript");
|
|
17
|
+
aliases = data.aliases ?? [];
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const EXTENSIONS = [".ts", ".tsx", ".mts", ".js", ".mjs", ".jsx", ".json"];
|
|
21
|
+
const EMPTY = "data:text/javascript,export%20default%20undefined%3B";
|
|
22
|
+
|
|
23
|
+
function fileIfExists(p) {
|
|
24
|
+
try {
|
|
25
|
+
return existsSync(p) && statSync(p).isFile() ? p : null;
|
|
26
|
+
} catch {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function withExtension(base) {
|
|
32
|
+
return fileIfExists(base) ?? EXTENSIONS.map((e) => fileIfExists(base + e)).find(Boolean) ?? EXTENSIONS.map((e) => fileIfExists(path.join(base, "index" + e))).find(Boolean) ?? null;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export async function resolve(specifier, context, next) {
|
|
36
|
+
if (specifier === "server-only" || specifier === "client-only") return { url: EMPTY, shortCircuit: true };
|
|
37
|
+
for (const a of aliases) {
|
|
38
|
+
if (specifier.startsWith(a.prefix)) {
|
|
39
|
+
const rest = specifier.slice(a.prefix.length);
|
|
40
|
+
for (const t of a.targets) {
|
|
41
|
+
const hit = withExtension(t + rest);
|
|
42
|
+
if (hit) return { url: pathToFileURL(hit).href, shortCircuit: true };
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
if ((specifier.startsWith("./") || specifier.startsWith("../")) && context.parentURL?.startsWith("file:")) {
|
|
47
|
+
const hit = withExtension(path.resolve(path.dirname(fileURLToPath(context.parentURL)), specifier));
|
|
48
|
+
if (hit) return { url: pathToFileURL(hit).href, shortCircuit: true };
|
|
49
|
+
}
|
|
50
|
+
return next(specifier, context);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export async function load(url, context, next) {
|
|
54
|
+
if (url.startsWith("file:")) {
|
|
55
|
+
const file = fileURLToPath(url);
|
|
56
|
+
if (/\.(ts|tsx|mts)$/.test(file)) {
|
|
57
|
+
const out = ts.transpileModule(readFileSync(file, "utf8"), {
|
|
58
|
+
fileName: file,
|
|
59
|
+
compilerOptions: { module: ts.ModuleKind.ESNext, target: ts.ScriptTarget.ES2022, jsx: ts.JsxEmit.ReactJSX, esModuleInterop: true },
|
|
60
|
+
});
|
|
61
|
+
return { format: "module", source: out.outputText, shortCircuit: true };
|
|
62
|
+
}
|
|
63
|
+
if (file.endsWith(".json")) {
|
|
64
|
+
return { format: "module", source: `export default ${readFileSync(file, "utf8")};`, shortCircuit: true };
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return next(url, context);
|
|
68
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// Types for wiring-audit.mjs, which stays plain JavaScript so it runs in a site's folder without a build.
|
|
2
|
+
|
|
3
|
+
export type AuditStatus = "wired" | "not_wired" | "missing" | "hard_coded" | "unknown" | "info";
|
|
4
|
+
export type Where = { file: string; line: number };
|
|
5
|
+
export type AuditItem = { area: string; status: AuditStatus; name: string; detail: string; fix: string | null; where: Where[]; more: number };
|
|
6
|
+
export type SiteFile = { rel: string; text: string; lines: string[]; usesKit: boolean };
|
|
7
|
+
export type SiteFiles = { files: SiteFile[]; publicFiles: string[] };
|
|
8
|
+
export type ApiAnswer = { status: number; data: any; meta: any; code: string | null };
|
|
9
|
+
export type Readers = { names: string[]; paths: string[]; imports?: string[] };
|
|
10
|
+
|
|
11
|
+
export const STATUS: Record<AuditStatus, string>;
|
|
12
|
+
export const MODULE_READERS: Record<string, Readers>;
|
|
13
|
+
export const ADMIN_ONLY: Set<string>;
|
|
14
|
+
export function parseEnv(text: string): Record<string, string>;
|
|
15
|
+
export function phonePattern(phone: string | null | undefined): RegExp | null;
|
|
16
|
+
export function literalPattern(value: string): RegExp;
|
|
17
|
+
export function containsPattern(value: string): RegExp;
|
|
18
|
+
export function bareUrl(url: string | null | undefined): string;
|
|
19
|
+
export function fileStem(name: string): string;
|
|
20
|
+
export function keyRefsIn(line: string): string[];
|
|
21
|
+
export function declaredFrom(mod: Record<string, unknown>): Map<string, { label: string; kind: string; image?: string }> | null;
|
|
22
|
+
export function readSite(siteDir: string, opts?: { ignore?: string[]; roots?: string[] }): SiteFiles;
|
|
23
|
+
export function findAll(files: SiteFile[], re: RegExp, filter?: (f: SiteFile) => boolean): Where[];
|
|
24
|
+
export function readsModule(files: SiteFile[], readers: Readers): boolean;
|
|
25
|
+
export function loadDeclaredKeys(siteDir: string, keysFile: string): Promise<{ declared?: Map<string, any>; error?: string }>;
|
|
26
|
+
export function makeApi(base: string, key: string, fetchImpl?: typeof fetch): (path: string) => Promise<ApiAnswer>;
|
|
27
|
+
export function uploadResult(base: string, key: string, result: { items: AuditItem[] }, kitVersion: string, fetchImpl?: typeof fetch): Promise<{ ok: boolean; message: string }>;
|
|
28
|
+
export function audit(input: {
|
|
29
|
+
site: SiteFiles;
|
|
30
|
+
api: (path: string) => Promise<ApiAnswer>;
|
|
31
|
+
declaredResult: { declared?: Map<string, any>; error?: string };
|
|
32
|
+
keysFile: string;
|
|
33
|
+
hasCopyKeysRoute: boolean;
|
|
34
|
+
}): Promise<{ site: { name: string; websiteUrl: string | null; modules: string[] }; items: AuditItem[] }>;
|
|
35
|
+
export function summarize(items: AuditItem[]): { counts: Record<AuditStatus, number>; failed: boolean };
|
|
36
|
+
export function renderReport(result: { site: { name: string }; items: AuditItem[] }, meta: { when: string; host: string; siteId: string; kitVersion: string; all?: boolean }): string;
|
|
37
|
+
export function main(argv: string[]): Promise<number>;
|