@extenshi/mcp
Version:
Extenshi MCP server — bring the extension catalog (search, security, market research) and pre-publish scanning into your AI tools
127 lines • 4.71 kB
TypeScript
/**
* Schema.org SoftwareApplication JSON-LD for an extension's public site.
*
* Pure and dependency-free on purpose: the landing-page generator
* (./landing-page.ts) embeds it, and that generator ships in three places —
* dojo (through shared-types), the published @extenshi/mcp package and the
* published @extenshi/cli package. Those two cannot import workspace
* shared-types at runtime, so they carry copies of this file:
*
* shared-types/json-ld.ts (canonical — edit here)
* tools/extenshi-mcp/src/json-ld.ts (byte-identical copy)
* tools/extenshi-cli/src/json-ld.ts (byte-identical copy)
*
* `landing-page-sync.test.ts` in each package fails when a copy drifts. After
* editing, run:
* cp shared-types/json-ld.ts tools/extenshi-mcp/src/json-ld.ts
* cp shared-types/json-ld.ts tools/extenshi-cli/src/json-ld.ts
*
* `shared-types/ai-visibility.ts` re-exports everything here, so existing
* `shared-types/ai-visibility.js` imports keep working.
*/
export interface JsonLdInput {
extensionName: string;
description: string;
websiteUrl?: string;
authorName?: string;
chromeUrl?: string;
firefoxUrl?: string;
edgeUrl?: string;
privacyPolicyUrl?: string;
/** Free (default) vs paid. Paid still omits a number — we are not the store. */
offersPrice?: '0' | 'paid';
/**
* Real prices (an Extenshi Pay offer bound to the page). When non-empty they
* replace the free offer: one Offer, or an AggregateOffer for several plans.
*/
paidOffers?: JsonLdPriceInput[];
capabilities?: string[];
/** ISO date; omitted when blank. */
datePublished?: string;
/** Absolute https screenshot URLs; anything else is dropped. */
screenshots?: string[];
}
export interface SoftwareApplicationJsonLd {
'@context': 'https://schema.org';
'@type': 'SoftwareApplication';
name: string;
description?: string;
url?: string;
applicationCategory: 'BrowserApplication';
operatingSystem?: string;
author?: {
'@type': 'Organization';
name: string;
};
offers?: JsonLdOffer | JsonLdAggregateOffer | JsonLdOffer[];
installUrl?: string;
sameAs?: string[];
featureList?: string[];
privacyPolicy?: string;
screenshot?: string[];
}
export interface JsonLdPriceInput {
name?: string;
/** Decimal amount in major units ("4.99"). */
price: string;
/** ISO 4217 code, any case. */
currency: string;
period?: 'month' | 'year' | 'one-time' | 'lifetime';
}
export interface JsonLdOffer {
'@type': 'Offer';
name?: string;
price: string;
priceCurrency: string;
priceSpecification?: {
'@type': 'UnitPriceSpecification';
price: string;
priceCurrency: string;
billingDuration: 'P1M' | 'P1Y';
};
}
export interface JsonLdAggregateOffer {
'@type': 'AggregateOffer';
lowPrice: string;
highPrice: string;
priceCurrency: string;
offerCount: number;
offers: JsonLdOffer[];
}
/**
* Offers for real prices: one Offer, an AggregateOffer when every plan is in
* one currency, else a list. Malformed entries are dropped; null when none is left.
*/
export declare function jsonLdOffers(list: readonly JsonLdPriceInput[]): JsonLdOffer | JsonLdAggregateOffer | JsonLdOffer[] | null;
/**
* Schema.org SoftwareApplication. Only fields we have evidence for are emitted —
* empty author / URL / install links are omitted rather than faked.
*/
export declare function generateJsonLd(input: JsonLdInput): SoftwareApplicationJsonLd;
export declare function generateJsonLdSnippet(input: JsonLdInput): string;
/**
* A `<script type="application/ld+json">` tag safe to drop into HTML.
* `<` is escaped so a description cannot close the script element.
*/
export declare function jsonLdScriptTag(input: JsonLdInput): string;
/** Map a landing-page form onto JSON-LD without a second source of truth. */
export declare function jsonLdFromLanding(input: {
extensionName: string;
tagline: string;
description: string;
storeUrls: Partial<Record<'chrome' | 'firefox' | 'edge', string>>;
features: {
title: string;
description: string;
}[];
privacyPolicyUrl: string;
/** Canonical URL of the landing page itself (JSON-LD `url`). */
homepageUrl?: string;
/** Absolute https screenshot URLs (JSON-LD `screenshot`). */
screenshots?: string[];
/** `paid` drops the free offer when no real price is known. Default free. */
offersPrice?: '0' | 'paid';
/** Prices of the plans the page shows (bound Pay offers). */
paidOffers?: JsonLdPriceInput[];
}): JsonLdInput;
//# sourceMappingURL=json-ld.d.ts.map