@codepress/blog 0.2.0 → 0.3.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.
- package/README.md +26 -6
- package/dist/chunks/{BlogEditor-EDAPNNP5.js → BlogEditor-IYNL6C7G.js} +166 -219
- package/dist/chunks/chunk-BPAM7T27.js +315 -0
- package/dist/chunks/{chunk-3GCZFCUK.js → chunk-LFSX43CO.js} +14 -3
- package/dist/chunks/{chunk-WJVZD4UI.js → chunk-PPMNLNLD.js} +8 -4
- package/dist/chunks/{chunk-3WRTL63O.js → chunk-WEBQTRDI.js} +10 -7
- package/dist/cli.js +100 -18
- package/dist/editor/BlogEditorMount.d.ts +3 -1
- package/dist/editor/client.d.ts +7 -1
- package/dist/editor/client.js +1 -1
- package/dist/editor/config.d.ts +6 -0
- package/dist/editor/host.d.ts +92 -0
- package/dist/editor/index.d.ts +2 -1
- package/dist/editor/index.js +605 -8
- package/dist/editor.css +3 -0
- package/dist/next/app.d.ts +15 -2
- package/dist/next/config.d.ts +18 -0
- package/dist/next/index.d.ts +1 -1
- package/dist/next/index.js +22 -5
- package/dist/next/pages.d.ts +4 -2
- package/dist/next/pages.js +29 -5
- package/dist/next/routes.js +1 -1
- package/dist/next/views.d.ts +5 -3
- package/package.json +3 -2
- package/dist/chunks/chunk-UA243KAQ.js +0 -104
|
@@ -27,6 +27,8 @@ export interface BlogEditorMountProps {
|
|
|
27
27
|
auth: BlogEditorAuth;
|
|
28
28
|
/** A post that does not exist yet: open the editor straight away. */
|
|
29
29
|
isNew?: boolean;
|
|
30
|
+
/** Open an existing post's editor straight away instead of showing the Edit button. */
|
|
31
|
+
startEditing?: boolean;
|
|
30
32
|
/** The host page's header the toolbar pins below. */
|
|
31
33
|
header?: BlogEditorHeader;
|
|
32
34
|
/** The reading column's classes; defaults to a 720px column. */
|
|
@@ -68,4 +70,4 @@ export declare function appPageUrl(appUrl: string, organizationSlug: string | nu
|
|
|
68
70
|
* the answer is `can_edit`; everyone else gets nothing and never downloads the
|
|
69
71
|
* editor.
|
|
70
72
|
*/
|
|
71
|
-
export declare function BlogEditorMount({ site, slug, apiBase, auth, isNew, header, column, appUrl, timings, onEditingChange, onPublished, onLeave, controller, slots, actions, }: BlogEditorMountProps): import("react/jsx-runtime").JSX.Element | null;
|
|
73
|
+
export declare function BlogEditorMount({ site, slug, apiBase, auth, isNew, startEditing, header, column, appUrl, timings, onEditingChange, onPublished, onLeave, controller, slots, actions, }: BlogEditorMountProps): import("react/jsx-runtime").JSX.Element | null;
|
package/dist/editor/client.d.ts
CHANGED
|
@@ -40,6 +40,8 @@ export interface Capabilities {
|
|
|
40
40
|
/** The org that owns the site and the repo its posts live in; set for editors only. */
|
|
41
41
|
organization_slug?: string | null;
|
|
42
42
|
repository_full_name?: string | null;
|
|
43
|
+
/** Whether the site's organization lets editors edit on the site's own page; reported to anyone. */
|
|
44
|
+
host_editing_enabled?: boolean;
|
|
43
45
|
}
|
|
44
46
|
export type SaveResult = {
|
|
45
47
|
kind: "saved";
|
|
@@ -73,7 +75,11 @@ export interface DraftClient {
|
|
|
73
75
|
} | {
|
|
74
76
|
error: string;
|
|
75
77
|
}>;
|
|
76
|
-
saveDraft(site: string, slug: string, html: string, baseSha: string | null
|
|
78
|
+
saveDraft(site: string, slug: string, html: string, baseSha: string | null,
|
|
79
|
+
/** `keepalive`: the page is going away, so the request must outlive it. */
|
|
80
|
+
options?: {
|
|
81
|
+
keepalive?: boolean;
|
|
82
|
+
}): Promise<SaveResult>;
|
|
77
83
|
publishDraft(site: string, slug: string): Promise<ActionResult>;
|
|
78
84
|
discardDraft(site: string, slug: string): Promise<ActionResult>;
|
|
79
85
|
}
|
package/dist/editor/client.js
CHANGED
package/dist/editor/config.d.ts
CHANGED
|
@@ -22,3 +22,9 @@ export declare const DEFAULT_APP_URL = "https://codepress.dev";
|
|
|
22
22
|
* viewport y of its bottom edge. Floating panels (Ask CodePress) keep below it.
|
|
23
23
|
*/
|
|
24
24
|
export declare const BLOG_TOOLBAR_BOTTOM_VAR = "--blog-toolbar-bottom";
|
|
25
|
+
/**
|
|
26
|
+
* The class every editor root carries (the editor, the Edit button, the
|
|
27
|
+
* loading notice, the new-post form, and the portaled menus and tooltips).
|
|
28
|
+
* `@codepress/blog/editor.css` styles only inside it.
|
|
29
|
+
*/
|
|
30
|
+
export declare const EDITOR_SCOPE_CLASS = "cp-blog-editor";
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Editing a blog on the site's own page. The page never sees a CodePress
|
|
3
|
+
* login: Edit hands off to codepress.dev's consent page with a PKCE
|
|
4
|
+
* challenge, which sends the browser back to the callback route with a
|
|
5
|
+
* one-time code, and the callback trades the code (with the verifier this tab
|
|
6
|
+
* kept) for a site-scoped editor token that lives 30 minutes in this tab's
|
|
7
|
+
* sessionStorage. Nothing renders unless the content site reports host
|
|
8
|
+
* editing enabled.
|
|
9
|
+
*
|
|
10
|
+
* Client-only. In the App Router a `"use client"` file must import these (the
|
|
11
|
+
* file `init` writes), because this entry also exports non-component helpers.
|
|
12
|
+
*/
|
|
13
|
+
import { type ReactNode } from "react";
|
|
14
|
+
import { type BlogEditorTimings } from "./config.js";
|
|
15
|
+
/** The query parameter that opens the editor on a post, or the new-post form on the index. */
|
|
16
|
+
export declare const EDIT_PARAM = "cp-edit";
|
|
17
|
+
/** Where the callback route lives below the blog's base path. */
|
|
18
|
+
export declare const CALLBACK_SEGMENT = "__cp/callback";
|
|
19
|
+
/** The consent page on the CodePress app. */
|
|
20
|
+
export declare const CONSENT_PATH = "/blog-edit/consent";
|
|
21
|
+
/** Page loads this module starts; a test replaces them. */
|
|
22
|
+
export declare const navigation: {
|
|
23
|
+
assign: (url: string) => void;
|
|
24
|
+
replace: (url: string) => void;
|
|
25
|
+
};
|
|
26
|
+
/** How a site's pages reach its CodePress content site. */
|
|
27
|
+
export interface HostEditingConfig {
|
|
28
|
+
/** The content site's slug. */
|
|
29
|
+
site: string;
|
|
30
|
+
/** The CodePress API root, `…/v1`. */
|
|
31
|
+
apiBase: string;
|
|
32
|
+
/** Where the blog is mounted, e.g. `/blog`. */
|
|
33
|
+
basePath: string;
|
|
34
|
+
/** The CodePress app (consent, Ask CodePress, History); defaults to https://codepress.dev. */
|
|
35
|
+
appUrl?: string;
|
|
36
|
+
/** The page's ISR window in seconds, for the note after a publish. */
|
|
37
|
+
revalidate?: number;
|
|
38
|
+
timings?: Partial<BlogEditorTimings>;
|
|
39
|
+
}
|
|
40
|
+
export interface HostEditingProps extends HostEditingConfig {
|
|
41
|
+
/** The post on this page; omitted on the index, which offers New post. */
|
|
42
|
+
slug?: string;
|
|
43
|
+
/** The page as readers see it; hidden while editing. */
|
|
44
|
+
children?: ReactNode;
|
|
45
|
+
}
|
|
46
|
+
interface StoredToken {
|
|
47
|
+
token: string;
|
|
48
|
+
/** Epoch milliseconds. */
|
|
49
|
+
expiresAt: number;
|
|
50
|
+
}
|
|
51
|
+
/** This tab's editor token for `site`, or null when there is none or it has (nearly) expired. */
|
|
52
|
+
export declare function readSiteToken(site: string, now?: number): StoredToken | null;
|
|
53
|
+
export declare function clearSiteToken(site: string): void;
|
|
54
|
+
/** A PKCE verifier: 32 random bytes, base64url (43 characters). */
|
|
55
|
+
export declare function createVerifier(): string;
|
|
56
|
+
/** The S256 challenge of `verifier`. */
|
|
57
|
+
export declare function challengeFor(verifier: string): Promise<string>;
|
|
58
|
+
/** The callback route's path for a blog mounted at `basePath`. */
|
|
59
|
+
export declare function callbackPath(basePath: string): string;
|
|
60
|
+
/**
|
|
61
|
+
* `value` when it is a path on this site below the blog, else the blog's
|
|
62
|
+
* index: the callback never sends the browser anywhere else.
|
|
63
|
+
*/
|
|
64
|
+
export declare function safeReturnPath(basePath: string, value: string | null | undefined): string;
|
|
65
|
+
/** The consent page URL for this page. */
|
|
66
|
+
export declare function consentUrl({ appUrl, site, origin, basePath, challenge, }: {
|
|
67
|
+
appUrl: string;
|
|
68
|
+
site: string;
|
|
69
|
+
origin: string;
|
|
70
|
+
basePath: string;
|
|
71
|
+
challenge: string;
|
|
72
|
+
}): string;
|
|
73
|
+
/** Starts the hand-off: keeps a verifier in this tab, then goes to the consent page. */
|
|
74
|
+
export declare function startHandoff(config: Pick<HostEditingConfig, "site" | "basePath" | "appUrl">, returnTo: string): Promise<void>;
|
|
75
|
+
/** A same-tab, same-origin link click that would leave this page, as an absolute URL. */
|
|
76
|
+
export declare function leavingLinkOf(event: MouseEvent): string | null;
|
|
77
|
+
/**
|
|
78
|
+
* The page's edit mode: an Edit link on a post (New post on the index) when
|
|
79
|
+
* the content site reports host editing enabled; with `?cp-edit` and this
|
|
80
|
+
* tab's site token, the editor over the post; without a token, the consent
|
|
81
|
+
* hand-off. Readers see `children` and nothing else.
|
|
82
|
+
*/
|
|
83
|
+
export declare function HostEditing({ site, apiBase, basePath, appUrl, revalidate, timings, slug, children, }: HostEditingProps): import("react/jsx-runtime").JSX.Element;
|
|
84
|
+
/**
|
|
85
|
+
* The callback route (`<basePath>/__cp/callback`): trades the consent page's
|
|
86
|
+
* code and this tab's verifier for the site token, then returns to the page
|
|
87
|
+
* that started. A declined consent, or a site that does not report host
|
|
88
|
+
* editing enabled, goes back to that page without editing; opened directly
|
|
89
|
+
* on such a site, it renders nothing.
|
|
90
|
+
*/
|
|
91
|
+
export declare function HostEditorCallback({ site, apiBase, basePath, }: HostEditingConfig): import("react/jsx-runtime").JSX.Element | null;
|
|
92
|
+
export {};
|
package/dist/editor/index.d.ts
CHANGED
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
export { BlogEditorMount, appPageUrl, type AskPanelProps, type BlogEditorMountProps, type DesignLinkContext, } from "./BlogEditorMount.js";
|
|
7
7
|
export type { BlogEditorController, BlogEditorControllerRef, } from "./controller.js";
|
|
8
8
|
export { NewPostForm, isValidNewSlug, type NewPostFormProps, } from "./NewPostForm.js";
|
|
9
|
-
export { BLOG_TOOLBAR_BOTTOM_VAR, DEFAULT_TIMINGS, type BlogEditorTimings, } from "./config.js";
|
|
9
|
+
export { BLOG_TOOLBAR_BOTTOM_VAR, DEFAULT_TIMINGS, EDITOR_SCOPE_CLASS, type BlogEditorTimings, } from "./config.js";
|
|
10
10
|
export { DEFAULT_HEADER_SELECTOR, type BlogEditorHeader } from "./header.js";
|
|
11
11
|
export { designUrl, type DesignTarget } from "./EditDesignLink.js";
|
|
12
|
+
export { CALLBACK_SEGMENT, CONSENT_PATH, EDIT_PARAM, HostEditing, HostEditorCallback, callbackPath, challengeFor, clearSiteToken, consentUrl, createVerifier, readSiteToken, safeReturnPath, startHandoff, type HostEditingConfig, type HostEditingProps, } from "./host.js";
|
|
12
13
|
export * from "./client.js";
|