kizlo 0.9.0 → 0.10.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/kizlo.d.ts CHANGED
@@ -14,16 +14,16 @@ import { ResultClient } from "./shared/result.js";
14
14
  type AnyKizloConfig = KizloConfig<any>;
15
15
  /**
16
16
  * Which credential set to read from the environment. Independent of `environment`
17
- * (which carries logging semantics off `NODE_ENV`): `"dev"` reads the `KIZLO_DEV_WORDPRESS_*`
18
- * / `KIZLO_DEV_SITE_SECRET` keys the local stack manages, `"production"` reads `KIZLO_WORDPRESS_*` / `KIZLO_SITE_SECRET`.
17
+ * (which carries logging semantics off `NODE_ENV`): `"local"` reads the `KIZLO_LOCAL_WP_*`
18
+ * / `KIZLO_LOCAL_WP_SECRET` keys local WordPress manages, `"remote"` reads `KIZLO_WP_*` / `KIZLO_WP_SECRET`.
19
19
  */
20
- type KizloTarget = "dev" | "production";
20
+ type KizloConnect = "local" | "remote";
21
21
  interface KizloConfig<TExts extends readonly AnyExtension[]> {
22
22
  baseUrl: string;
23
23
  siteSecret: string;
24
24
  extensions?: TExts;
25
25
  environment: Environment;
26
- target: KizloTarget;
26
+ connect: KizloConnect;
27
27
  adapters?: ServiceAdapters;
28
28
  credentials: WordPressCredentials;
29
29
  }
@@ -50,26 +50,26 @@ declare class Kizlo<TExts extends readonly AnyExtension[] = []> {
50
50
  private registerExtensions;
51
51
  }
52
52
  interface CreateKizloOptions<TExts extends readonly AnyExtension[] = []> {
53
- /** Public base URL of your Kizlo server, used to route requests. Falls back to the `KIZLO_BACKEND_URL` env var. */
53
+ /** Public base URL of your Kizlo server, used to route requests. Falls back to the `KIZLO_API_URL` env var. */
54
54
  baseUrl?: string;
55
- /** Secret shared with the WordPress plugin to sign and verify webhooks. Falls back to the `KIZLO_SITE_SECRET` env var (target-selected). */
55
+ /** Secret shared with the WordPress plugin to sign and verify webhooks. Falls back to the `KIZLO_WP_SECRET` env var (connect-selected). */
56
56
  siteSecret?: string;
57
57
  /** Extensions to register, built with `createExtension` — mounts their namespaces on the client and their routes and event handlers on the handler. */
58
58
  extensions?: TExts;
59
59
  /** Runtime environment. Falls back to `NODE_ENV`, then `"development"`. */
60
60
  environment?: Environment;
61
61
  /**
62
- * Which credential set to use. Falls back to the `KIZLO_TARGET` env var, then `"production"`.
63
- * Independent of `environment`: `"dev"` reads `KIZLO_DEV_WORDPRESS_*` / `KIZLO_DEV_SITE_SECRET` (the keys the
64
- * local dev stack manages), `"production"` reads `KIZLO_WORDPRESS_*` / `KIZLO_SITE_SECRET`.
62
+ * Which credential set to use. Falls back to the `KIZLO_CONNECT` env var, then `"remote"`.
63
+ * Independent of `environment`: `"local"` reads `KIZLO_LOCAL_WP_*` / `KIZLO_LOCAL_WP_SECRET` (the keys
64
+ * local WordPress manages), `"remote"` reads `KIZLO_WP_*` / `KIZLO_WP_SECRET`.
65
65
  */
66
- target?: KizloTarget;
66
+ connect?: KizloConnect;
67
67
  /** Service adapters: auth, captcha, geo, logger, and cookies. */
68
68
  adapters?: ServiceAdapters;
69
69
  /**
70
- * WordPress connection. Each credential falls back to a target-selected env var: with the default
71
- * `"production"` target to `KIZLO_WORDPRESS_URL` / `KIZLO_WORDPRESS_USERNAME` / `KIZLO_WORDPRESS_APPLICATION_PASSWORD`,
72
- * and with the `"dev"` target to their `KIZLO_DEV_WORDPRESS_*` counterparts.
70
+ * WordPress connection. Each credential falls back to a connect-selected env var: with the default
71
+ * `"remote"` connect to `KIZLO_WP_URL` / `KIZLO_WP_USERNAME` / `KIZLO_WP_APP_PASSWORD`,
72
+ * and with the `"local"` connect to their `KIZLO_LOCAL_WP_*` counterparts.
73
73
  */
74
74
  wordpress?: {
75
75
  credentials?: Partial<WordPressCredentials>;
@@ -85,10 +85,10 @@ declare function resolveKizloConfig<TExts extends readonly AnyExtension[]>(optio
85
85
  adapters?: ServiceAdapters;
86
86
  }): KizloConfig<TExts>;
87
87
  /**
88
- * Creates a Kizlo server from the environment (`KIZLO_BACKEND_URL`, `KIZLO_SITE_SECRET`,
89
- * `KIZLO_WORDPRESS_*`), with options taking precedence. Framework packages wrap this
88
+ * Creates a Kizlo server from the environment (`KIZLO_API_URL`, `KIZLO_WP_SECRET`,
89
+ * `KIZLO_WP_*`), with options taking precedence. Framework packages wrap this
90
90
  * with their own URL convention and adapters.
91
91
  */
92
92
  declare function createKizlo<TExts extends readonly AnyExtension[] = []>(options?: CreateKizloOptions<TExts>): Kizlo<TExts>;
93
93
  //#endregion
94
- export { AnyKizloConfig, CreateKizloOptions, Kizlo, KizloConfig, KizloTarget, RootRouter, S2SClient, ServiceAdapters, createKizlo, resolveKizloConfig };
94
+ export { AnyKizloConfig, CreateKizloOptions, Kizlo, KizloConfig, KizloConnect, RootRouter, S2SClient, ServiceAdapters, createKizlo, resolveKizloConfig };
package/dist/kizlo.js CHANGED
@@ -105,17 +105,21 @@ function requireEnv(name) {
105
105
  if (!value) throw new KizloError("MISSING_ENV_VARIABLE", { message: `Please define ${name} in your .env file.` });
106
106
  return value;
107
107
  }
108
- function resolveTarget(option) {
109
- return option ?? (process.env.KIZLO_TARGET === "dev" ? "dev" : "production");
108
+ function resolveConnect(option) {
109
+ if (option) return option;
110
+ const value = process.env.KIZLO_CONNECT?.trim();
111
+ if (!value) return "remote";
112
+ if (value !== "local" && value !== "remote") throw new KizloError("INVALID_ENV_VARIABLE", { message: `KIZLO_CONNECT must be "local" or "remote", got "${value}".` });
113
+ return value;
110
114
  }
111
- /** Env var names for a credential set: `KIZLO_DEV_WORDPRESS_URL` / `KIZLO_DEV_SITE_SECRET` for dev, `KIZLO_WORDPRESS_URL` / `KIZLO_SITE_SECRET` for production. */
112
- function targetEnvKeys(target) {
113
- const prefix = target === "dev" ? "KIZLO_DEV_" : "KIZLO_";
115
+ /** Env var names for a credential set: `KIZLO_LOCAL_WP_URL` / `KIZLO_LOCAL_WP_SECRET` for local, `KIZLO_WP_URL` / `KIZLO_WP_SECRET` for remote. */
116
+ function connectEnvKeys(connect) {
117
+ const prefix = connect === "local" ? "KIZLO_LOCAL_" : "KIZLO_";
114
118
  return {
115
- siteSecret: `${prefix}SITE_SECRET`,
116
- url: `${prefix}WORDPRESS_URL`,
117
- username: `${prefix}WORDPRESS_USERNAME`,
118
- password: `${prefix}WORDPRESS_APPLICATION_PASSWORD`
119
+ siteSecret: `${prefix}WP_SECRET`,
120
+ url: `${prefix}WP_URL`,
121
+ username: `${prefix}WP_USERNAME`,
122
+ password: `${prefix}WP_APP_PASSWORD`
119
123
  };
120
124
  }
121
125
  /**
@@ -125,13 +129,13 @@ function targetEnvKeys(target) {
125
129
  */
126
130
  function resolveKizloConfig(options, defaults) {
127
131
  const credentials = options?.wordpress?.credentials;
128
- const target = resolveTarget(options?.target);
129
- const keys = targetEnvKeys(target);
132
+ const connect = resolveConnect(options?.connect);
133
+ const keys = connectEnvKeys(connect);
130
134
  return {
131
135
  baseUrl: options?.baseUrl ?? requireEnv(defaults.baseUrlEnvKey),
132
136
  siteSecret: options?.siteSecret ?? requireEnv(keys.siteSecret),
133
137
  environment: options?.environment ?? process.env.NODE_ENV ?? "development",
134
- target,
138
+ connect,
135
139
  extensions: options?.extensions,
136
140
  adapters: {
137
141
  ...defaults.adapters,
@@ -145,12 +149,12 @@ function resolveKizloConfig(options, defaults) {
145
149
  };
146
150
  }
147
151
  /**
148
- * Creates a Kizlo server from the environment (`KIZLO_BACKEND_URL`, `KIZLO_SITE_SECRET`,
149
- * `KIZLO_WORDPRESS_*`), with options taking precedence. Framework packages wrap this
152
+ * Creates a Kizlo server from the environment (`KIZLO_API_URL`, `KIZLO_WP_SECRET`,
153
+ * `KIZLO_WP_*`), with options taking precedence. Framework packages wrap this
150
154
  * with their own URL convention and adapters.
151
155
  */
152
156
  function createKizlo(options) {
153
- return new Kizlo(resolveKizloConfig(options, { baseUrlEnvKey: "KIZLO_BACKEND_URL" }));
157
+ return new Kizlo(resolveKizloConfig(options, { baseUrlEnvKey: "KIZLO_API_URL" }));
154
158
  }
155
159
 
156
160
  //#endregion
package/dist/package.js CHANGED
@@ -1,5 +1,5 @@
1
1
  //#region package.json
2
- var version = "0.9.0";
2
+ var version = "0.10.0";
3
3
 
4
4
  //#endregion
5
5
  export { version };
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?: "id" | "date" | "slug" | "parent" | "title" | "author" | "include" | "modified" | "relevance" | "include_slugs" | undefined;
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?: "id" | "date" | "slug" | "parent" | "title" | "author" | "include" | "modified" | "relevance" | "include_slugs" | "menu_order" | undefined;
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;
@@ -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?: "id" | "date" | "slug" | "parent" | "title" | "author" | "include" | "relevance" | "include_slugs" | "menu_order" | undefined;
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?: "id" | "date" | "slug" | "parent" | "title" | "author" | "include" | "relevance" | "include_slugs" | "menu_order" | undefined;
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?: "id" | "date" | "parent" | "post" | "include" | undefined;
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;
@@ -18,7 +18,7 @@ function getKizloTestInstance(options) {
18
18
  baseUrl: "http://test.local",
19
19
  siteSecret: "test-secret",
20
20
  environment: "test",
21
- target: "production",
21
+ connect: "remote",
22
22
  credentials: {
23
23
  url: creds.url,
24
24
  username: creds.users.admin.username,
package/dist/test.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { DevPluginSource, Fixture, FixtureCleanupFn, FixtureSeedFn, JsonValue, LocalPlugin, PluginSource, SeedContext, TestAdminUser, TestCredentials, TestUser, defineFixture, isLocalPlugin } from "./cli/wp/types.js";
2
- import { COMPOSE_FILE, CONFIG_FILES, CREDENTIALS_REL, DEFAULT_PLUGINS, DEFAULT_PORT, OPCACHE_INI, REMAP_ENTRYPOINT, SEED_MARKER_OPTION, SEED_VERSION, TEST_ADMIN, TEST_USER, githubRelease, kizloRelease } from "./cli/wp/constants.js";
3
- import { DockerStack, RunResult, Stack, compose, composeDown, composePull, composeStop, composeUp, createStack, dockerAvailable, wpCli } from "./cli/wp/docker.js";
2
+ import { COMPOSE_FILE, CONFIG_FILES, CREDENTIALS_REL, DEFAULT_PLUGINS, DEFAULT_PORT, LOCAL_DIR_REL, OPCACHE_INI, REMAP_ENTRYPOINT, SEED_MARKER_OPTION, SEED_VERSION, TEST_ADMIN, TEST_USER, githubRelease, kizloRelease } from "./cli/wp/constants.js";
3
+ import { DockerStack, DockerStatus, RunResult, Stack, compose, composeDown, composePull, composeStop, composeUp, createStack, dockerAvailable, dockerHint, dockerStatus, wpCli } from "./cli/wp/docker.js";
4
4
  import { activateLocalPlugin, credentialsPath, ensurePlugin, ensurePlugins, findConfigDir, getTestCredentials, isSeeded, recordedPort, resolvePluginSource } from "./cli/wp/utils.js";
5
5
  import { TestAuthAdapterUser, toTestUser } from "./test/users.js";
6
6
  import { testAuthAdapter } from "./test/auth.js";
@@ -10,4 +10,4 @@ import { KizloClientTestInstance, getKizloClientTestInstance } from "./test/clie
10
10
  import { menuFixture } from "./menu/fixture.js";
11
11
  import { postFixture } from "./post/fixture.js";
12
12
  import { coreFixtures } from "./test/fixtures.js";
13
- export { CAPTCHA_TEST_TOKEN_PASS, COMPOSE_FILE, CONFIG_FILES, CREDENTIALS_REL, DEFAULT_PLUGINS, DEFAULT_PORT, DevPluginSource, DockerStack, Fixture, FixtureCleanupFn, FixtureSeedFn, JsonValue, KizloClientTestInstance, KizloTestInstance, LocalPlugin, OPCACHE_INI, PluginSource, REMAP_ENTRYPOINT, RunResult, SEED_MARKER_OPTION, SEED_VERSION, SeedContext, Stack, TEST_ADMIN, TEST_USER, TestAdminUser, TestAuthAdapterUser, TestCredentials, TestUser, activateLocalPlugin, captchaMock, compose, composeDown, composePull, composeStop, composeUp, coreFixtures, createStack, credentialsPath, defineFixture, dockerAvailable, ensurePlugin, ensurePlugins, findConfigDir, getKizloClientTestInstance, getKizloTestInstance, getTestCredentials, githubRelease, isLocalPlugin, isSeeded, kizloRelease, menuFixture, postFixture, recordedPort, resolvePluginSource, testAuthAdapter, toTestUser, wpCli };
13
+ export { CAPTCHA_TEST_TOKEN_PASS, COMPOSE_FILE, CONFIG_FILES, CREDENTIALS_REL, DEFAULT_PLUGINS, DEFAULT_PORT, DevPluginSource, DockerStack, DockerStatus, Fixture, FixtureCleanupFn, FixtureSeedFn, JsonValue, KizloClientTestInstance, KizloTestInstance, LOCAL_DIR_REL, LocalPlugin, OPCACHE_INI, PluginSource, REMAP_ENTRYPOINT, RunResult, SEED_MARKER_OPTION, SEED_VERSION, SeedContext, Stack, TEST_ADMIN, TEST_USER, TestAdminUser, TestAuthAdapterUser, TestCredentials, TestUser, activateLocalPlugin, captchaMock, compose, composeDown, composePull, composeStop, composeUp, coreFixtures, createStack, credentialsPath, defineFixture, dockerAvailable, dockerHint, dockerStatus, ensurePlugin, ensurePlugins, findConfigDir, getKizloClientTestInstance, getKizloTestInstance, getTestCredentials, githubRelease, isLocalPlugin, isSeeded, kizloRelease, menuFixture, postFixture, recordedPort, resolvePluginSource, testAuthAdapter, toTestUser, wpCli };
package/dist/test.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { defineFixture, isLocalPlugin } from "./cli/wp/types.js";
2
- import { COMPOSE_FILE, CONFIG_FILES, CREDENTIALS_REL, DEFAULT_PLUGINS, DEFAULT_PORT, OPCACHE_INI, REMAP_ENTRYPOINT, SEED_MARKER_OPTION, SEED_VERSION, TEST_ADMIN, TEST_USER, githubRelease, kizloRelease } from "./cli/wp/constants.js";
3
- import { compose, composeDown, composePull, composeStop, composeUp, createStack, dockerAvailable, wpCli } from "./cli/wp/docker.js";
2
+ import { COMPOSE_FILE, CONFIG_FILES, CREDENTIALS_REL, DEFAULT_PLUGINS, DEFAULT_PORT, LOCAL_DIR_REL, OPCACHE_INI, REMAP_ENTRYPOINT, SEED_MARKER_OPTION, SEED_VERSION, TEST_ADMIN, TEST_USER, githubRelease, kizloRelease } from "./cli/wp/constants.js";
3
+ import { compose, composeDown, composePull, composeStop, composeUp, createStack, dockerAvailable, dockerHint, dockerStatus, wpCli } from "./cli/wp/docker.js";
4
4
  import { activateLocalPlugin, credentialsPath, ensurePlugin, ensurePlugins, findConfigDir, getTestCredentials, isSeeded, recordedPort, resolvePluginSource } from "./cli/wp/utils.js";
5
5
  import { testAuthAdapter } from "./test/auth.js";
6
6
  import { CAPTCHA_TEST_TOKEN_PASS, captchaMock } from "./test/captcha.js";
@@ -11,4 +11,4 @@ import { coreFixtures } from "./test/fixtures.js";
11
11
  import { toTestUser } from "./test/users.js";
12
12
  import { getKizloTestInstance } from "./test/server.js";
13
13
 
14
- export { CAPTCHA_TEST_TOKEN_PASS, COMPOSE_FILE, CONFIG_FILES, CREDENTIALS_REL, DEFAULT_PLUGINS, DEFAULT_PORT, OPCACHE_INI, REMAP_ENTRYPOINT, SEED_MARKER_OPTION, SEED_VERSION, TEST_ADMIN, TEST_USER, activateLocalPlugin, captchaMock, compose, composeDown, composePull, composeStop, composeUp, coreFixtures, createStack, credentialsPath, defineFixture, dockerAvailable, ensurePlugin, ensurePlugins, findConfigDir, getKizloClientTestInstance, getKizloTestInstance, getTestCredentials, githubRelease, isLocalPlugin, isSeeded, kizloRelease, menuFixture, postFixture, recordedPort, resolvePluginSource, testAuthAdapter, toTestUser, wpCli };
14
+ export { CAPTCHA_TEST_TOKEN_PASS, COMPOSE_FILE, CONFIG_FILES, CREDENTIALS_REL, DEFAULT_PLUGINS, DEFAULT_PORT, LOCAL_DIR_REL, OPCACHE_INI, REMAP_ENTRYPOINT, SEED_MARKER_OPTION, SEED_VERSION, TEST_ADMIN, TEST_USER, activateLocalPlugin, captchaMock, compose, composeDown, composePull, composeStop, composeUp, coreFixtures, createStack, credentialsPath, defineFixture, dockerAvailable, dockerHint, dockerStatus, ensurePlugin, ensurePlugins, findConfigDir, getKizloClientTestInstance, getKizloTestInstance, getTestCredentials, githubRelease, isLocalPlugin, isSeeded, kizloRelease, menuFixture, postFixture, recordedPort, resolvePluginSource, testAuthAdapter, toTestUser, wpCli };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kizlo",
3
- "version": "0.9.0",
3
+ "version": "0.10.0",
4
4
  "type": "module",
5
5
  "description": "A headless WordPress framework for TypeScript.",
6
6
  "keywords": [
@@ -14,7 +14,7 @@
14
14
  "nextjs",
15
15
  "sdk"
16
16
  ],
17
- "license": "MIT",
17
+ "license": "Apache-2.0",
18
18
  "author": "Kizlo",
19
19
  "homepage": "https://github.com/kizlo-io/kizlo/tree/main/packages/kizlo#readme",
20
20
  "bugs": "https://github.com/kizlo-io/kizlo/issues",
@@ -76,7 +76,7 @@
76
76
  },
77
77
  "dependencies": {
78
78
  "@clack/prompts": "^1.5.1",
79
- "@kizlo/shared": "0.5.0",
79
+ "@kizlo/shared": "0.5.1",
80
80
  "@orpc/client": "^1.14.3",
81
81
  "@orpc/contract": "^1.14.3",
82
82
  "@orpc/openapi": "^1.14.3",
@@ -1,113 +0,0 @@
1
- import { join, resolve, sep } from "node:path";
2
- import { execFileSync } from "node:child_process";
3
- import { cpSync, createReadStream, existsSync, mkdirSync, readdirSync, renameSync, rmSync } from "node:fs";
4
- import { createInterface } from "node:readline";
5
-
6
- //#region src/cli/wp/byo.ts
7
- /** Path under the config's `.kizlo/` dir where the dump is staged for import, then deleted. */
8
- const SQL_STAGE_REL = ".kizlo/byo-import.sql";
9
- function tar(args) {
10
- try {
11
- return execFileSync("tar", args, {
12
- encoding: "utf8",
13
- maxBuffer: 64 * 1024 * 1024
14
- });
15
- } catch (error) {
16
- const e = error;
17
- throw new Error(`tar ${args.join(" ")} failed:\n${e.stderr || e.message}`);
18
- }
19
- }
20
- /** Drop a leading `./` that some tar archives prefix entries with. */
21
- function norm(entry) {
22
- return entry.replace(/^\.\//, "");
23
- }
24
- /** Move `src` to `dest`, falling back to copy+remove across filesystems (rename's EXDEV). */
25
- function moveInto(src, dest) {
26
- try {
27
- renameSync(src, dest);
28
- } catch (error) {
29
- if (error.code !== "EXDEV") throw error;
30
- cpSync(src, dest, { recursive: true });
31
- rmSync(src, {
32
- recursive: true,
33
- force: true
34
- });
35
- }
36
- }
37
- /**
38
- * Validate a BYO archive and return the name of its single root-level `.sql` dump. The
39
- * archive must be a `.tar.gz` holding a top-level `wordpress/` directory and exactly one
40
- * root-level `*.sql`, and must live outside `wordpressDir` (else `reset`, which wipes
41
- * that folder, would delete the archive before it could be re-read).
42
- */
43
- function validateByoArchive(archivePath, wordpressDir) {
44
- if (!existsSync(archivePath)) throw new Error(`dev.byo archive not found: ${archivePath}`);
45
- if (!/\.tar(\.(gz|xz|bz2|zst))?$|\.(tgz|txz|tbz2?|tzst)$/i.test(archivePath)) throw new Error(`dev.byo must be a tar archive (.tar.gz, .tar.xz, .tar.bz2, .tar.zst, .tar): ${archivePath}`);
46
- if (resolve(archivePath).startsWith(resolve(wordpressDir) + sep)) throw new Error(`dev.byo archive must live outside dev.path — reset would delete it: ${archivePath}`);
47
- const entries = tar(["-tf", archivePath]).split("\n").map(norm).filter(Boolean);
48
- if (!entries.some((e) => e === "wordpress/" || e.startsWith("wordpress/"))) throw new Error("dev.byo archive must contain a top-level `wordpress/` directory");
49
- const sqls = entries.filter((e) => /^[^/]+\.sql$/.test(e));
50
- if (sqls.length !== 1) throw new Error(`dev.byo archive must contain exactly one root-level .sql file (found ${sqls.length})`);
51
- return sqls[0];
52
- }
53
- /**
54
- * Detect the dump's table prefix from its `{prefix}options` table — the one table every
55
- * WordPress install has exactly one of. Streams the file and stops at the first match;
56
- * falls back to `wp_` when none is found (so a standard dump still imports).
57
- */
58
- async function detectTablePrefix(sqlPath) {
59
- const rl = createInterface({
60
- input: createReadStream(sqlPath),
61
- crlfDelay: Number.POSITIVE_INFINITY
62
- });
63
- try {
64
- for await (const line of rl) {
65
- const match = line.match(/(?:CREATE TABLE(?:\s+IF NOT EXISTS)?|INSERT INTO)\s+`?([0-9a-zA-Z$_]+?)options`?\b/i);
66
- if (match) return match[1];
67
- }
68
- } finally {
69
- rl.close();
70
- }
71
- return "wp_";
72
- }
73
- /**
74
- * Lay a BYO install onto disk before the containers boot: extract the archive, move its
75
- * `wordpress/` files into `wordpressDir` (dropping the bundled `wp-config.php` — the image
76
- * regenerates one with the compose DB credentials), stage the dump under `.kizlo/`, and
77
- * read its table prefix. Returns the prefix (to match the regenerated config) and the host
78
- * path of the staged dump (the caller pipes it into the `mysql` container, then deletes it).
79
- */
80
- async function prepareByo(archivePath, wordpressDir, configDir) {
81
- const sqlName = validateByoArchive(archivePath, wordpressDir);
82
- const tmp = join(configDir, ".kizlo", "byo-extract");
83
- rmSync(tmp, {
84
- recursive: true,
85
- force: true
86
- });
87
- mkdirSync(tmp, { recursive: true });
88
- try {
89
- tar([
90
- "-xf",
91
- archivePath,
92
- "-C",
93
- tmp
94
- ]);
95
- mkdirSync(wordpressDir, { recursive: true });
96
- for (const entry of readdirSync(join(tmp, "wordpress"))) moveInto(join(tmp, "wordpress", entry), join(wordpressDir, entry));
97
- rmSync(join(wordpressDir, "wp-config.php"), { force: true });
98
- const sqlPath = join(configDir, SQL_STAGE_REL);
99
- moveInto(join(tmp, sqlName), sqlPath);
100
- return {
101
- prefix: await detectTablePrefix(sqlPath),
102
- sqlPath
103
- };
104
- } finally {
105
- rmSync(tmp, {
106
- recursive: true,
107
- force: true
108
- });
109
- }
110
- }
111
-
112
- //#endregion
113
- export { prepareByo };