kizlo 0.17.0 → 0.19.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/dist/adapters/auth.d.ts +17 -16
- package/dist/adapters/auth.js +4 -5
- package/dist/category/index.js +4 -4
- package/dist/category/schema.d.ts +153 -0
- package/dist/category/schema.js +4 -3
- package/dist/cli/commands/_wiring.js +9 -8
- package/dist/cli/commands/check.js +11 -15
- package/dist/cli/commands/dev.js +3 -3
- package/dist/cli/commands/generate.js +15 -17
- package/dist/cli/commands/test.js +3 -3
- package/dist/cli/daemon/config.js +148 -82
- package/dist/cli/daemon/generate.js +54 -54
- package/dist/cli/daemon/watch.js +41 -54
- package/dist/cli/wp/constants.d.ts +2 -4
- package/dist/cli/wp/constants.js +2 -4
- package/dist/cli/wp/types.d.ts +6 -3
- package/dist/cli/wp/utils.d.ts +3 -3
- package/dist/cli/wp/utils.js +9 -3
- package/dist/comment/errors.js +0 -1
- package/dist/comment/index.js +6 -6
- package/dist/config.d.ts +61 -47
- package/dist/context.d.ts +7 -7
- package/dist/context.js +4 -4
- package/dist/index.d.ts +9 -4
- package/dist/index.js +8 -3
- package/dist/package.js +1 -1
- package/dist/page/index.js +3 -3
- package/dist/page/schema.d.ts +226 -0
- package/dist/page/schema.js +4 -3
- package/dist/post/index.js +3 -3
- package/dist/post/schema.d.ts +268 -0
- package/dist/post/schema.js +4 -3
- package/dist/procedures.d.ts +35 -902
- package/dist/seo/index.js +1 -1
- package/dist/seo/schema.d.ts +5 -5
- package/dist/shared/contract.d.ts +1 -1
- package/dist/shared/procedure.d.ts +12 -3
- package/dist/shared/procedure.js +4 -0
- package/dist/shared/result.d.ts +16 -7
- package/dist/shared/types.d.ts +1 -1
- package/dist/tag/index.js +3 -3
- package/dist/tag/schema.d.ts +151 -0
- package/dist/tag/schema.js +4 -3
- package/dist/test/auth.js +2 -3
- package/dist/test/users.d.ts +2 -4
- package/dist/test/users.js +4 -9
- package/dist/test.d.ts +2 -2
- package/dist/test.js +2 -2
- package/dist/wordpress/endpoint.js +2 -1
- package/dist/wordpress/error.d.ts +1 -0
- package/dist/wordpress/error.js +2 -0
- package/dist/wordpress/fetch-introspection.js +1 -1
- package/dist/wordpress/generate.js +51 -7
- package/dist/wordpress/index.d.ts +1 -1
- package/dist/wordpress/transport.js +5 -3
- package/dist/wordpress/types.d.ts +38 -12
- package/dist/wordpress/utils.d.ts +1 -0
- package/package.json +1 -1
package/dist/cli/daemon/watch.js
CHANGED
|
@@ -2,9 +2,9 @@ import { integrationEnv, resolveWordPressConnection } from "../../kizlo.js";
|
|
|
2
2
|
import { node } from "../../integrations/node/integration.js";
|
|
3
3
|
import { log } from "./logger.js";
|
|
4
4
|
import { loadEnvFiles } from "../utils.js";
|
|
5
|
-
import { resolveConfig
|
|
5
|
+
import { resolveConfig } from "./config.js";
|
|
6
6
|
import { IntrospectionFetchError } from "../../wordpress/fetch-introspection.js";
|
|
7
|
-
import {
|
|
7
|
+
import { generateIntrospectionOnce, generateOnce, reportGenerationError } from "./generate.js";
|
|
8
8
|
import { acquire, lockPath, release } from "./lock.js";
|
|
9
9
|
import path from "node:path";
|
|
10
10
|
import { FSWatcher } from "chokidar";
|
|
@@ -19,51 +19,49 @@ function debounce(fn, delay) {
|
|
|
19
19
|
}
|
|
20
20
|
async function regenerate(cfg, credentials) {
|
|
21
21
|
try {
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
const result = await generateOnce(cfg, { credentials });
|
|
23
|
+
if (result.contract === "built") log.success("Contract updated");
|
|
24
|
+
else if (result.contract === "empty" && cfg.server) log.warn(`No Kizlo server found in ${cfg.server.entry}`);
|
|
24
25
|
} catch (error) {
|
|
25
26
|
reportGenerationError("Failed to update the Kizlo contract:", error);
|
|
26
27
|
}
|
|
27
28
|
}
|
|
28
|
-
/** Watches the server directory and regenerates the contract on change. */
|
|
29
|
-
async function watch(cfg, credentials) {
|
|
29
|
+
/** Watches the server directory and regenerates the contract on change. Only called when a server is present. */
|
|
30
|
+
async function watch(cfg, server, credentials) {
|
|
30
31
|
const watcher = new FSWatcher({
|
|
31
32
|
persistent: true,
|
|
32
33
|
ignoreInitial: true,
|
|
33
|
-
ignored: path.resolve(cfg.cwd,
|
|
34
|
+
ignored: path.resolve(cfg.cwd, server.contractDir)
|
|
34
35
|
});
|
|
35
36
|
const onChange = debounce(() => regenerate(cfg, credentials), 300);
|
|
36
|
-
watcher.add(path.resolve(cfg.cwd,
|
|
37
|
+
watcher.add(path.resolve(cfg.cwd, server.dir));
|
|
37
38
|
watcher.on("all", () => void onChange());
|
|
38
39
|
return watcher;
|
|
39
40
|
}
|
|
40
41
|
/**
|
|
41
|
-
* Report
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
* nothing the first one did not. A failure that reads differently is a different answer and is reported.
|
|
48
|
-
* The state is per reporter rather than per process, so restarting the watcher reports afresh, and one
|
|
49
|
-
* generation failing never silences the other.
|
|
42
|
+
* Report the introspection poll's pass. It carries the last failure it reported, because most of what
|
|
43
|
+
* can fail here cannot clear without the user acting (WordPress down, credentials wrong, a document
|
|
44
|
+
* that will not parse, an introspection version this package does not speak), and repeating the same
|
|
45
|
+
* line every few seconds says nothing the first one did not. A failure that reads differently is a
|
|
46
|
+
* different answer and is reported. The state is per reporter rather than per process, so restarting the
|
|
47
|
+
* watcher reports afresh.
|
|
50
48
|
*/
|
|
51
|
-
function reportGeneration(
|
|
49
|
+
function reportGeneration(stack) {
|
|
52
50
|
let reported;
|
|
53
51
|
return async (run) => {
|
|
54
52
|
try {
|
|
55
|
-
if (await run() === "generated") log.success(
|
|
53
|
+
if (await run() === "generated") log.success("WordPress introspection updated");
|
|
56
54
|
stack?.answered();
|
|
57
55
|
if (reported !== void 0) {
|
|
58
56
|
reported = void 0;
|
|
59
|
-
log.success(
|
|
57
|
+
log.success("Updating the WordPress introspection again");
|
|
60
58
|
}
|
|
61
59
|
} catch (error) {
|
|
62
60
|
if (error instanceof IntrospectionFetchError && error.unreachable && await stack?.ended()) return;
|
|
63
61
|
const message = error instanceof Error ? error.message : String(error);
|
|
64
62
|
if (message === reported) return;
|
|
65
63
|
reported = message;
|
|
66
|
-
reportGenerationError(
|
|
64
|
+
reportGenerationError("Failed to update the WordPress introspection:", error);
|
|
67
65
|
}
|
|
68
66
|
};
|
|
69
67
|
}
|
|
@@ -96,26 +94,20 @@ function endOnStoppedStack(stack, now = Date.now) {
|
|
|
96
94
|
};
|
|
97
95
|
}
|
|
98
96
|
/**
|
|
99
|
-
* One pass of the
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
* Both reporters share one stack guard, so a stopped stack ends the session once rather than once per
|
|
105
|
-
* generation the pass refreshes.
|
|
97
|
+
* One pass of the introspection poll: refetch and rewrite `introspection.ts` when WordPress has changed.
|
|
98
|
+
* A server-backed app and a package that ships only procedures both take this same pass, since each has
|
|
99
|
+
* exactly one introspection to keep current; the plugin's PHP changing is picked up either way. The
|
|
100
|
+
* contract is not refreshed here; the file watcher rebuilds it on a server source change.
|
|
106
101
|
*/
|
|
107
|
-
function createWordPressRefresh(
|
|
108
|
-
const
|
|
109
|
-
const service = reportGeneration("service", guard);
|
|
110
|
-
const client = reportGeneration("client", guard);
|
|
102
|
+
function createWordPressRefresh(cfg, options, stack) {
|
|
103
|
+
const introspection = reportGeneration(stack ? endOnStoppedStack(stack) : void 0);
|
|
111
104
|
return async () => {
|
|
112
|
-
|
|
113
|
-
if (wordpressClientDir) await client(() => generateWorkspaceClientOnce(cwd, wordpressClientDir, options));
|
|
105
|
+
await introspection(() => generateIntrospectionOnce(cfg, options));
|
|
114
106
|
};
|
|
115
107
|
}
|
|
116
108
|
/** Run {@link createWordPressRefresh} on a timer, skipping a tick while the previous one is still going. */
|
|
117
|
-
function refreshWordPress(
|
|
118
|
-
const refresh = createWordPressRefresh(
|
|
109
|
+
function refreshWordPress(cfg, credentials, stack) {
|
|
110
|
+
const refresh = createWordPressRefresh(cfg, { credentials }, stack);
|
|
119
111
|
let refreshing = false;
|
|
120
112
|
const timer = setInterval(() => {
|
|
121
113
|
if (refreshing) return;
|
|
@@ -128,12 +120,11 @@ function refreshWordPress(cwd, cfg, wordpressClientDir, credentials, stack) {
|
|
|
128
120
|
return timer;
|
|
129
121
|
}
|
|
130
122
|
/**
|
|
131
|
-
* Acquire the single-instance lock, generate
|
|
132
|
-
*
|
|
133
|
-
* lock
|
|
134
|
-
*
|
|
135
|
-
*
|
|
136
|
-
* stack and when it runs the watcher alone, so a single terminal covers the whole dev loop.
|
|
123
|
+
* Acquire the single-instance lock, generate once, and start the file watcher. Returns a synchronous
|
|
124
|
+
* `stop()` that closes the watcher and releases the lock, or `undefined` when another watcher already
|
|
125
|
+
* holds the lock (a framework dev script, or a second `kizlo dev`), or when nothing is configured to
|
|
126
|
+
* generate, in which case the caller carries on without watching. Used by `kizlo dev`, both when it
|
|
127
|
+
* boots a local stack and when it runs the watcher alone, so a single terminal covers the whole dev loop.
|
|
137
128
|
*/
|
|
138
129
|
async function startWatcher(cwd, opts) {
|
|
139
130
|
const lock = lockPath(cwd);
|
|
@@ -144,26 +135,22 @@ async function startWatcher(cwd, opts) {
|
|
|
144
135
|
let handedOver = false;
|
|
145
136
|
try {
|
|
146
137
|
const cfg = await resolveConfig(cwd, { dir: opts?.dir });
|
|
147
|
-
|
|
148
|
-
if (!cfg && !wordpressClientDir) {
|
|
138
|
+
if (!cfg) {
|
|
149
139
|
log.info("skipping the contract generation.");
|
|
150
140
|
return;
|
|
151
141
|
}
|
|
152
142
|
loadEnvFiles(cwd);
|
|
153
143
|
const { credentials } = resolveWordPressConnection(void 0, integrationEnv([node()]));
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
if (cfg) try {
|
|
160
|
-
if (await generateOnce(cfg, { credentials })) log.success("Contract generated");
|
|
161
|
-
else log.warn(`No Kizlo server found in ${cfg.serverEntry}`);
|
|
144
|
+
try {
|
|
145
|
+
const result = await generateOnce(cfg, { credentials });
|
|
146
|
+
if (result.contract === "built") log.success("Contract generated");
|
|
147
|
+
else if (result.contract === "empty" && cfg.server) log.warn(`No Kizlo server found in ${cfg.server.entry}`);
|
|
148
|
+
else if (result.introspection === "generated") log.success("WordPress introspection generated");
|
|
162
149
|
} catch (error) {
|
|
163
150
|
reportGenerationError("Failed to generate the Kizlo contract:", error);
|
|
164
151
|
}
|
|
165
|
-
const watcher = cfg ? await watch(cfg, credentials) : void 0;
|
|
166
|
-
const wordpressRefresh = refreshWordPress(
|
|
152
|
+
const watcher = cfg.server ? await watch(cfg, cfg.server, credentials) : void 0;
|
|
153
|
+
const wordpressRefresh = refreshWordPress(cfg, credentials, opts?.stack);
|
|
167
154
|
let stopped = false;
|
|
168
155
|
handedOver = true;
|
|
169
156
|
return () => {
|
|
@@ -34,9 +34,7 @@ declare const CREDENTIALS_REL = ".kizlo/test.json";
|
|
|
34
34
|
* working dir rather than next to the generated files on purpose: it describes one machine's last
|
|
35
35
|
* fetch, so a fresh clone has to regenerate rather than trust a cache it never populated.
|
|
36
36
|
*/
|
|
37
|
-
declare const
|
|
38
|
-
/** Same, for the standalone client written by `wordpressClientDir`. Separate so the two never share one ETag. */
|
|
39
|
-
declare const WORDPRESS_CLIENT_META_REL = ".kizlo/wordpress.client.meta.json";
|
|
37
|
+
declare const INTROSPECTION_META_REL = ".kizlo/introspection.meta.json";
|
|
40
38
|
/**
|
|
41
39
|
* Fixed folder the local WordPress install lives in, relative to the config root. The whole install
|
|
42
40
|
* (core, themes, uploads, plugins) is bind-mounted here; `kizlo dev reset` wipes it. It sits under
|
|
@@ -56,4 +54,4 @@ declare const DEFAULT_PLUGINS: PluginSource[];
|
|
|
56
54
|
declare const TEST_ADMIN: Omit<TestAdminUser, "id" | "applicationPassword">;
|
|
57
55
|
declare const TEST_USER: Omit<TestUser, "id">;
|
|
58
56
|
//#endregion
|
|
59
|
-
export { COMPOSE_FILE, CONFIG_FILES, CREDENTIALS_REL, DEFAULT_PLUGINS, DEFAULT_PORT, DEFAULT_WORDPRESS_TAG, LOCAL_DIR_REL, OPCACHE_INI, REMAP_ENTRYPOINT, SEED_MARKER_OPTION, SEED_VERSION, TEST_ADMIN, TEST_USER,
|
|
57
|
+
export { COMPOSE_FILE, CONFIG_FILES, CREDENTIALS_REL, DEFAULT_PLUGINS, DEFAULT_PORT, DEFAULT_WORDPRESS_TAG, INTROSPECTION_META_REL, LOCAL_DIR_REL, OPCACHE_INI, REMAP_ENTRYPOINT, SEED_MARKER_OPTION, SEED_VERSION, TEST_ADMIN, TEST_USER, githubRelease, kizloRelease };
|
package/dist/cli/wp/constants.js
CHANGED
|
@@ -44,9 +44,7 @@ const CREDENTIALS_REL = ".kizlo/test.json";
|
|
|
44
44
|
* working dir rather than next to the generated files on purpose: it describes one machine's last
|
|
45
45
|
* fetch, so a fresh clone has to regenerate rather than trust a cache it never populated.
|
|
46
46
|
*/
|
|
47
|
-
const
|
|
48
|
-
/** Same, for the standalone client written by `wordpressClientDir`. Separate so the two never share one ETag. */
|
|
49
|
-
const WORDPRESS_CLIENT_META_REL = ".kizlo/wordpress.client.meta.json";
|
|
47
|
+
const INTROSPECTION_META_REL = ".kizlo/introspection.meta.json";
|
|
50
48
|
/**
|
|
51
49
|
* Fixed folder the local WordPress install lives in, relative to the config root. The whole install
|
|
52
50
|
* (core, themes, uploads, plugins) is bind-mounted here; `kizlo dev reset` wipes it. It sits under
|
|
@@ -83,4 +81,4 @@ const TEST_USER = {
|
|
|
83
81
|
};
|
|
84
82
|
|
|
85
83
|
//#endregion
|
|
86
|
-
export { COMPOSE_FILE, CONFIG_FILES, CREDENTIALS_REL, DEFAULT_PLUGINS, DEFAULT_PORT, DEFAULT_WORDPRESS_TAG, LOCAL_DIR_REL, OPCACHE_INI, REMAP_ENTRYPOINT, SEED_MARKER_OPTION, SEED_VERSION, TEST_ADMIN, TEST_USER,
|
|
84
|
+
export { COMPOSE_FILE, CONFIG_FILES, CREDENTIALS_REL, DEFAULT_PLUGINS, DEFAULT_PORT, DEFAULT_WORDPRESS_TAG, INTROSPECTION_META_REL, LOCAL_DIR_REL, OPCACHE_INI, REMAP_ENTRYPOINT, SEED_MARKER_OPTION, SEED_VERSION, TEST_ADMIN, TEST_USER, githubRelease, kizloRelease };
|
package/dist/cli/wp/types.d.ts
CHANGED
|
@@ -53,13 +53,16 @@ interface SeedContext {
|
|
|
53
53
|
/**
|
|
54
54
|
* A plugin to ensure installed + active during bootstrap. A bare string is a
|
|
55
55
|
* wp.org slug (the installed name and the install source are the same). The
|
|
56
|
-
* object form
|
|
57
|
-
* installed slug (`name`, used for activation checks)
|
|
58
|
-
* source.
|
|
56
|
+
* object form names an install source explicitly, either a wp.org slug or a zip
|
|
57
|
+
* URL, when the installed slug (`name`, used for activation checks) cannot be
|
|
58
|
+
* derived from the source or the wp.org release must be pinned. `version` is
|
|
59
|
+
* passed to `wp plugin install --version` when present. `source` is passed
|
|
60
|
+
* straight to `wp plugin install`.
|
|
59
61
|
*/
|
|
60
62
|
type PluginSource = string | {
|
|
61
63
|
name: string;
|
|
62
64
|
source: string;
|
|
65
|
+
version?: string;
|
|
63
66
|
};
|
|
64
67
|
/**
|
|
65
68
|
* A local plugin directory to bind-mount into the dev stack (`kizlo dev`) instead
|
package/dist/cli/wp/utils.d.ts
CHANGED
|
@@ -14,15 +14,15 @@ import { DevPluginSource, Fixture, PluginSource, SettleContext, TestCredentials
|
|
|
14
14
|
* Bumping `SEED_VERSION` invalidates older marks and forces a reseed.
|
|
15
15
|
*/
|
|
16
16
|
declare function isSeeded(): Promise<boolean>;
|
|
17
|
-
/** Resolve a `PluginSource` to the
|
|
18
|
-
declare function resolvePluginSource(plugin: PluginSource): [name: string, source: string];
|
|
17
|
+
/** Resolve a `PluginSource` to the arguments `ensurePlugin` needs. */
|
|
18
|
+
declare function resolvePluginSource(plugin: PluginSource): [name: string, source: string, version?: string];
|
|
19
19
|
/**
|
|
20
20
|
* Ensure a plugin is active without ever re-downloading. Plugin files persist in
|
|
21
21
|
* the `wp_data` volume, so an already-installed plugin is just activated; the
|
|
22
22
|
* download (`source` = release zip URL or wp.org slug) happens only when the files
|
|
23
23
|
* are absent (i.e. after `wp reset` wipes the volume).
|
|
24
24
|
*/
|
|
25
|
-
declare function ensurePlugin(name: string, source: string): Promise<void>;
|
|
25
|
+
declare function ensurePlugin(name: string, source: string, version?: string): Promise<void>;
|
|
26
26
|
/**
|
|
27
27
|
* Activate a bind-mounted local plugin by its directory basename (the slug the
|
|
28
28
|
* mount lands at under `wp-content/plugins`). Idempotent: the files arrive via the
|
package/dist/cli/wp/utils.js
CHANGED
|
@@ -29,9 +29,14 @@ async function isSeeded() {
|
|
|
29
29
|
]);
|
|
30
30
|
return marker.code === 0 && marker.stdout.trim() === SEED_VERSION;
|
|
31
31
|
}
|
|
32
|
-
/** Resolve a `PluginSource` to the
|
|
32
|
+
/** Resolve a `PluginSource` to the arguments `ensurePlugin` needs. */
|
|
33
33
|
function resolvePluginSource(plugin) {
|
|
34
|
-
|
|
34
|
+
if (typeof plugin === "string") return [plugin, plugin];
|
|
35
|
+
return plugin.version === void 0 ? [plugin.name, plugin.source] : [
|
|
36
|
+
plugin.name,
|
|
37
|
+
plugin.source,
|
|
38
|
+
plugin.version
|
|
39
|
+
];
|
|
35
40
|
}
|
|
36
41
|
/**
|
|
37
42
|
* Ensure a plugin is active without ever re-downloading. Plugin files persist in
|
|
@@ -39,7 +44,7 @@ function resolvePluginSource(plugin) {
|
|
|
39
44
|
* download (`source` = release zip URL or wp.org slug) happens only when the files
|
|
40
45
|
* are absent (i.e. after `wp reset` wipes the volume).
|
|
41
46
|
*/
|
|
42
|
-
async function ensurePlugin(name, source) {
|
|
47
|
+
async function ensurePlugin(name, source, version) {
|
|
43
48
|
if ((await compose([
|
|
44
49
|
"exec",
|
|
45
50
|
"-T",
|
|
@@ -69,6 +74,7 @@ async function ensurePlugin(name, source) {
|
|
|
69
74
|
"plugin",
|
|
70
75
|
"install",
|
|
71
76
|
source,
|
|
77
|
+
...version === void 0 ? [] : [`--version=${version}`],
|
|
72
78
|
"--activate"
|
|
73
79
|
]);
|
|
74
80
|
}
|
package/dist/comment/errors.js
CHANGED
package/dist/comment/index.js
CHANGED
|
@@ -98,26 +98,26 @@ const COMMENT_PROCEDURES = {
|
|
|
98
98
|
const connInfo = await context.getConnInfo();
|
|
99
99
|
if (!connInfo?.ip) throw new Error("Connection IP is required.");
|
|
100
100
|
if (!connInfo?.userAgent) throw new Error("Connection user agent is required.");
|
|
101
|
-
const
|
|
102
|
-
if (!
|
|
101
|
+
const session = await context.getSession();
|
|
102
|
+
if (!session) {
|
|
103
103
|
if (!input.body.captchaToken) throw errors.COMMENT_CAPTCHA_REQUIRED();
|
|
104
104
|
if (!await context.verifyCaptcha(input.body.captchaToken)) throw errors.COMMENT_CAPTCHA_INVALID();
|
|
105
105
|
}
|
|
106
|
-
const
|
|
107
|
-
user_id: user?.id,
|
|
106
|
+
const submission = {
|
|
108
107
|
author_ip: connInfo.ip,
|
|
109
108
|
user_agent: connInfo.userAgent,
|
|
110
109
|
content: input.body.content,
|
|
111
110
|
post_id: input.body.postId,
|
|
111
|
+
user_email: session?.email,
|
|
112
112
|
author_email: input.body.authorEmail,
|
|
113
113
|
author_name: input.body.authorName,
|
|
114
114
|
author_url: input.body.authorUrl,
|
|
115
115
|
parent: input.body.parentId
|
|
116
|
-
}
|
|
116
|
+
};
|
|
117
|
+
const response = await context.wordpress.kizlo.comments.create(submission);
|
|
117
118
|
if (response.error) switch (response.error.code) {
|
|
118
119
|
case "require_name_email": throw errors.COMMENT_NAME_EMAIL_REQUIRED();
|
|
119
120
|
case "require_valid_email": throw errors.COMMENT_INVALID_EMAIL();
|
|
120
|
-
case "kizlo_invalid_user": throw errors.COMMENT_USER_NOT_FOUND();
|
|
121
121
|
case "require_valid_comment": throw errors.COMMENT_EMPTY_CONTENT();
|
|
122
122
|
case "not_logged_in": throw errors.COMMENT_LOGIN_REQUIRED();
|
|
123
123
|
case "comment_closed": throw errors.COMMENT_CLOSED();
|
package/dist/config.d.ts
CHANGED
|
@@ -2,14 +2,28 @@ import { Fixture } from "./cli/wp/types.js";
|
|
|
2
2
|
import "./test.js";
|
|
3
3
|
|
|
4
4
|
//#region src/config.d.ts
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Where Kizlo generates, and what it watches. A string is the home directory Kizlo owns the layout
|
|
8
|
+
* under: sources in `<dir>/server`, and the generated files (`contract.json`, the barrel, and
|
|
9
|
+
* `introspection.ts`) under `<dir>/server/generated`. The object form sets each path on its own. Omit
|
|
10
|
+
* `server` and there are no sources to watch and no contract is built, so only the introspection is
|
|
11
|
+
* generated (the shape a package that ships procedures but no server takes).
|
|
12
|
+
*/
|
|
13
|
+
type KizloDir = string | {
|
|
14
|
+
/** Server sources (extensions and procedures). Watched by `kizlo dev`; its presence is what builds a contract. */
|
|
15
|
+
server?: string;
|
|
16
|
+
/** Where `contract.json` and the generated barrel are written. Defaults to `generated/` under `server`. */
|
|
17
|
+
contract?: string;
|
|
18
|
+
/** Where the generated `introspection.ts` is written. Defaults to `generated/` under `server`. */
|
|
19
|
+
introspection?: string;
|
|
20
|
+
};
|
|
5
21
|
interface KizloDevConfig {
|
|
6
22
|
/**
|
|
7
|
-
* Run
|
|
8
|
-
*
|
|
9
|
-
* (for a project pointing at your own WordPress). Set for you by `kizlo create` / `kizlo init`
|
|
10
|
-
* when you choose local WordPress.
|
|
23
|
+
* Run the dev stack. On by default when local WordPress is enabled; set `false` to keep local
|
|
24
|
+
* WordPress on for `kizlo test` while `kizlo dev` runs the contract watcher alone.
|
|
11
25
|
*/
|
|
12
|
-
|
|
26
|
+
enable?: boolean;
|
|
13
27
|
/** Published WP port (default 8080). */
|
|
14
28
|
port?: number;
|
|
15
29
|
/**
|
|
@@ -17,8 +31,8 @@ interface KizloDevConfig {
|
|
|
17
31
|
* Hub: a bare version (`"7.1.0"`), or a full tag (`"7.1.0-php8.3-apache"`) when you need
|
|
18
32
|
* a specific PHP. Defaults to `latest`, so an unconfigured project gets current WordPress.
|
|
19
33
|
*
|
|
20
|
-
* Worth setting once you commit a generated
|
|
21
|
-
* whatever the stack serves: on `latest` that
|
|
34
|
+
* Worth setting once you commit a generated introspection, which is derived from
|
|
35
|
+
* whatever the stack serves: on `latest` that introspection goes stale the day WordPress ships.
|
|
22
36
|
*
|
|
23
37
|
* An existing install keeps the core files it was provisioned with, so changing this
|
|
24
38
|
* takes effect on the next `kizlo dev reset` and Kizlo says so when the two disagree.
|
|
@@ -45,27 +59,24 @@ interface KizloDevConfig {
|
|
|
45
59
|
}
|
|
46
60
|
interface KizloTestConfig {
|
|
47
61
|
/**
|
|
48
|
-
* Run local WordPress
|
|
49
|
-
* WordPress
|
|
50
|
-
|
|
51
|
-
|
|
62
|
+
* Run the test stack. On by default when local WordPress is enabled; set `false` to keep local
|
|
63
|
+
* WordPress on for `kizlo dev` while `kizlo test` just runs the project's own test script.
|
|
64
|
+
*/
|
|
65
|
+
enable?: boolean;
|
|
66
|
+
/**
|
|
67
|
+
* Fall back to the dev stack's `version` and `fixtures` when this stack leaves them unset (default
|
|
68
|
+
* `true`), so the two stacks a local-WordPress project always wants together are declared once.
|
|
69
|
+
* Set `false` to configure the test stack independently, taking Kizlo's defaults where it is silent.
|
|
52
70
|
*/
|
|
53
|
-
|
|
71
|
+
inherit?: boolean;
|
|
54
72
|
/** Published WP port (default 8889). */
|
|
55
73
|
port?: number;
|
|
56
74
|
/**
|
|
57
75
|
* WordPress version the local stack boots, given as the tag after `wordpress:` on Docker
|
|
58
|
-
* Hub
|
|
59
|
-
* a specific PHP. Defaults to `latest`, so an unconfigured project gets current WordPress.
|
|
60
|
-
*
|
|
61
|
-
* Worth setting once you commit a generated WordPress client, which is derived from
|
|
62
|
-
* whatever the stack serves: on `latest` that client goes stale the day WordPress ships.
|
|
63
|
-
*
|
|
64
|
-
* An existing install keeps the core files it was provisioned with, so changing this
|
|
65
|
-
* takes effect on the next `kizlo test reset` and Kizlo says so when the two disagree.
|
|
76
|
+
* Hub. Falls back to the dev stack's `version` unless `inherit` is `false`; defaults to `latest`.
|
|
66
77
|
*/
|
|
67
78
|
version?: string;
|
|
68
|
-
/** Integration fixtures to install + seed. */
|
|
79
|
+
/** Integration fixtures to install + seed. Falls back to the dev stack's `fixtures` unless `inherit` is `false`. */
|
|
69
80
|
fixtures?: Fixture[];
|
|
70
81
|
/**
|
|
71
82
|
* Package manager used to launch the test script (default: auto-detected from
|
|
@@ -78,20 +89,12 @@ interface KizloTestConfig {
|
|
|
78
89
|
*/
|
|
79
90
|
command?: string;
|
|
80
91
|
}
|
|
81
|
-
interface
|
|
82
|
-
/**
|
|
83
|
-
* Kizlo's home directory. Kizlo owns the layout inside it: your server
|
|
84
|
-
* (`server/`, whose `index.ts` exports `procedures` plus your integrations), the
|
|
85
|
-
* browser `client.ts`, and the generated contract.
|
|
86
|
-
* @default 'src/lib/kizlo' (or 'lib/kizlo' without a src dir)
|
|
87
|
-
*/
|
|
88
|
-
dir?: string;
|
|
92
|
+
interface KizloLocalConfig {
|
|
89
93
|
/**
|
|
90
|
-
*
|
|
91
|
-
*
|
|
92
|
-
* again; an empty string (`""`) is the recorded choice to use relative imports.
|
|
94
|
+
* Enable local Docker WordPress (default `true` in this object form). Set `false` to keep the
|
|
95
|
+
* stacks configured but off, the same as omitting `local` entirely.
|
|
93
96
|
*/
|
|
94
|
-
|
|
97
|
+
enable?: boolean;
|
|
95
98
|
/**
|
|
96
99
|
* Base name for the local Docker stacks (`kizlo-<name>-dev`, `kizlo-<name>-test`). Defaults
|
|
97
100
|
* to the sanitized `package.json` name, falling back to the config dir basename.
|
|
@@ -99,8 +102,8 @@ interface KizloGlobalConfig {
|
|
|
99
102
|
name?: string;
|
|
100
103
|
/**
|
|
101
104
|
* Give each branch its own local Docker stacks, by appending the checked-out branch to
|
|
102
|
-
* {@link name} (`kizlo-<name>-<branch>-dev`). Off unless set, since the stacks it
|
|
103
|
-
* are the ones an existing project is already using.
|
|
105
|
+
* {@link KizloLocalConfig.name} (`kizlo-<name>-<branch>-dev`). Off unless set, since the stacks it
|
|
106
|
+
* isolates are the ones an existing project is already using.
|
|
104
107
|
*
|
|
105
108
|
* Turn it on when you work in several checkouts at once, typically git worktrees: without it
|
|
106
109
|
* every checkout of a project resolves to one stack, so parallel `kizlo dev` and `kizlo test`
|
|
@@ -109,20 +112,31 @@ interface KizloGlobalConfig {
|
|
|
109
112
|
* A detached `HEAD` names no branch and keeps the unsuffixed stack.
|
|
110
113
|
*/
|
|
111
114
|
worktrees?: boolean;
|
|
112
|
-
/**
|
|
113
|
-
* Directory to write the WordPress client into, as `<wordpressClientDir>/wordpress.ts`. For a package or
|
|
114
|
-
* workspace that ships procedures but no Kizlo server: there is no procedure tree to build a contract from,
|
|
115
|
-
* yet those procedures still call the generated tree, so they need the client on its own.
|
|
116
|
-
*
|
|
117
|
-
* Independent of `dir`. An app leaves this unset and gets its client inside `dir` alongside the
|
|
118
|
-
* contract; set both only if a project is somehow each of those things at once.
|
|
119
|
-
*/
|
|
120
|
-
wordpressClientDir?: string;
|
|
121
|
-
/** Local WordPress and contract watcher run by `kizlo dev`. */
|
|
115
|
+
/** The dev stack run by `kizlo dev`. */
|
|
122
116
|
dev?: KizloDevConfig;
|
|
123
|
-
/**
|
|
117
|
+
/** The test stack run by `kizlo test`. Inherits `version` and `fixtures` from {@link KizloLocalConfig.dev}. */
|
|
124
118
|
test?: KizloTestConfig;
|
|
125
119
|
}
|
|
120
|
+
interface KizloGlobalConfig {
|
|
121
|
+
/**
|
|
122
|
+
* Where Kizlo generates, and what it watches. A string names the home directory Kizlo owns the
|
|
123
|
+
* layout under; the object form sets the server, contract, and introspection paths independently.
|
|
124
|
+
* @default 'src/lib/kizlo' (or 'lib/kizlo' without a src dir)
|
|
125
|
+
*/
|
|
126
|
+
dir?: KizloDir;
|
|
127
|
+
/**
|
|
128
|
+
* Import alias prefix for generated imports (e.g. `@`). Recorded by `kizlo init`
|
|
129
|
+
* from your `--alias` flag or its prompt, so later runs reuse it instead of asking
|
|
130
|
+
* again; an empty string (`""`) is the recorded choice to use relative imports.
|
|
131
|
+
*/
|
|
132
|
+
alias?: string;
|
|
133
|
+
/**
|
|
134
|
+
* Local Docker WordPress, off unless set. `true` enables both the dev and test stacks with
|
|
135
|
+
* defaults; the object form enables and configures them, and is where the stack name, the
|
|
136
|
+
* per-branch `worktrees` toggle, and the two stacks live.
|
|
137
|
+
*/
|
|
138
|
+
local?: boolean | KizloLocalConfig;
|
|
139
|
+
}
|
|
126
140
|
declare function defineConfig(config: KizloGlobalConfig): KizloGlobalConfig;
|
|
127
141
|
//#endregion
|
|
128
|
-
export { KizloDevConfig, KizloGlobalConfig, KizloTestConfig, defineConfig };
|
|
142
|
+
export { KizloDevConfig, KizloDir, KizloGlobalConfig, KizloLocalConfig, KizloTestConfig, defineConfig };
|
package/dist/context.d.ts
CHANGED
|
@@ -20,7 +20,7 @@ interface ContextConfig {
|
|
|
20
20
|
/** WordPress plugins the registered integrations need, checked against what each response reports. */
|
|
21
21
|
integrationPlugins?: IntegrationPluginRequirement[];
|
|
22
22
|
}
|
|
23
|
-
type
|
|
23
|
+
type SessionFn = () => Promise<AuthUser | null>;
|
|
24
24
|
type ConnInfoFn = () => Promise<ConnInfo | null>;
|
|
25
25
|
type VerifyCaptchaFn = (token: string) => Promise<boolean>;
|
|
26
26
|
type VerifyPreviewTokenFn = (token: string) => Promise<PreviewTokenPayload | null>;
|
|
@@ -46,8 +46,8 @@ interface ProcedureContext {
|
|
|
46
46
|
config: ContextConfig;
|
|
47
47
|
/** Resolve the caller's connection info (IP, geo) via the geo adapter, or `null`. */
|
|
48
48
|
getConnInfo: ConnInfoFn;
|
|
49
|
-
/** Resolve the authenticated
|
|
50
|
-
|
|
49
|
+
/** Resolve the authenticated session via the auth adapter, or `null`. */
|
|
50
|
+
getSession: SessionFn;
|
|
51
51
|
/** Read and write cookies through the cookies adapter. */
|
|
52
52
|
cookies: CookiesStorage;
|
|
53
53
|
/** Verify a CAPTCHA token via the captcha adapter. */
|
|
@@ -84,7 +84,7 @@ declare class Context {
|
|
|
84
84
|
email: EmailService;
|
|
85
85
|
getConnInfo: ConnInfoFn;
|
|
86
86
|
verifyCaptcha: VerifyCaptchaFn;
|
|
87
|
-
|
|
87
|
+
getSession: SessionFn;
|
|
88
88
|
verifyPreviewToken: VerifyPreviewTokenFn;
|
|
89
89
|
cookies: CookiesStorage;
|
|
90
90
|
invokedBy: "client";
|
|
@@ -98,7 +98,7 @@ declare class Context {
|
|
|
98
98
|
wordpress: WordPressTransport;
|
|
99
99
|
settings: SettingsService;
|
|
100
100
|
email: EmailService;
|
|
101
|
-
|
|
101
|
+
getSession: SessionFn;
|
|
102
102
|
getConnInfo: ConnInfoFn;
|
|
103
103
|
verifyCaptcha: VerifyCaptchaFn;
|
|
104
104
|
verifyPreviewToken: VerifyPreviewTokenFn;
|
|
@@ -107,9 +107,9 @@ declare class Context {
|
|
|
107
107
|
private createRestCookieStorage;
|
|
108
108
|
private createVerifyCaptchaFn;
|
|
109
109
|
private createConnInfoFn;
|
|
110
|
-
private
|
|
110
|
+
private createGetSessionFn;
|
|
111
111
|
private createVerifyPreviewTokenFn;
|
|
112
112
|
private createLogger;
|
|
113
113
|
}
|
|
114
114
|
//#endregion
|
|
115
|
-
export {
|
|
115
|
+
export { ConnInfoFn, Context, ContextConfig, ProcedureContext, SessionFn, VerifyCaptchaFn, VerifyPreviewTokenFn };
|
package/dist/context.js
CHANGED
|
@@ -102,7 +102,7 @@ var Context = class {
|
|
|
102
102
|
email: this.email,
|
|
103
103
|
getConnInfo: this.createConnInfoFn(request),
|
|
104
104
|
verifyCaptcha: this.createVerifyCaptchaFn(request),
|
|
105
|
-
|
|
105
|
+
getSession: this.createGetSessionFn(request),
|
|
106
106
|
verifyPreviewToken: this.createVerifyPreviewTokenFn(),
|
|
107
107
|
cookies: this.createRestCookieStorage(request, headers),
|
|
108
108
|
invokedBy: "client"
|
|
@@ -118,7 +118,7 @@ var Context = class {
|
|
|
118
118
|
wordpress: this.wordpress,
|
|
119
119
|
settings: this.settings,
|
|
120
120
|
email: this.email,
|
|
121
|
-
|
|
121
|
+
getSession: this.createGetSessionFn(null),
|
|
122
122
|
getConnInfo: this.createConnInfoFn(null),
|
|
123
123
|
verifyCaptcha: this.createVerifyCaptchaFn(null),
|
|
124
124
|
verifyPreviewToken: this.createVerifyPreviewTokenFn(),
|
|
@@ -176,9 +176,9 @@ var Context = class {
|
|
|
176
176
|
return await this.config.adapters?.geo?.getConnInfo?.(request) ?? null;
|
|
177
177
|
};
|
|
178
178
|
}
|
|
179
|
-
|
|
179
|
+
createGetSessionFn(request) {
|
|
180
180
|
return async () => {
|
|
181
|
-
return await Promise.resolve(this.config.adapters?.auth?.
|
|
181
|
+
return await Promise.resolve(this.config.adapters?.auth?.getSession?.(request)) ?? null;
|
|
182
182
|
};
|
|
183
183
|
}
|
|
184
184
|
createVerifyPreviewTokenFn() {
|