kizlo 0.8.2 → 0.8.3
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/cli/commands/_setup.js +10 -6
- package/dist/cli/commands/_wiring.js +116 -0
- package/dist/cli/commands/create.js +114 -48
- package/dist/cli/commands/init.js +9 -82
- package/dist/cli/presets/template.js +28 -12
- package/dist/cli/utils.js +102 -2
- package/dist/package.js +1 -1
- package/dist/router.d.ts +9 -9
- package/dist/seo/schema.d.ts +5 -5
- package/package.json +1 -1
|
@@ -321,11 +321,11 @@ async function syncRemote(conn) {
|
|
|
321
321
|
});
|
|
322
322
|
if (!sync.ok) p.log.warn(`Could not sync the site settings to WordPress (${sync.error}) — make sure the kizlo plugin is active, then set them from the Kizlo settings.`);
|
|
323
323
|
}
|
|
324
|
-
/** The
|
|
325
|
-
function
|
|
326
|
-
|
|
324
|
+
/** The "Next steps" lines, branched on whether a local dev stack was set up. */
|
|
325
|
+
function nextStepsLines(mode, prefix = "") {
|
|
326
|
+
return [
|
|
327
327
|
...mode === "local" ? [
|
|
328
|
-
`Start your local WordPress dev stack
|
|
328
|
+
`Start your local WordPress dev stack:`,
|
|
329
329
|
` ${prefix}npx kizlo dev`,
|
|
330
330
|
``
|
|
331
331
|
] : [
|
|
@@ -335,8 +335,12 @@ function nextStepsNote(mode, prefix = "") {
|
|
|
335
335
|
],
|
|
336
336
|
`Generate the contract once for production builds:`,
|
|
337
337
|
` ${prefix}npx kizlo generate`
|
|
338
|
-
]
|
|
338
|
+
];
|
|
339
|
+
}
|
|
340
|
+
/** The shared "Next steps" note, branched on whether a local dev stack was set up. */
|
|
341
|
+
function nextStepsNote(mode, prefix = "") {
|
|
342
|
+
p.note(nextStepsLines(mode, prefix).join("\n"), "Next steps");
|
|
339
343
|
}
|
|
340
344
|
|
|
341
345
|
//#endregion
|
|
342
|
-
export { collectConnectionFromEnv, collectConnectionInteractively, dirPath, nextStepsNote, orCancel, setupLocalWordPress, syncRemote, validate, withApiPath, writeEnv };
|
|
346
|
+
export { collectConnectionFromEnv, collectConnectionInteractively, dirPath, nextStepsLines, nextStepsNote, orCancel, setupLocalWordPress, syncRemote, validate, withApiPath, writeEnv };
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { resolveModuleImport, writeFileIfAbsent } from "../utils.js";
|
|
2
|
+
import { applyPatchToSource, patchChanged, renderPatchCode } from "../presets/patch.js";
|
|
3
|
+
import { findRootLayout, patchEntries, resolvePatch } from "../presets/template.js";
|
|
4
|
+
import { orCancel } from "./_setup.js";
|
|
5
|
+
import { CONTRACT_BARREL } from "../daemon/generate.js";
|
|
6
|
+
import path from "node:path";
|
|
7
|
+
import fs from "node:fs";
|
|
8
|
+
import * as p from "@clack/prompts";
|
|
9
|
+
|
|
10
|
+
//#region src/cli/commands/_wiring.ts
|
|
11
|
+
/** The kizlo.config.ts a scaffolded project gets: the Kizlo directory, optional import alias, and —
|
|
12
|
+
* for a local dev setup — the WordPress install folder so `kizlo dev` knows where it lives. */
|
|
13
|
+
function kizloConfigTemplate(dir, alias, devPath) {
|
|
14
|
+
return `import { defineConfig } from "kizlo/config"
|
|
15
|
+
|
|
16
|
+
export default defineConfig({
|
|
17
|
+
dir: "${dir}",${alias ? `\n\talias: "${alias}",` : ""}${devPath ? `\n\tdev: { path: "${devPath}" },` : ""}
|
|
18
|
+
})
|
|
19
|
+
`;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Build the {@link ScaffoldContext} that adapts a template's tokenized paths and imports to a real
|
|
23
|
+
* project. `dirRel` is the Kizlo home directory, `appDir` the App Router directory, and `alias` the
|
|
24
|
+
* import-alias prefix (empty for relative imports). The server-entry import is resolved per calling
|
|
25
|
+
* file so each scaffolded file references the server through the right specifier.
|
|
26
|
+
*/
|
|
27
|
+
function buildScaffoldContext(cwd, { dirRel, appDir, alias, clientUrl }) {
|
|
28
|
+
const serverDirRel = path.join(dirRel, "server");
|
|
29
|
+
return {
|
|
30
|
+
kizloDir: dirRel,
|
|
31
|
+
serverDirName: path.basename(serverDirRel),
|
|
32
|
+
serverEntryPath: path.join(serverDirRel, "index.ts"),
|
|
33
|
+
clientPath: path.join(dirRel, "client.ts"),
|
|
34
|
+
appDir,
|
|
35
|
+
serverImport: (fromDir) => resolveModuleImport(cwd, serverDirRel, fromDir, alias),
|
|
36
|
+
clientUrl
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* The single overwrite policy for every scaffolded file: create it when absent, overwrite on
|
|
41
|
+
* `--force`, and otherwise ask before clobbering an existing file (keeping it when the user
|
|
42
|
+
* declines or when running non-interactively with `--yes`). Every scaffolded file routes through
|
|
43
|
+
* here rather than deciding for itself, so new files inherit the same behavior for free.
|
|
44
|
+
*/
|
|
45
|
+
async function scaffoldFile(cwd, file, opts) {
|
|
46
|
+
const absPath = path.join(cwd, file.relPath);
|
|
47
|
+
const existed = fs.existsSync(absPath);
|
|
48
|
+
if (existed) {
|
|
49
|
+
let overwrite = opts.force;
|
|
50
|
+
if (!opts.force && !opts.yes) {
|
|
51
|
+
p.log.warn(`${file.label} already exists at ${file.relPath}`);
|
|
52
|
+
overwrite = orCancel(await p.confirm({
|
|
53
|
+
message: "Overwrite it?",
|
|
54
|
+
initialValue: true
|
|
55
|
+
}));
|
|
56
|
+
}
|
|
57
|
+
if (!overwrite) return "kept";
|
|
58
|
+
}
|
|
59
|
+
fs.mkdirSync(path.dirname(absPath), { recursive: true });
|
|
60
|
+
fs.writeFileSync(absPath, file.contents);
|
|
61
|
+
return existed ? "overwritten" : "created";
|
|
62
|
+
}
|
|
63
|
+
/** Report a {@link scaffoldFile} outcome in the setup commands' usual voice. */
|
|
64
|
+
function reportScaffold(file, result, yes) {
|
|
65
|
+
if (result === "kept") p.log.info(`Kept existing ${file.label} (${file.relPath})${yes ? " — pass --force to overwrite" : ""}`);
|
|
66
|
+
else p.log.success(`${result === "overwritten" ? "Overwrote" : "Created"} ${file.label} (${file.relPath})`);
|
|
67
|
+
}
|
|
68
|
+
/** Seed the generated-contract directory so imports resolve before the first `kizlo watch`/`generate`. */
|
|
69
|
+
function writeGeneratedContract(cwd, serverDirRel) {
|
|
70
|
+
const generatedDirRel = path.join(serverDirRel, "generated");
|
|
71
|
+
writeFileIfAbsent(path.join(cwd, generatedDirRel, "contract.json"), "{}\n");
|
|
72
|
+
writeFileIfAbsent(path.join(cwd, generatedDirRel, "index.ts"), CONTRACT_BARREL);
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Merge Kizlo wiring into files the project already owns (the root layout's SEO exports). Never
|
|
76
|
+
* aborts: the target is resolved by identity (the layout that renders `<html>`), and on any doubt —
|
|
77
|
+
* not found, not parseable — the resolved payload is printed at the end with placement instructions
|
|
78
|
+
* rather than written to a guessed-at file. A confident apply is an idempotent upsert: it replaces
|
|
79
|
+
* our exports if present, adds them if not.
|
|
80
|
+
*/
|
|
81
|
+
function applyLayoutPatches(cwd, manifest, scaffold) {
|
|
82
|
+
const manualSteps = [];
|
|
83
|
+
for (const entry of patchEntries(manifest)) {
|
|
84
|
+
const resolved = resolvePatch(entry, manifest.tokens, scaffold);
|
|
85
|
+
const target = findRootLayout(cwd, scaffold.appDir, resolved.relPath);
|
|
86
|
+
if (!target) {
|
|
87
|
+
manualSteps.push(resolved);
|
|
88
|
+
p.log.info(`Couldn't find your ${resolved.label} to wire Kizlo into — see the code to add below`);
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
const relTarget = path.relative(cwd, target);
|
|
92
|
+
const src = fs.readFileSync(target, "utf8");
|
|
93
|
+
let applied;
|
|
94
|
+
try {
|
|
95
|
+
applied = applyPatchToSource(src, resolved);
|
|
96
|
+
} catch {
|
|
97
|
+
manualSteps.push(resolved);
|
|
98
|
+
p.log.warn(`Couldn't parse your ${resolved.label} (${relTarget}) — see the code to add below`);
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
const { text, changes } = applied;
|
|
102
|
+
if (patchChanged(changes)) {
|
|
103
|
+
fs.writeFileSync(target, text);
|
|
104
|
+
const parts = [
|
|
105
|
+
...changes.replacedExports.length ? [`replaced ${changes.replacedExports.join(", ")}`] : [],
|
|
106
|
+
...changes.addedExports.length ? [`added ${changes.addedExports.join(", ")}`] : [],
|
|
107
|
+
...changes.addedImports.length ? ["imports"] : []
|
|
108
|
+
];
|
|
109
|
+
p.log.success(`Wired Kizlo into your ${resolved.label} (${relTarget}) — ${parts.join(", ")}`);
|
|
110
|
+
} else p.log.info(`Your ${resolved.label} is already wired (${relTarget})`);
|
|
111
|
+
}
|
|
112
|
+
for (const resolved of manualSteps) p.note(renderPatchCode(resolved), `Add these to your ${resolved.label} (the layout that renders <html>)`);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
//#endregion
|
|
116
|
+
export { applyLayoutPatches, buildScaffoldContext, kizloConfigTemplate, reportScaffold, scaffoldFile, writeGeneratedContract };
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { dockerAvailable } from "../wp/docker.js";
|
|
2
|
-
import {
|
|
2
|
+
import { availablePackageManagers, detectInvokingPackageManager, ensureGitignored, frameworkCreateArgs, getVersion, installArgs, runCommandAsync, runCommandCaptured } from "../utils.js";
|
|
3
3
|
import { printBanner } from "../banner.js";
|
|
4
4
|
import { getPreset } from "../presets/index.js";
|
|
5
5
|
import { fetchTemplate } from "../presets/source.js";
|
|
6
|
-
import { readManifest } from "../presets/template.js";
|
|
7
|
-
import { collectConnectionInteractively,
|
|
6
|
+
import { adaptOwnFile, ownEntries, readManifest } from "../presets/template.js";
|
|
7
|
+
import { collectConnectionInteractively, nextStepsLines, orCancel, setupLocalWordPress, syncRemote, validate, withApiPath, writeEnv } from "./_setup.js";
|
|
8
|
+
import { applyLayoutPatches, buildScaffoldContext, kizloConfigTemplate, reportScaffold, scaffoldFile, writeGeneratedContract } from "./_wiring.js";
|
|
8
9
|
import z from "zod/v4";
|
|
9
10
|
import path from "node:path";
|
|
10
11
|
import fs from "node:fs";
|
|
@@ -14,54 +15,77 @@ import * as p from "@clack/prompts";
|
|
|
14
15
|
//#region src/cli/commands/create.ts
|
|
15
16
|
/**
|
|
16
17
|
* The templates `create` can scaffold from. Each id is both the `templates/<id>` folder and the
|
|
17
|
-
* preset that drives its WordPress setup.
|
|
18
|
+
* preset that drives its WordPress setup and framework bootstrap.
|
|
18
19
|
*/
|
|
19
20
|
const TEMPLATES = ["nextjs"];
|
|
20
21
|
function isTemplate(value) {
|
|
21
22
|
return TEMPLATES.includes(value);
|
|
22
23
|
}
|
|
23
24
|
const projectName = validate(z.string().trim().min(1, "Required").refine((value) => !value.startsWith(".") && !value.includes("/") && !value.includes("\\"), "Enter a folder name (letters, numbers, dashes)"));
|
|
24
|
-
/**
|
|
25
|
-
const
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
|
|
31
|
-
]);
|
|
25
|
+
/** Package managers `create` can wire the getting-started steps for, in display order. */
|
|
26
|
+
const PACKAGE_MANAGERS = [
|
|
27
|
+
"pnpm",
|
|
28
|
+
"npm",
|
|
29
|
+
"yarn",
|
|
30
|
+
"bun"
|
|
31
|
+
];
|
|
32
32
|
/**
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
* The template's `template.json` is an internal input, so it's left out of the copy — as is
|
|
38
|
-
* local build junk (`node_modules`, `.next`, …) that only exists on the `KIZLO_TEMPLATE_LOCAL_DIR` path.
|
|
33
|
+
* Pin the `kizlo` dependency in the freshly bootstrapped `package.json`. The template is
|
|
34
|
+
* authoritative for the version (`kizloVersion` in its manifest, stamped at release), falling back to
|
|
35
|
+
* the running CLI's version in-repo before the first stamp. The dependency is only recorded, not
|
|
36
|
+
* installed — the getting-started note tells the user to run install.
|
|
39
37
|
*/
|
|
40
|
-
|
|
41
|
-
const { dir: src, cleanup } = await fetchTemplate(template);
|
|
42
|
-
let kizloVersion;
|
|
43
|
-
try {
|
|
44
|
-
kizloVersion = readManifest(src).kizloVersion ?? `^${getVersion()}`;
|
|
45
|
-
fs.cpSync(src, dir, {
|
|
46
|
-
recursive: true,
|
|
47
|
-
filter: (from) => !SKIP_COPY.has(path.basename(from))
|
|
48
|
-
});
|
|
49
|
-
} finally {
|
|
50
|
-
cleanup();
|
|
51
|
-
}
|
|
38
|
+
function recordKizloDependency(dir, manifest) {
|
|
52
39
|
const pkgPath = path.join(dir, "package.json");
|
|
53
|
-
if (!fs.existsSync(pkgPath)) {
|
|
54
|
-
fs.rmSync(dir, {
|
|
55
|
-
recursive: true,
|
|
56
|
-
force: true
|
|
57
|
-
});
|
|
58
|
-
throw new Error(`Template "${template}" wasn't found. Check the template name and your network connection, then try again.`);
|
|
59
|
-
}
|
|
60
40
|
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
|
|
61
|
-
pkg.
|
|
62
|
-
|
|
41
|
+
pkg.dependencies ??= {};
|
|
42
|
+
pkg.dependencies.kizlo = manifest.kizloVersion ?? `^${getVersion()}`;
|
|
63
43
|
fs.writeFileSync(pkgPath, `${JSON.stringify(pkg, null, " ")}\n`);
|
|
64
44
|
}
|
|
45
|
+
/**
|
|
46
|
+
* The argv `create` runs to bootstrap a fresh base app with the framework's own official CLI, built
|
|
47
|
+
* from the template manifest's `bootstrap` (initializer + flags) — the template is the single source
|
|
48
|
+
* of truth for the framework. The CLI owns only the package-manager mechanics: {@link frameworkCreateArgs}
|
|
49
|
+
* assembles the `<pm> create …` invocation, and the `{{pm}}` token in the flags is substituted with the
|
|
50
|
+
* chosen manager (e.g. `--use-{{pm}}` → `--use-pnpm`).
|
|
51
|
+
*/
|
|
52
|
+
function bootstrapArgs(manifest, pm, name) {
|
|
53
|
+
if (!manifest.bootstrap) return void 0;
|
|
54
|
+
const flags = manifest.bootstrap.flags.map((flag) => flag.replaceAll("{{pm}}", pm));
|
|
55
|
+
return frameworkCreateArgs(pm, manifest.bootstrap.initializer, name, flags);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Layer Kizlo's wiring onto a freshly bootstrapped app in `dir`, from an already-fetched template
|
|
59
|
+
* directory + manifest. The framework CLI has produced the base project (package.json, config,
|
|
60
|
+
* tsconfig, the root layout); this drives the manifest — the same engine `init` uses — to record the
|
|
61
|
+
* `kizlo` dependency, write `kizlo.config.ts`, scaffold the manifest's own files (wiring plus the demo
|
|
62
|
+
* starter pages), seed the generated contract, ignore `.env`, and patch the root layout's SEO exports.
|
|
63
|
+
* The target directory layout comes straight from the manifest tokens, which the bootstrap flags are
|
|
64
|
+
* chosen to match, so files land where the manifest expects. Fresh files are written with `force`,
|
|
65
|
+
* silently replacing the framework defaults.
|
|
66
|
+
*/
|
|
67
|
+
async function applyManifestWiring(dir, templateDir, manifest, opts) {
|
|
68
|
+
const { kizloDir, appDir, alias } = manifest.tokens;
|
|
69
|
+
const scaffold = buildScaffoldContext(dir, {
|
|
70
|
+
dirRel: kizloDir,
|
|
71
|
+
appDir,
|
|
72
|
+
alias,
|
|
73
|
+
clientUrl: void 0
|
|
74
|
+
});
|
|
75
|
+
recordKizloDependency(dir, manifest);
|
|
76
|
+
const files = [{
|
|
77
|
+
label: "Kizlo config",
|
|
78
|
+
relPath: "kizlo.config.ts",
|
|
79
|
+
contents: kizloConfigTemplate(kizloDir, alias, opts.devPath)
|
|
80
|
+
}, ...ownEntries(manifest, { includeStarter: true }).map((entry) => adaptOwnFile(templateDir, entry, manifest.tokens, scaffold))];
|
|
81
|
+
for (const file of files) reportScaffold(file, await scaffoldFile(dir, file, {
|
|
82
|
+
force: true,
|
|
83
|
+
yes: false
|
|
84
|
+
}), false);
|
|
85
|
+
writeGeneratedContract(dir, path.join(kizloDir, "server"));
|
|
86
|
+
ensureGitignored(dir, ".env");
|
|
87
|
+
applyLayoutPatches(dir, manifest, scaffold);
|
|
88
|
+
}
|
|
65
89
|
const create = defineCommand({
|
|
66
90
|
meta: {
|
|
67
91
|
name: "create",
|
|
@@ -120,21 +144,60 @@ const create = defineCommand({
|
|
|
120
144
|
p.cancel(`No preset for template "${template}".`);
|
|
121
145
|
process.exit(1);
|
|
122
146
|
}
|
|
147
|
+
const installed = availablePackageManagers(PACKAGE_MANAGERS);
|
|
148
|
+
const invokingPm = detectInvokingPackageManager();
|
|
149
|
+
const defaultPm = invokingPm && installed.includes(invokingPm) ? invokingPm : installed[0];
|
|
150
|
+
const pm = orCancel(await p.select({
|
|
151
|
+
message: "Package manager",
|
|
152
|
+
options: installed.map((id) => ({
|
|
153
|
+
value: id,
|
|
154
|
+
label: id
|
|
155
|
+
})),
|
|
156
|
+
initialValue: defaultPm
|
|
157
|
+
}));
|
|
123
158
|
const conn = await collectConnectionInteractively(preset);
|
|
124
159
|
if (preset.apiPath && conn.baseUrl) conn.baseUrl = withApiPath(conn.baseUrl, preset.apiPath);
|
|
125
160
|
if (conn.mode === "local" && !await dockerAvailable()) {
|
|
126
161
|
p.cancel("Docker isn't available — start Docker (or install it) and re-run, or choose “Use my own WordPress”.");
|
|
127
162
|
process.exit(1);
|
|
128
163
|
}
|
|
164
|
+
const fetched = await fetchTemplate(template);
|
|
165
|
+
const fail = (message) => {
|
|
166
|
+
fetched.cleanup();
|
|
167
|
+
p.cancel(message);
|
|
168
|
+
process.exit(1);
|
|
169
|
+
};
|
|
170
|
+
const manifest = readManifest(fetched.dir);
|
|
171
|
+
const bootstrap = bootstrapArgs(manifest, pm, name);
|
|
172
|
+
if (!bootstrap) {
|
|
173
|
+
fetched.cleanup();
|
|
174
|
+
p.cancel(`Template "${template}" can't be scaffolded — its manifest declares no framework bootstrap.`);
|
|
175
|
+
process.exit(1);
|
|
176
|
+
}
|
|
129
177
|
const s = p.spinner();
|
|
130
|
-
s.start(`Creating ${name}
|
|
178
|
+
s.start(`Creating ${name} with the ${preset.label} CLI`);
|
|
179
|
+
const scaffold = runCommandCaptured(bootstrap, cwd);
|
|
180
|
+
s.stop(scaffold.ok ? `Created ${name} with the ${preset.label} CLI` : `${preset.label} setup failed`);
|
|
181
|
+
if (!scaffold.ok) {
|
|
182
|
+
if (scaffold.output) p.log.error(scaffold.output);
|
|
183
|
+
fail(`${preset.label} setup failed — see the output above and try again.`);
|
|
184
|
+
}
|
|
131
185
|
try {
|
|
132
|
-
await
|
|
133
|
-
s.stop(`Created ${name}`);
|
|
186
|
+
await applyManifestWiring(dir, fetched.dir, manifest, { devPath: conn.devPath });
|
|
134
187
|
} catch (error) {
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
188
|
+
fail(error instanceof Error ? error.message : String(error));
|
|
189
|
+
}
|
|
190
|
+
fetched.cleanup();
|
|
191
|
+
let depsInstalled = false;
|
|
192
|
+
if (orCancel(await p.confirm({
|
|
193
|
+
message: "Install dependencies now?",
|
|
194
|
+
initialValue: true
|
|
195
|
+
}))) {
|
|
196
|
+
const is = p.spinner();
|
|
197
|
+
is.start(`Installing dependencies with ${pm}`);
|
|
198
|
+
depsInstalled = await runCommandAsync(installArgs(pm), dir, "ignore");
|
|
199
|
+
is.stop(depsInstalled ? "Installed dependencies" : "Could not install dependencies");
|
|
200
|
+
if (!depsInstalled) p.log.warn(`Install them yourself: cd ${name} && ${installArgs(pm).join(" ")}`);
|
|
138
201
|
}
|
|
139
202
|
await setupLocalWordPress(dir, conn);
|
|
140
203
|
await writeEnv(dir, preset, conn, {
|
|
@@ -142,9 +205,12 @@ const create = defineCommand({
|
|
|
142
205
|
yes: false
|
|
143
206
|
});
|
|
144
207
|
await syncRemote(conn);
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
208
|
+
p.note([
|
|
209
|
+
`cd ${name}`,
|
|
210
|
+
...depsInstalled ? [] : [`${pm} install`],
|
|
211
|
+
``,
|
|
212
|
+
...nextStepsLines(conn.mode)
|
|
213
|
+
].join("\n"), "Next steps");
|
|
148
214
|
p.outro("Kizlo is ready 🎉");
|
|
149
215
|
}
|
|
150
216
|
});
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import { dockerAvailable } from "../wp/docker.js";
|
|
2
|
-
import { addDependencyArgs, detectImportAlias, detectPackageManager, ensureGitignored, getVersion, loadEnvFiles,
|
|
2
|
+
import { addDependencyArgs, detectImportAlias, detectPackageManager, ensureGitignored, getVersion, loadEnvFiles, runCommand } from "../utils.js";
|
|
3
3
|
import { printBanner } from "../banner.js";
|
|
4
4
|
import { PRESETS, detectPreset, getPreset } from "../presets/index.js";
|
|
5
5
|
import { fetchTemplate } from "../presets/source.js";
|
|
6
|
-
import {
|
|
7
|
-
import { adaptOwnFile, findRootLayout, ownEntries, patchEntries, readManifest, resolvePatch } from "../presets/template.js";
|
|
6
|
+
import { adaptOwnFile, ownEntries, readManifest } from "../presets/template.js";
|
|
8
7
|
import { collectConnectionFromEnv, collectConnectionInteractively, dirPath, nextStepsNote, orCancel, setupLocalWordPress, syncRemote, validate, withApiPath, writeEnv } from "./_setup.js";
|
|
9
|
-
import {
|
|
8
|
+
import { applyLayoutPatches, buildScaffoldContext, kizloConfigTemplate, reportScaffold, scaffoldFile, writeGeneratedContract } from "./_wiring.js";
|
|
10
9
|
import path from "node:path";
|
|
11
10
|
import fs from "node:fs";
|
|
12
11
|
import { defineCommand } from "citty";
|
|
@@ -20,14 +19,6 @@ function defaultDir(hasSrcDir) {
|
|
|
20
19
|
function aliasWithSlash(alias) {
|
|
21
20
|
return alias ? `${alias.replace(/\/+$/, "")}/` : "";
|
|
22
21
|
}
|
|
23
|
-
function kizloConfigTemplate(dir, alias, devPath) {
|
|
24
|
-
return `import { defineConfig } from "kizlo/config"
|
|
25
|
-
|
|
26
|
-
export default defineConfig({
|
|
27
|
-
dir: "${dir}",${alias ? `\n\talias: "${alias}",` : ""}${devPath ? `\n\tdev: { path: "${devPath}" },` : ""}
|
|
28
|
-
})
|
|
29
|
-
`;
|
|
30
|
-
}
|
|
31
22
|
/** Whether two URLs share an origin (scheme + host + port); false when either can't be parsed. */
|
|
32
23
|
function sameOrigin(a, b) {
|
|
33
24
|
try {
|
|
@@ -41,35 +32,6 @@ function detectAppDir(cwd, hasSrcDir) {
|
|
|
41
32
|
if (fs.existsSync(path.join(cwd, "app"))) return "app";
|
|
42
33
|
return hasSrcDir ? "src/app" : "app";
|
|
43
34
|
}
|
|
44
|
-
/**
|
|
45
|
-
* The single overwrite policy for every scaffolded file: create it when absent, overwrite on
|
|
46
|
-
* `--force`, and otherwise ask before clobbering an existing file (keeping it when the user
|
|
47
|
-
* declines or when running non-interactively with `--yes`). Every scaffolded file routes through
|
|
48
|
-
* here rather than deciding for itself, so new files inherit the same behavior for free.
|
|
49
|
-
*/
|
|
50
|
-
async function scaffoldFile(cwd, file, opts) {
|
|
51
|
-
const absPath = path.join(cwd, file.relPath);
|
|
52
|
-
const existed = fs.existsSync(absPath);
|
|
53
|
-
if (existed) {
|
|
54
|
-
let overwrite = opts.force;
|
|
55
|
-
if (!opts.force && !opts.yes) {
|
|
56
|
-
p.log.warn(`${file.label} already exists at ${file.relPath}`);
|
|
57
|
-
overwrite = orCancel(await p.confirm({
|
|
58
|
-
message: "Overwrite it?",
|
|
59
|
-
initialValue: true
|
|
60
|
-
}));
|
|
61
|
-
}
|
|
62
|
-
if (!overwrite) return "kept";
|
|
63
|
-
}
|
|
64
|
-
fs.mkdirSync(path.dirname(absPath), { recursive: true });
|
|
65
|
-
fs.writeFileSync(absPath, file.contents);
|
|
66
|
-
return existed ? "overwritten" : "created";
|
|
67
|
-
}
|
|
68
|
-
/** Report a {@link scaffoldFile} outcome in init's usual voice. */
|
|
69
|
-
function reportScaffold(file, result, yes) {
|
|
70
|
-
if (result === "kept") p.log.info(`Kept existing ${file.label} (${file.relPath})${yes ? " — pass --force to overwrite" : ""}`);
|
|
71
|
-
else p.log.success(`${result === "overwritten" ? "Overwrote" : "Created"} ${file.label} (${file.relPath})`);
|
|
72
|
-
}
|
|
73
35
|
async function collectInteractively(ctx) {
|
|
74
36
|
const conn = await collectConnectionInteractively(ctx.preset);
|
|
75
37
|
const dir = orCancel(await p.text({
|
|
@@ -243,15 +205,12 @@ const init = defineCommand({
|
|
|
243
205
|
const dirRel = setup.dir.replace(/^\.\//, "").replace(/\/+$/, "");
|
|
244
206
|
const serverDirRel = path.join(dirRel, "server");
|
|
245
207
|
const clientUrl = setup.siteUrl && !sameOrigin(setup.siteUrl, setup.baseUrl) ? setup.baseUrl : void 0;
|
|
246
|
-
const scaffold = {
|
|
247
|
-
|
|
248
|
-
serverDirName: path.basename(serverDirRel),
|
|
249
|
-
serverEntryPath: path.join(serverDirRel, "index.ts"),
|
|
250
|
-
clientPath: path.join(dirRel, "client.ts"),
|
|
208
|
+
const scaffold = buildScaffoldContext(cwd, {
|
|
209
|
+
dirRel,
|
|
251
210
|
appDir: detectAppDir(cwd, hasSrcDir),
|
|
252
|
-
|
|
211
|
+
alias: setup.alias,
|
|
253
212
|
clientUrl
|
|
254
|
-
};
|
|
213
|
+
});
|
|
255
214
|
const files = [{
|
|
256
215
|
label: "Kizlo config",
|
|
257
216
|
relPath: "kizlo.config.ts",
|
|
@@ -276,42 +235,10 @@ const init = defineCommand({
|
|
|
276
235
|
yes
|
|
277
236
|
})
|
|
278
237
|
});
|
|
279
|
-
|
|
280
|
-
writeFileIfAbsent(path.join(cwd, generatedDirRel, "contract.json"), "{}\n");
|
|
281
|
-
writeFileIfAbsent(path.join(cwd, generatedDirRel, "index.ts"), CONTRACT_BARREL);
|
|
238
|
+
writeGeneratedContract(cwd, serverDirRel);
|
|
282
239
|
const gitignore = ensureGitignored(cwd, ".env");
|
|
283
240
|
for (const { file, result } of scaffolded) reportScaffold(file, result, yes);
|
|
284
|
-
|
|
285
|
-
for (const entry of manifest ? patchEntries(manifest) : []) {
|
|
286
|
-
const resolved = resolvePatch(entry, manifest.tokens, scaffold);
|
|
287
|
-
const target = findRootLayout(cwd, scaffold.appDir, resolved.relPath);
|
|
288
|
-
if (!target) {
|
|
289
|
-
manualSteps.push(resolved);
|
|
290
|
-
p.log.info(`Couldn't find your ${resolved.label} to wire Kizlo into — see the code to add below`);
|
|
291
|
-
continue;
|
|
292
|
-
}
|
|
293
|
-
const relTarget = path.relative(cwd, target);
|
|
294
|
-
const src = fs.readFileSync(target, "utf8");
|
|
295
|
-
let applied;
|
|
296
|
-
try {
|
|
297
|
-
applied = applyPatchToSource(src, resolved);
|
|
298
|
-
} catch {
|
|
299
|
-
manualSteps.push(resolved);
|
|
300
|
-
p.log.warn(`Couldn't parse your ${resolved.label} (${relTarget}) — see the code to add below`);
|
|
301
|
-
continue;
|
|
302
|
-
}
|
|
303
|
-
const { text, changes } = applied;
|
|
304
|
-
if (patchChanged(changes)) {
|
|
305
|
-
fs.writeFileSync(target, text);
|
|
306
|
-
const parts = [
|
|
307
|
-
...changes.replacedExports.length ? [`replaced ${changes.replacedExports.join(", ")}`] : [],
|
|
308
|
-
...changes.addedExports.length ? [`added ${changes.addedExports.join(", ")}`] : [],
|
|
309
|
-
...changes.addedImports.length ? ["imports"] : []
|
|
310
|
-
];
|
|
311
|
-
p.log.success(`Wired Kizlo into your ${resolved.label} (${relTarget}) — ${parts.join(", ")}`);
|
|
312
|
-
} else p.log.info(`Your ${resolved.label} is already wired (${relTarget})`);
|
|
313
|
-
}
|
|
314
|
-
for (const resolved of manualSteps) p.note(renderPatchCode(resolved), `Add these to your ${resolved.label} (the layout that renders <html>)`);
|
|
241
|
+
if (manifest) applyLayoutPatches(cwd, manifest, scaffold);
|
|
315
242
|
if (gitignore !== "present") p.log.success(`${gitignore === "created" ? "Created" : "Updated"} .gitignore (ignoring .env)`);
|
|
316
243
|
nextStepsNote(setup.mode);
|
|
317
244
|
p.outro("Kizlo is ready 🎉");
|
|
@@ -5,15 +5,17 @@ import fs from "node:fs";
|
|
|
5
5
|
|
|
6
6
|
//#region src/cli/presets/template.ts
|
|
7
7
|
/**
|
|
8
|
-
* The template's `template.json`. It is the single declaration of which files
|
|
9
|
-
* and how each is applied
|
|
10
|
-
*
|
|
8
|
+
* The template's `template.json`. It is the single declaration of which files Kizlo lays onto a
|
|
9
|
+
* project and how each is applied — the same engine drives both `create` (onto a fresh app the
|
|
10
|
+
* framework CLI just bootstrapped) and `init` (onto the user's existing project). Every entry is one
|
|
11
|
+
* of a small closed set — deliberately no "patch an arbitrary source file" kind, so a dangerous
|
|
12
|
+
* strategy is unrepresentable:
|
|
11
13
|
*
|
|
12
|
-
* - `own` — a whole file Kizlo writes
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
14
|
+
* - `own` — a whole file Kizlo writes, adapted to the project's directories and written through the
|
|
15
|
+
* overwrite policy. `wiring`-scope files (the default) are laid down by both commands; `starter`
|
|
16
|
+
* demo files are laid down only by `create` (see {@link ownEntries}).
|
|
17
|
+
* - `patch` — a partial injection into a file the framework owns (the root layout's SEO exports).
|
|
18
|
+
* Both commands try a confident apply, otherwise print the payload with placement instructions.
|
|
17
19
|
*/
|
|
18
20
|
const tokensSchema = z.object({
|
|
19
21
|
kizloDir: z.string(),
|
|
@@ -23,7 +25,8 @@ const tokensSchema = z.object({
|
|
|
23
25
|
const ownSchema = z.object({
|
|
24
26
|
kind: z.literal("own"),
|
|
25
27
|
role: z.string(),
|
|
26
|
-
path: z.string()
|
|
28
|
+
path: z.string(),
|
|
29
|
+
scope: z.enum(["wiring", "starter"]).optional()
|
|
27
30
|
});
|
|
28
31
|
const patchSchema = z.object({
|
|
29
32
|
kind: z.literal("patch"),
|
|
@@ -39,9 +42,14 @@ const patchSchema = z.object({
|
|
|
39
42
|
value: z.string()
|
|
40
43
|
}))
|
|
41
44
|
});
|
|
45
|
+
const bootstrapSchema = z.object({
|
|
46
|
+
initializer: z.string(),
|
|
47
|
+
flags: z.array(z.string()).default([])
|
|
48
|
+
});
|
|
42
49
|
const manifestSchema = z.object({
|
|
43
50
|
framework: z.string(),
|
|
44
51
|
kizloVersion: z.string().optional(),
|
|
52
|
+
bootstrap: bootstrapSchema.optional(),
|
|
45
53
|
tokens: tokensSchema,
|
|
46
54
|
files: z.array(z.discriminatedUnion("kind", [ownSchema, patchSchema]))
|
|
47
55
|
});
|
|
@@ -53,7 +61,10 @@ const ROLE_LABELS = {
|
|
|
53
61
|
robots: "robots.txt route",
|
|
54
62
|
sitemap: "sitemap route",
|
|
55
63
|
"sitemap-redirect": "sitemap.xml redirect route",
|
|
56
|
-
manifest: "web manifest route"
|
|
64
|
+
manifest: "web manifest route",
|
|
65
|
+
"home-page": "home page",
|
|
66
|
+
"blog-post": "blog post page",
|
|
67
|
+
styles: "global styles"
|
|
57
68
|
};
|
|
58
69
|
/** Read and validate the template's manifest from a fetched template directory. */
|
|
59
70
|
function readManifest(templateDir) {
|
|
@@ -61,8 +72,13 @@ function readManifest(templateDir) {
|
|
|
61
72
|
if (!fs.existsSync(manifestPath)) throw new Error(`Template manifest not found at ${manifestPath}`);
|
|
62
73
|
return manifestSchema.parse(JSON.parse(fs.readFileSync(manifestPath, "utf8")));
|
|
63
74
|
}
|
|
64
|
-
|
|
65
|
-
|
|
75
|
+
/**
|
|
76
|
+
* The `own` files to scaffold. By default only `wiring` files (the Kizlo plumbing) — this is what
|
|
77
|
+
* `init` lays onto an existing project, so it never touches the user's own pages. With
|
|
78
|
+
* `includeStarter`, demo `starter` files are added too, which is what `create` lays onto a fresh app.
|
|
79
|
+
*/
|
|
80
|
+
function ownEntries(manifest, opts = {}) {
|
|
81
|
+
return manifest.files.filter((file) => file.kind === "own" && (opts.includeStarter || file.scope !== "starter"));
|
|
66
82
|
}
|
|
67
83
|
function patchEntries(manifest) {
|
|
68
84
|
return manifest.files.filter((file) => file.kind === "patch");
|
package/dist/cli/utils.js
CHANGED
|
@@ -2,7 +2,7 @@ import { log } from "./daemon/logger.js";
|
|
|
2
2
|
import { PortInUseError, resolveHostPort } from "./wp/ports.js";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
|
-
import { spawnSync } from "node:child_process";
|
|
5
|
+
import { spawn, spawnSync } from "node:child_process";
|
|
6
6
|
import fs from "node:fs";
|
|
7
7
|
import * as p from "@clack/prompts";
|
|
8
8
|
|
|
@@ -107,6 +107,31 @@ function detectPackageManager(cwd) {
|
|
|
107
107
|
if (fs.existsSync(path.join(cwd, "bun.lockb")) || fs.existsSync(path.join(cwd, "bun.lock"))) return "bun";
|
|
108
108
|
return "npm";
|
|
109
109
|
}
|
|
110
|
+
/**
|
|
111
|
+
* The package manager that invoked the current process, read from `npm_config_user_agent`
|
|
112
|
+
* (e.g. `pnpm/9.0.0 npm/? node/v20`). Used to pre-select the most likely choice when a fresh
|
|
113
|
+
* project has no lockfile to detect from. Returns undefined when the agent is absent or unknown.
|
|
114
|
+
*/
|
|
115
|
+
function detectInvokingPackageManager() {
|
|
116
|
+
const name = process.env.npm_config_user_agent?.split("/")[0];
|
|
117
|
+
return name === "pnpm" || name === "yarn" || name === "bun" || name === "npm" ? name : void 0;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Whether `command` resolves to a runnable executable, probed with `--version`. Used to hide or
|
|
121
|
+
* disable package-manager choices the user can't actually run. A non-zero exit or a spawn error
|
|
122
|
+
* (the binary isn't on PATH) both count as unavailable.
|
|
123
|
+
*/
|
|
124
|
+
function isCommandAvailable(command) {
|
|
125
|
+
const result = spawnSync(command, ["--version"], {
|
|
126
|
+
stdio: "ignore",
|
|
127
|
+
shell: process.platform === "win32"
|
|
128
|
+
});
|
|
129
|
+
return !result.error && result.status === 0;
|
|
130
|
+
}
|
|
131
|
+
/** The package managers currently installed on the host, in the given display order. */
|
|
132
|
+
function availablePackageManagers(order) {
|
|
133
|
+
return order.filter((pm) => isCommandAvailable(pm));
|
|
134
|
+
}
|
|
110
135
|
function addDependencyArgs(pm, pkg) {
|
|
111
136
|
if (pm === "npm") return [
|
|
112
137
|
"npm",
|
|
@@ -119,6 +144,42 @@ function addDependencyArgs(pm, pkg) {
|
|
|
119
144
|
pkg
|
|
120
145
|
];
|
|
121
146
|
}
|
|
147
|
+
/** The argv to install a project's dependencies with `pm` — every supported manager spells it `<pm> install`. */
|
|
148
|
+
function installArgs(pm) {
|
|
149
|
+
return [pm, "install"];
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* The argv to run a framework's `create-*` initializer through a package manager, e.g.
|
|
153
|
+
* `pnpm create next-app@latest my-app --ts …`. The mechanics differ per manager: npm forwards
|
|
154
|
+
* flags to the initializer only after a `--` separator, and `yarn create` resolves the latest
|
|
155
|
+
* version itself so the `@latest` tag is dropped. `flags` are the initializer's own options.
|
|
156
|
+
*/
|
|
157
|
+
function frameworkCreateArgs(pm, initializer, name, flags) {
|
|
158
|
+
switch (pm) {
|
|
159
|
+
case "npm": return [
|
|
160
|
+
"npm",
|
|
161
|
+
"create",
|
|
162
|
+
initializer,
|
|
163
|
+
name,
|
|
164
|
+
"--",
|
|
165
|
+
...flags
|
|
166
|
+
];
|
|
167
|
+
case "yarn": return [
|
|
168
|
+
"yarn",
|
|
169
|
+
"create",
|
|
170
|
+
initializer.replace(/@latest$/, ""),
|
|
171
|
+
name,
|
|
172
|
+
...flags
|
|
173
|
+
];
|
|
174
|
+
default: return [
|
|
175
|
+
pm,
|
|
176
|
+
"create",
|
|
177
|
+
initializer,
|
|
178
|
+
name,
|
|
179
|
+
...flags
|
|
180
|
+
];
|
|
181
|
+
}
|
|
182
|
+
}
|
|
122
183
|
function runCommand(args, cwd, stdio = "inherit") {
|
|
123
184
|
const [command, ...rest] = args;
|
|
124
185
|
if (!command) return false;
|
|
@@ -128,6 +189,45 @@ function runCommand(args, cwd, stdio = "inherit") {
|
|
|
128
189
|
shell: process.platform === "win32"
|
|
129
190
|
}).status === 0;
|
|
130
191
|
}
|
|
192
|
+
/**
|
|
193
|
+
* Async sibling of {@link runCommand}: runs a command without blocking the event loop, so a clack
|
|
194
|
+
* spinner can keep animating while it works (a synchronous `spawnSync` would freeze it on the first
|
|
195
|
+
* frame). Resolves whether it exited cleanly; a spawn error (binary off PATH) resolves false.
|
|
196
|
+
*/
|
|
197
|
+
function runCommandAsync(args, cwd, stdio = "inherit") {
|
|
198
|
+
const [command, ...rest] = args;
|
|
199
|
+
if (!command) return Promise.resolve(false);
|
|
200
|
+
return new Promise((resolve$1) => {
|
|
201
|
+
const child = spawn(command, rest, {
|
|
202
|
+
cwd,
|
|
203
|
+
stdio,
|
|
204
|
+
shell: process.platform === "win32"
|
|
205
|
+
});
|
|
206
|
+
child.on("error", () => resolve$1(false));
|
|
207
|
+
child.on("close", (code) => resolve$1(code === 0));
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Run a command capturing its combined output instead of streaming it, for a step that should stay
|
|
212
|
+
* quiet on success but whose logs are worth surfacing when it fails (e.g. the framework's scaffolder
|
|
213
|
+
* behind a spinner). Returns whether it succeeded and the trimmed stdout+stderr.
|
|
214
|
+
*/
|
|
215
|
+
function runCommandCaptured(args, cwd) {
|
|
216
|
+
const [command, ...rest] = args;
|
|
217
|
+
if (!command) return {
|
|
218
|
+
ok: false,
|
|
219
|
+
output: ""
|
|
220
|
+
};
|
|
221
|
+
const result = spawnSync(command, rest, {
|
|
222
|
+
cwd,
|
|
223
|
+
encoding: "utf8",
|
|
224
|
+
shell: process.platform === "win32"
|
|
225
|
+
});
|
|
226
|
+
return {
|
|
227
|
+
ok: result.status === 0,
|
|
228
|
+
output: `${result.stdout ?? ""}${result.stderr ?? ""}`.trim()
|
|
229
|
+
};
|
|
230
|
+
}
|
|
131
231
|
function writeFileIfAbsent(filePath, contents) {
|
|
132
232
|
if (fs.existsSync(filePath)) return false;
|
|
133
233
|
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
@@ -263,4 +363,4 @@ function groupDefault(subCommandNames, run) {
|
|
|
263
363
|
}
|
|
264
364
|
|
|
265
365
|
//#endregion
|
|
266
|
-
export { addDependencyArgs, detectImportAlias, detectPackageManager, ensureGitignored, envGroups, envKeysPresent, getVersion, groupDefault, loadEnvFiles, mergeEnv, pickStackPort, resolveModuleImport, runCommand, withSpinner, writeFileIfAbsent };
|
|
366
|
+
export { addDependencyArgs, availablePackageManagers, detectImportAlias, detectInvokingPackageManager, detectPackageManager, ensureGitignored, envGroups, envKeysPresent, frameworkCreateArgs, getVersion, groupDefault, installArgs, loadEnvFiles, mergeEnv, pickStackPort, resolveModuleImport, runCommand, runCommandAsync, runCommandCaptured, withSpinner, writeFileIfAbsent };
|
package/dist/package.js
CHANGED
package/dist/router.d.ts
CHANGED
|
@@ -179,7 +179,7 @@ declare const ROUTER_MAP: {
|
|
|
179
179
|
include?: string | number | (string | number)[] | undefined;
|
|
180
180
|
offset?: string | number | undefined;
|
|
181
181
|
order?: "asc" | "desc" | undefined;
|
|
182
|
-
orderby?: "
|
|
182
|
+
orderby?: "date" | "id" | "slug" | "parent" | "title" | "author" | "include" | "modified" | "relevance" | "include_slugs" | undefined;
|
|
183
183
|
searchColumns?: ("post_title" | "post_content" | "post_excerpt")[] | undefined;
|
|
184
184
|
slug?: string | string[] | undefined;
|
|
185
185
|
taxRelation?: "AND" | "OR" | undefined;
|
|
@@ -507,7 +507,7 @@ declare const ROUTER_MAP: {
|
|
|
507
507
|
include?: string | number | (string | number)[] | undefined;
|
|
508
508
|
offset?: string | number | undefined;
|
|
509
509
|
order?: "asc" | "desc" | undefined;
|
|
510
|
-
orderby?: "
|
|
510
|
+
orderby?: "date" | "id" | "slug" | "parent" | "title" | "author" | "include" | "modified" | "relevance" | "include_slugs" | "menu_order" | undefined;
|
|
511
511
|
searchColumns?: ("post_title" | "post_content" | "post_excerpt")[] | undefined;
|
|
512
512
|
slug?: string | string[] | undefined;
|
|
513
513
|
parent?: string | number | (string | number)[] | undefined;
|
|
@@ -764,7 +764,7 @@ declare const ROUTER_MAP: {
|
|
|
764
764
|
exclude?: string | number | (string | number)[] | undefined;
|
|
765
765
|
include?: string | number | (string | number)[] | undefined;
|
|
766
766
|
order?: "asc" | "desc" | undefined;
|
|
767
|
-
orderBy?: "id" | "slug" | "name" | "description" | "include" | "include_slugs" | "term_group" |
|
|
767
|
+
orderBy?: "count" | "id" | "slug" | "name" | "description" | "include" | "include_slugs" | "term_group" | undefined;
|
|
768
768
|
hideEmpty?: string | boolean | undefined;
|
|
769
769
|
parent?: string | number | undefined;
|
|
770
770
|
post?: string | number | undefined;
|
|
@@ -976,7 +976,7 @@ declare const ROUTER_MAP: {
|
|
|
976
976
|
exclude?: string | number | (string | number)[] | undefined;
|
|
977
977
|
include?: string | number | (string | number)[] | undefined;
|
|
978
978
|
order?: "asc" | "desc" | undefined;
|
|
979
|
-
orderBy?: "id" | "slug" | "name" | "description" | "include" | "include_slugs" | "term_group" |
|
|
979
|
+
orderBy?: "count" | "id" | "slug" | "name" | "description" | "include" | "include_slugs" | "term_group" | undefined;
|
|
980
980
|
hideEmpty?: string | boolean | undefined;
|
|
981
981
|
post?: string | number | undefined;
|
|
982
982
|
slug?: string | string[] | undefined;
|
|
@@ -1135,7 +1135,7 @@ declare const ROUTER_MAP: {
|
|
|
1135
1135
|
sitemaps: {
|
|
1136
1136
|
list: Procedure<"internal", {}, {
|
|
1137
1137
|
key: string;
|
|
1138
|
-
type: "
|
|
1138
|
+
type: "post_type" | "taxonomy" | "author";
|
|
1139
1139
|
pages: number;
|
|
1140
1140
|
lastmod: string;
|
|
1141
1141
|
}[], DefinedErrorMapLike>;
|
|
@@ -1143,7 +1143,7 @@ declare const ROUTER_MAP: {
|
|
|
1143
1143
|
origin: string;
|
|
1144
1144
|
sitemaps: {
|
|
1145
1145
|
key: string;
|
|
1146
|
-
type: "
|
|
1146
|
+
type: "post_type" | "taxonomy" | "author";
|
|
1147
1147
|
pages: number;
|
|
1148
1148
|
lastmod: string;
|
|
1149
1149
|
}[];
|
|
@@ -1186,7 +1186,7 @@ declare const ROUTER_MAP: {
|
|
|
1186
1186
|
include?: string | number | (string | number)[] | undefined;
|
|
1187
1187
|
offset?: string | number | undefined;
|
|
1188
1188
|
order?: "asc" | "desc" | undefined;
|
|
1189
|
-
orderby?: "
|
|
1189
|
+
orderby?: "date" | "id" | "slug" | "parent" | "title" | "author" | "include" | "relevance" | "include_slugs" | "menu_order" | undefined;
|
|
1190
1190
|
searchColumns?: ("post_title" | "post_content" | "post_excerpt")[] | undefined;
|
|
1191
1191
|
slug?: string | string[] | undefined;
|
|
1192
1192
|
taxRelation?: "AND" | "OR" | undefined;
|
|
@@ -1265,7 +1265,7 @@ declare const ROUTER_MAP: {
|
|
|
1265
1265
|
include?: string | number | (string | number)[] | undefined;
|
|
1266
1266
|
offset?: string | number | undefined;
|
|
1267
1267
|
order?: "asc" | "desc" | undefined;
|
|
1268
|
-
orderby?: "
|
|
1268
|
+
orderby?: "date" | "id" | "slug" | "parent" | "title" | "author" | "include" | "relevance" | "include_slugs" | "menu_order" | undefined;
|
|
1269
1269
|
searchColumns?: ("post_title" | "post_content" | "post_excerpt")[] | undefined;
|
|
1270
1270
|
slug?: string | string[] | undefined;
|
|
1271
1271
|
taxRelation?: "AND" | "OR" | undefined;
|
|
@@ -1414,7 +1414,7 @@ declare const ROUTER_MAP: {
|
|
|
1414
1414
|
include?: string | number | (string | number)[] | undefined;
|
|
1415
1415
|
offset?: string | number | undefined;
|
|
1416
1416
|
order?: "asc" | "desc" | undefined;
|
|
1417
|
-
orderby?: "
|
|
1417
|
+
orderby?: "date" | "id" | "parent" | "post" | "include" | undefined;
|
|
1418
1418
|
parent?: string | number | (string | number)[] | undefined;
|
|
1419
1419
|
parentExclude?: string | number | (string | number)[] | undefined;
|
|
1420
1420
|
post?: string | number | (string | number)[] | undefined;
|
package/dist/seo/schema.d.ts
CHANGED
|
@@ -108,17 +108,17 @@ declare const Seo: z.ZodObject<{
|
|
|
108
108
|
type Seo = z.infer<typeof Seo>;
|
|
109
109
|
declare const CONTENT_TYPES: readonly ["post_type", "taxonomy", "author"];
|
|
110
110
|
declare const ContentType: z.ZodEnum<{
|
|
111
|
-
author: "author";
|
|
112
111
|
post_type: "post_type";
|
|
113
112
|
taxonomy: "taxonomy";
|
|
113
|
+
author: "author";
|
|
114
114
|
}>;
|
|
115
115
|
type ContentType = z.infer<typeof ContentType>;
|
|
116
116
|
declare const Sitemap: z.ZodObject<{
|
|
117
117
|
key: z.ZodString;
|
|
118
118
|
type: z.ZodEnum<{
|
|
119
|
-
author: "author";
|
|
120
119
|
post_type: "post_type";
|
|
121
120
|
taxonomy: "taxonomy";
|
|
121
|
+
author: "author";
|
|
122
122
|
}>;
|
|
123
123
|
pages: z.ZodNumber;
|
|
124
124
|
lastmod: z.ZodString;
|
|
@@ -127,9 +127,9 @@ type Sitemap = z.infer<typeof Sitemap>;
|
|
|
127
127
|
declare const SitemapList: z.ZodArray<z.ZodObject<{
|
|
128
128
|
key: z.ZodString;
|
|
129
129
|
type: z.ZodEnum<{
|
|
130
|
-
author: "author";
|
|
131
130
|
post_type: "post_type";
|
|
132
131
|
taxonomy: "taxonomy";
|
|
132
|
+
author: "author";
|
|
133
133
|
}>;
|
|
134
134
|
pages: z.ZodNumber;
|
|
135
135
|
lastmod: z.ZodString;
|
|
@@ -140,9 +140,9 @@ declare const SitemapIndex: z.ZodObject<{
|
|
|
140
140
|
sitemaps: z.ZodArray<z.ZodObject<{
|
|
141
141
|
key: z.ZodString;
|
|
142
142
|
type: z.ZodEnum<{
|
|
143
|
-
author: "author";
|
|
144
143
|
post_type: "post_type";
|
|
145
144
|
taxonomy: "taxonomy";
|
|
145
|
+
author: "author";
|
|
146
146
|
}>;
|
|
147
147
|
pages: z.ZodNumber;
|
|
148
148
|
lastmod: z.ZodString;
|
|
@@ -174,9 +174,9 @@ declare const SitemapUrlList: z.ZodArray<z.ZodObject<{
|
|
|
174
174
|
type SitemapUrlList = z.infer<typeof SitemapUrlList>;
|
|
175
175
|
declare const ListSitemapUrlInputBase: z.ZodObject<{
|
|
176
176
|
type: z.ZodEnum<{
|
|
177
|
-
author: "author";
|
|
178
177
|
post_type: "post_type";
|
|
179
178
|
taxonomy: "taxonomy";
|
|
179
|
+
author: "author";
|
|
180
180
|
}>;
|
|
181
181
|
page: z.ZodOptional<z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>, z.ZodCoercedNumber<string | number>>>;
|
|
182
182
|
}, z.core.$strip>;
|