@caelo-cms/shared 0.10.44 → 0.10.46

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/index.d.ts CHANGED
@@ -26,6 +26,7 @@ export * from "./plugin-preview.js";
26
26
  export * from "./preview-compose.js";
27
27
  export * from "./preview-scanner.js";
28
28
  export * from "./proposal-status.js";
29
+ export * from "./provisioning-command.js";
29
30
  export * from "./redirect-target.js";
30
31
  export * from "./responsive-images.js";
31
32
  export * from "./result.js";
@@ -52,5 +53,5 @@ export * from "./theme-render.js";
52
53
  export * from "./themes.js";
53
54
  export * from "./themes-errors.js";
54
55
  export * from "./url.js";
55
- export { CAELO_VERSION, CALEO_VERSION, type CaeloVersion, parseVersion } from "./version.js";
56
+ export { CAELO_VERSION, CALEO_VERSION, type CaeloVersion, isNewerVersion, parseVersion, } from "./version.js";
56
57
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,YAAY,cAAc,CAAC;AAExC,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AACvC,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,wBAAwB,CAAC;AACvC,cAAc,oBAAoB,CAAC;AACnC,cAAc,yBAAyB,CAAC;AACxC,cAAc,mBAAmB,CAAC;AAClC,OAAO,EACL,KAAK,UAAU,EACf,KAAK,MAAM,EACX,KAAK,aAAa,EAClB,KAAK,QAAQ,EACb,UAAU,EACV,aAAa,EACb,MAAM,EACN,KAAK,WAAW,EAChB,KAAK,kBAAkB,GACxB,MAAM,aAAa,CAAC;AACrB,cAAc,YAAY,CAAC;AAC3B,cAAc,2BAA2B,CAAC;AAC1C,cAAc,eAAe,CAAC;AAC9B,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,0BAA0B,CAAC;AACzC,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC;AACrC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC;AACrC,cAAc,kCAAkC,CAAC;AACjD,cAAc,2BAA2B,CAAC;AAC1C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,uCAAuC,CAAC;AACtD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,sBAAsB,CAAC;AACrC,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC;AAC5B,cAAc,oBAAoB,CAAC;AACnC,cAAc,UAAU,CAAC;AACzB,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,KAAK,YAAY,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,YAAY,cAAc,CAAC;AAExC,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AACvC,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,wBAAwB,CAAC;AACvC,cAAc,oBAAoB,CAAC;AACnC,cAAc,yBAAyB,CAAC;AACxC,cAAc,mBAAmB,CAAC;AAClC,OAAO,EACL,KAAK,UAAU,EACf,KAAK,MAAM,EACX,KAAK,aAAa,EAClB,KAAK,QAAQ,EACb,UAAU,EACV,aAAa,EACb,MAAM,EACN,KAAK,WAAW,EAChB,KAAK,kBAAkB,GACxB,MAAM,aAAa,CAAC;AACrB,cAAc,YAAY,CAAC;AAC3B,cAAc,2BAA2B,CAAC;AAC1C,cAAc,eAAe,CAAC;AAC9B,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,0BAA0B,CAAC;AACzC,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC;AACrC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC;AACrC,cAAc,kCAAkC,CAAC;AACjD,cAAc,2BAA2B,CAAC;AAC1C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,uCAAuC,CAAC;AACtD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,sBAAsB,CAAC;AACrC,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC;AAC5B,cAAc,oBAAoB,CAAC;AACnC,cAAc,UAAU,CAAC;AACzB,OAAO,EACL,aAAa,EACb,aAAa,EACb,KAAK,YAAY,EACjB,cAAc,EACd,YAAY,GACb,MAAM,cAAc,CAAC"}
package/dist/index.js CHANGED
@@ -27,6 +27,7 @@ export * from "./plugin-preview.js";
27
27
  export * from "./preview-compose.js";
28
28
  export * from "./preview-scanner.js";
29
29
  export * from "./proposal-status.js";
30
+ export * from "./provisioning-command.js";
30
31
  export * from "./redirect-target.js";
31
32
  export * from "./responsive-images.js";
32
33
  export * from "./result.js";
@@ -53,5 +54,5 @@ export * from "./theme-render.js";
53
54
  export * from "./themes.js";
54
55
  export * from "./themes-errors.js";
55
56
  export * from "./url.js";
56
- export { CAELO_VERSION, CALEO_VERSION, parseVersion } from "./version.js";
57
+ export { CAELO_VERSION, CALEO_VERSION, isNewerVersion, parseVersion, } from "./version.js";
57
58
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,mCAAmC;AAEnC,MAAM,CAAC,MAAM,YAAY,GAAG,WAAW,CAAC;AAExC,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AACvC,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,wBAAwB,CAAC;AACvC,cAAc,oBAAoB,CAAC;AACnC,cAAc,yBAAyB,CAAC;AACxC,cAAc,mBAAmB,CAAC;AAClC,OAAO,EAKL,UAAU,EACV,aAAa,EACb,MAAM,GAGP,MAAM,aAAa,CAAC;AACrB,cAAc,YAAY,CAAC;AAC3B,cAAc,2BAA2B,CAAC;AAC1C,cAAc,eAAe,CAAC;AAC9B,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,0BAA0B,CAAC;AACzC,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC;AACrC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC;AACrC,cAAc,kCAAkC,CAAC;AACjD,cAAc,2BAA2B,CAAC;AAC1C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,uCAAuC,CAAC;AACtD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,sBAAsB,CAAC;AACrC,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC;AAC5B,cAAc,oBAAoB,CAAC;AACnC,cAAc,UAAU,CAAC;AACzB,OAAO,EAAE,aAAa,EAAE,aAAa,EAAqB,YAAY,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,mCAAmC;AAEnC,MAAM,CAAC,MAAM,YAAY,GAAG,WAAW,CAAC;AAExC,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AACvC,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,wBAAwB,CAAC;AACvC,cAAc,oBAAoB,CAAC;AACnC,cAAc,yBAAyB,CAAC;AACxC,cAAc,mBAAmB,CAAC;AAClC,OAAO,EAKL,UAAU,EACV,aAAa,EACb,MAAM,GAGP,MAAM,aAAa,CAAC;AACrB,cAAc,YAAY,CAAC;AAC3B,cAAc,2BAA2B,CAAC;AAC1C,cAAc,eAAe,CAAC;AAC9B,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,0BAA0B,CAAC;AACzC,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC;AACrC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC;AACrC,cAAc,kCAAkC,CAAC;AACjD,cAAc,2BAA2B,CAAC;AAC1C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,uCAAuC,CAAC;AACtD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,sBAAsB,CAAC;AACrC,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC;AAC5B,cAAc,oBAAoB,CAAC;AACnC,cAAc,UAAU,CAAC;AACzB,OAAO,EACL,aAAa,EACb,aAAa,EAEb,cAAc,EACd,YAAY,GACb,MAAM,cAAc,CAAC"}
@@ -0,0 +1,40 @@
1
+ /** npm name of the provisioning CLI. */
2
+ export declare const PROVISIONING_PACKAGE = "@caelo-cms/provisioning";
3
+ /**
4
+ * `bunx @caelo-cms/provisioning@<version> <args>`.
5
+ *
6
+ * @param version an exact release (`0.10.44`, a leading `v` is dropped);
7
+ * throws on anything that is not a version, so a tag like `latest` can
8
+ * never slip into a printed command.
9
+ * @param args the CLI arguments, already split.
10
+ * @example provisioningCommand("0.10.44", ["status"])
11
+ * // → "bunx @caelo-cms/provisioning@0.10.44 status"
12
+ */
13
+ export declare function provisioningCommand(version: string, args?: readonly string[]): string;
14
+ /**
15
+ * The upgrade command for one install, pinned twice: the CLI runs as the
16
+ * target release (its upgrade logic matches the release it installs) and
17
+ * `--version` makes it roll exactly that release, even if a newer one ships
18
+ * before the operator runs it (without the flag, `upgrade` rolls the
19
+ * registry's `latest` tag).
20
+ *
21
+ * @param args.version the release to install.
22
+ * @param args.install the install's domain (or install id); `upgrade`
23
+ * matches either against `~/.caelo-<id>/install.json`.
24
+ * @example provisioningUpgradeCommand({ version: "0.10.44", install: "example.com" })
25
+ * // → "bunx @caelo-cms/provisioning@0.10.44 upgrade --version 0.10.44 --install example.com"
26
+ */
27
+ export declare function provisioningUpgradeCommand(args: {
28
+ version: string;
29
+ install: string;
30
+ }): string;
31
+ /**
32
+ * The `--install` value for the install whose public site is `siteUrl`
33
+ * (the admin's `CAELO_SITE_URL`, which the stacks set to
34
+ * `https://<domain>` — the same domain `install.json` records).
35
+ *
36
+ * @returns the lower-cased hostname, or null when `siteUrl` is not a URL
37
+ * or its host is not a plain domain (an IP literal with a port, say).
38
+ */
39
+ export declare function installHintFromSiteUrl(siteUrl: string): string | null;
40
+ //# sourceMappingURL=provisioning-command.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provisioning-command.d.ts","sourceRoot":"","sources":["../src/provisioning-command.ts"],"names":[],"mappings":"AAiBA,wCAAwC;AACxC,eAAO,MAAM,oBAAoB,4BAA4B,CAAC;AAS9D;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,GAAE,SAAS,MAAM,EAAO,GAAG,MAAM,CAGzF;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,0BAA0B,CAAC,IAAI,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAM7F;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAQrE"}
@@ -0,0 +1,75 @@
1
+ // SPDX-License-Identifier: MPL-2.0
2
+ /**
3
+ * The `bunx @caelo-cms/provisioning …` commands Caelo prints — in the CLI's
4
+ * own next-step hints, `status`, and the admin's Settings → Updates page
5
+ * (issue #696 Phase 0).
6
+ *
7
+ * Every command names an exact package version. Without one, `bunx` reuses
8
+ * whatever copy of the CLI it cached first and never looks again, so an
9
+ * operator who installed months ago would upgrade with months-old upgrade
10
+ * logic (the same trap #552 fixed for the MCP shim). The version is always
11
+ * one the caller knows for certain: the running CLI's own, or the release
12
+ * the release check reported — never "whatever is newest".
13
+ */
14
+ import { parseVersion } from "./version.js";
15
+ /** npm name of the provisioning CLI. */
16
+ export const PROVISIONING_PACKAGE = "@caelo-cms/provisioning";
17
+ /**
18
+ * A hostname the `--install` flag can carry into a copy-pasted shell
19
+ * command: letters, digits, dots and hyphens only, so nothing in it can be
20
+ * read by the shell.
21
+ */
22
+ const SAFE_INSTALL_HINT = /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)*$/;
23
+ /**
24
+ * `bunx @caelo-cms/provisioning@<version> <args>`.
25
+ *
26
+ * @param version an exact release (`0.10.44`, a leading `v` is dropped);
27
+ * throws on anything that is not a version, so a tag like `latest` can
28
+ * never slip into a printed command.
29
+ * @param args the CLI arguments, already split.
30
+ * @example provisioningCommand("0.10.44", ["status"])
31
+ * // → "bunx @caelo-cms/provisioning@0.10.44 status"
32
+ */
33
+ export function provisioningCommand(version, args = []) {
34
+ const exact = parseVersion(version.replace(/^v/, "")).raw;
35
+ return [`bunx ${PROVISIONING_PACKAGE}@${exact}`, ...args].join(" ");
36
+ }
37
+ /**
38
+ * The upgrade command for one install, pinned twice: the CLI runs as the
39
+ * target release (its upgrade logic matches the release it installs) and
40
+ * `--version` makes it roll exactly that release, even if a newer one ships
41
+ * before the operator runs it (without the flag, `upgrade` rolls the
42
+ * registry's `latest` tag).
43
+ *
44
+ * @param args.version the release to install.
45
+ * @param args.install the install's domain (or install id); `upgrade`
46
+ * matches either against `~/.caelo-<id>/install.json`.
47
+ * @example provisioningUpgradeCommand({ version: "0.10.44", install: "example.com" })
48
+ * // → "bunx @caelo-cms/provisioning@0.10.44 upgrade --version 0.10.44 --install example.com"
49
+ */
50
+ export function provisioningUpgradeCommand(args) {
51
+ const version = parseVersion(args.version.replace(/^v/, "")).raw;
52
+ if (!SAFE_INSTALL_HINT.test(args.install)) {
53
+ throw new Error(`not a domain or install id: ${JSON.stringify(args.install)}`);
54
+ }
55
+ return provisioningCommand(version, ["upgrade", "--version", version, "--install", args.install]);
56
+ }
57
+ /**
58
+ * The `--install` value for the install whose public site is `siteUrl`
59
+ * (the admin's `CAELO_SITE_URL`, which the stacks set to
60
+ * `https://<domain>` — the same domain `install.json` records).
61
+ *
62
+ * @returns the lower-cased hostname, or null when `siteUrl` is not a URL
63
+ * or its host is not a plain domain (an IP literal with a port, say).
64
+ */
65
+ export function installHintFromSiteUrl(siteUrl) {
66
+ let host;
67
+ try {
68
+ host = new URL(siteUrl).hostname.toLowerCase();
69
+ }
70
+ catch {
71
+ return null;
72
+ }
73
+ return SAFE_INSTALL_HINT.test(host) ? host : null;
74
+ }
75
+ //# sourceMappingURL=provisioning-command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provisioning-command.js","sourceRoot":"","sources":["../src/provisioning-command.ts"],"names":[],"mappings":"AAAA,mCAAmC;AAEnC;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,wCAAwC;AACxC,MAAM,CAAC,MAAM,oBAAoB,GAAG,yBAAyB,CAAC;AAE9D;;;;GAIG;AACH,MAAM,iBAAiB,GAAG,yEAAyE,CAAC;AAEpG;;;;;;;;;GASG;AACH,MAAM,UAAU,mBAAmB,CAAC,OAAe,EAAE,OAA0B,EAAE;IAC/E,MAAM,KAAK,GAAG,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;IAC1D,OAAO,CAAC,QAAQ,oBAAoB,IAAI,KAAK,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACtE,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,0BAA0B,CAAC,IAA0C;IACnF,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;IACjE,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QAC1C,MAAM,IAAI,KAAK,CAAC,+BAA+B,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACjF,CAAC;IACD,OAAO,mBAAmB,CAAC,OAAO,EAAE,CAAC,SAAS,EAAE,WAAW,EAAE,OAAO,EAAE,WAAW,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;AACpG,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,sBAAsB,CAAC,OAAe;IACpD,IAAI,IAAY,CAAC;IACjB,IAAI,CAAC;QACH,IAAI,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;IACjD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AACpD,CAAC"}
package/dist/version.d.ts CHANGED
@@ -19,7 +19,7 @@
19
19
  * Format: SemVer 2.0.0. Pre-1.0 minor bumps are breaking; post-1.0
20
20
  * follow standard SemVer.
21
21
  */
22
- export declare const CAELO_VERSION = "0.10.44";
22
+ export declare const CAELO_VERSION = "0.10.46";
23
23
  /**
24
24
  * Deprecated alias for back-compat — early P17 work spelled this
25
25
  * `CALEO_VERSION` (typo of "Caelo"). New code should import
@@ -31,7 +31,7 @@ export declare const CAELO_VERSION = "0.10.44";
31
31
  *
32
32
  * @deprecated use CAELO_VERSION
33
33
  */
34
- export declare const CALEO_VERSION = "0.10.44";
34
+ export declare const CALEO_VERSION = "0.10.46";
35
35
  /**
36
36
  * Parsed shape — major/minor/patch + optional pre-release tag.
37
37
  * Stable interface for callers that need to feature-gate (rare —
@@ -46,4 +46,15 @@ export interface CaeloVersion {
46
46
  readonly raw: string;
47
47
  }
48
48
  export declare function parseVersion(raw?: string): CaeloVersion;
49
+ /**
50
+ * True when release `latest` is newer than `current` (both SemVer
51
+ * `X.Y.Z[-pre]`; a leading `v` is ignored). A pre-release sorts before the
52
+ * same X.Y.Z stable; two pre-releases of one X.Y.Z compare as strings.
53
+ * Mirrors the ordering in scripts/release.ts so the "update available"
54
+ * notice agrees with the release pipeline. A string that is not a version
55
+ * is never newer.
56
+ *
57
+ * @example isNewerVersion("0.10.44", "0.10.43") // → true
58
+ */
59
+ export declare function isNewerVersion(latest: string, current: string): boolean;
49
60
  //# sourceMappingURL=version.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,eAAO,MAAM,aAAa,YAAY,CAAC;AAEvC;;;;;;;;;;GAUG;AACH,eAAO,MAAM,aAAa,YAAgB,CAAC;AAE3C;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,YAAY,CAAC,GAAG,GAAE,MAAsB,GAAG,YAAY,CAYtE"}
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,eAAO,MAAM,aAAa,YAAY,CAAC;AAEvC;;;;;;;;;;GAUG;AACH,eAAO,MAAM,aAAa,YAAgB,CAAC;AAE3C;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,YAAY,CAAC,GAAG,GAAE,MAAsB,GAAG,YAAY,CAYtE;AAED;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAkBvE"}
package/dist/version.js CHANGED
@@ -20,7 +20,7 @@
20
20
  * Format: SemVer 2.0.0. Pre-1.0 minor bumps are breaking; post-1.0
21
21
  * follow standard SemVer.
22
22
  */
23
- export const CAELO_VERSION = "0.10.44";
23
+ export const CAELO_VERSION = "0.10.46";
24
24
  /**
25
25
  * Deprecated alias for back-compat — early P17 work spelled this
26
26
  * `CALEO_VERSION` (typo of "Caelo"). New code should import
@@ -46,4 +46,39 @@ export function parseVersion(raw = CAELO_VERSION) {
46
46
  raw,
47
47
  };
48
48
  }
49
+ /**
50
+ * True when release `latest` is newer than `current` (both SemVer
51
+ * `X.Y.Z[-pre]`; a leading `v` is ignored). A pre-release sorts before the
52
+ * same X.Y.Z stable; two pre-releases of one X.Y.Z compare as strings.
53
+ * Mirrors the ordering in scripts/release.ts so the "update available"
54
+ * notice agrees with the release pipeline. A string that is not a version
55
+ * is never newer.
56
+ *
57
+ * @example isNewerVersion("0.10.44", "0.10.43") // → true
58
+ */
59
+ export function isNewerVersion(latest, current) {
60
+ const parse = (v) => {
61
+ try {
62
+ return parseVersion(v.replace(/^v/, ""));
63
+ }
64
+ catch {
65
+ return null;
66
+ }
67
+ };
68
+ const a = parse(latest);
69
+ const b = parse(current);
70
+ if (!a || !b)
71
+ return false;
72
+ for (const k of ["major", "minor", "patch"]) {
73
+ if (a[k] !== b[k])
74
+ return a[k] > b[k];
75
+ }
76
+ if (a.preRelease && !b.preRelease)
77
+ return false;
78
+ if (!a.preRelease && b.preRelease)
79
+ return true;
80
+ if (a.preRelease && b.preRelease)
81
+ return a.preRelease > b.preRelease;
82
+ return false;
83
+ }
49
84
  //# sourceMappingURL=version.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,mCAAmC;AAEnC;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,MAAM,CAAC,MAAM,aAAa,GAAG,SAAS,CAAC;AAEvC;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,aAAa,CAAC;AAgB3C,MAAM,UAAU,YAAY,CAAC,MAAc,aAAa;IACtD,MAAM,CAAC,GAAG,iCAAiC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACtD,IAAI,CAAC,CAAC,EAAE,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,0BAA0B,GAAG,EAAE,CAAC,CAAC;IACnD,CAAC;IACD,OAAO;QACL,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,EAAE,CAAC;QACvC,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,EAAE,CAAC;QACvC,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,EAAE,CAAC;QACvC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI;QACxB,GAAG;KACJ,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,mCAAmC;AAEnC;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,MAAM,CAAC,MAAM,aAAa,GAAG,SAAS,CAAC;AAEvC;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,aAAa,CAAC;AAgB3C,MAAM,UAAU,YAAY,CAAC,MAAc,aAAa;IACtD,MAAM,CAAC,GAAG,iCAAiC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACtD,IAAI,CAAC,CAAC,EAAE,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,0BAA0B,GAAG,EAAE,CAAC,CAAC;IACnD,CAAC;IACD,OAAO;QACL,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,EAAE,CAAC;QACvC,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,EAAE,CAAC;QACvC,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,EAAE,CAAC;QACvC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI;QACxB,GAAG;KACJ,CAAC;AACJ,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,cAAc,CAAC,MAAc,EAAE,OAAe;IAC5D,MAAM,KAAK,GAAG,CAAC,CAAS,EAAuB,EAAE;QAC/C,IAAI,CAAC;YACH,OAAO,YAAY,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;QAC3C,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC,CAAC;IACF,MAAM,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;IACxB,MAAM,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC;IACzB,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IAC3B,KAAK,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAU,EAAE,CAAC;QACrD,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAAE,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACxC,CAAC;IACD,IAAI,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC,CAAC,UAAU;QAAE,OAAO,KAAK,CAAC;IAChD,IAAI,CAAC,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC,UAAU;QAAE,OAAO,IAAI,CAAC;IAC/C,IAAI,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC,UAAU;QAAE,OAAO,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,UAAU,CAAC;IACrE,OAAO,KAAK,CAAC;AACf,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@caelo-cms/shared",
3
- "version": "0.10.44",
3
+ "version": "0.10.46",
4
4
  "private": false,
5
5
  "license": "MPL-2.0",
6
6
  "description": "Shared Zod schemas + types + the two-pass HTML composer used by every Caelo CMS workspace package. Stable enough for plugin authors and embedders to depend on directly.",
package/src/index.ts CHANGED
@@ -39,6 +39,7 @@ export * from "./plugin-preview.js";
39
39
  export * from "./preview-compose.js";
40
40
  export * from "./preview-scanner.js";
41
41
  export * from "./proposal-status.js";
42
+ export * from "./provisioning-command.js";
42
43
  export * from "./redirect-target.js";
43
44
  export * from "./responsive-images.js";
44
45
  export * from "./result.js";
@@ -65,4 +66,10 @@ export * from "./theme-render.js";
65
66
  export * from "./themes.js";
66
67
  export * from "./themes-errors.js";
67
68
  export * from "./url.js";
68
- export { CAELO_VERSION, CALEO_VERSION, type CaeloVersion, parseVersion } from "./version.js";
69
+ export {
70
+ CAELO_VERSION,
71
+ CALEO_VERSION,
72
+ type CaeloVersion,
73
+ isNewerVersion,
74
+ parseVersion,
75
+ } from "./version.js";
@@ -0,0 +1,78 @@
1
+ // SPDX-License-Identifier: MPL-2.0
2
+
3
+ import { describe, expect, it } from "bun:test";
4
+ import {
5
+ installHintFromSiteUrl,
6
+ provisioningCommand,
7
+ provisioningUpgradeCommand,
8
+ } from "./provisioning-command.js";
9
+ import { isNewerVersion } from "./version.js";
10
+
11
+ describe("provisioningCommand", () => {
12
+ it("pins the package to an exact version", () => {
13
+ expect(provisioningCommand("0.10.44", ["status"])).toBe(
14
+ "bunx @caelo-cms/provisioning@0.10.44 status",
15
+ );
16
+ expect(provisioningCommand("v0.10.44")).toBe("bunx @caelo-cms/provisioning@0.10.44");
17
+ });
18
+
19
+ it("refuses a tag or anything else that is not a version", () => {
20
+ expect(() => provisioningCommand("latest")).toThrow(/invalid Caelo version/);
21
+ expect(() => provisioningCommand("0.10")).toThrow(/invalid Caelo version/);
22
+ });
23
+ });
24
+
25
+ describe("provisioningUpgradeCommand", () => {
26
+ it("runs the target release's CLI, rolls exactly that release, on exactly this install", () => {
27
+ expect(provisioningUpgradeCommand({ version: "0.10.44", install: "example.com" })).toBe(
28
+ "bunx @caelo-cms/provisioning@0.10.44 upgrade --version 0.10.44 --install example.com",
29
+ );
30
+ });
31
+
32
+ it("accepts a v-prefixed tag and a pre-release", () => {
33
+ expect(provisioningUpgradeCommand({ version: "v0.11.0-rc.1", install: "gcp-acme" })).toBe(
34
+ "bunx @caelo-cms/provisioning@0.11.0-rc.1 upgrade --version 0.11.0-rc.1 --install gcp-acme",
35
+ );
36
+ });
37
+
38
+ it("refuses an install hint the shell could interpret", () => {
39
+ for (const install of ["example.com; rm -rf ~", "$(id)", "a b", "", "Example.com"]) {
40
+ expect(() => provisioningUpgradeCommand({ version: "0.10.44", install })).toThrow(
41
+ /not a domain/,
42
+ );
43
+ }
44
+ });
45
+ });
46
+
47
+ describe("installHintFromSiteUrl", () => {
48
+ it("names the install by its site's domain", () => {
49
+ expect(installHintFromSiteUrl("https://Example.com")).toBe("example.com");
50
+ expect(installHintFromSiteUrl("https://www.example.co.uk/")).toBe("www.example.co.uk");
51
+ });
52
+
53
+ it("returns null for something that is not a URL", () => {
54
+ expect(installHintFromSiteUrl("example.com")).toBeNull();
55
+ expect(installHintFromSiteUrl("")).toBeNull();
56
+ });
57
+ });
58
+
59
+ describe("isNewerVersion", () => {
60
+ it("orders by major, minor, patch", () => {
61
+ expect(isNewerVersion("0.10.44", "0.10.43")).toBe(true);
62
+ expect(isNewerVersion("0.11.0", "0.10.99")).toBe(true);
63
+ expect(isNewerVersion("1.0.0", "0.99.99")).toBe(true);
64
+ expect(isNewerVersion("0.10.43", "0.10.43")).toBe(false);
65
+ expect(isNewerVersion("0.10.42", "0.10.43")).toBe(false);
66
+ });
67
+
68
+ it("sorts a pre-release before its stable", () => {
69
+ expect(isNewerVersion("0.11.0-rc.1", "0.11.0")).toBe(false);
70
+ expect(isNewerVersion("0.11.0", "0.11.0-rc.1")).toBe(true);
71
+ expect(isNewerVersion("0.11.0-rc.2", "0.11.0-rc.1")).toBe(true);
72
+ });
73
+
74
+ it("ignores a leading v and treats a non-version as never newer", () => {
75
+ expect(isNewerVersion("v0.10.44", "0.10.43")).toBe(true);
76
+ expect(isNewerVersion("nightly", "0.10.43")).toBe(false);
77
+ });
78
+ });
@@ -0,0 +1,80 @@
1
+ // SPDX-License-Identifier: MPL-2.0
2
+
3
+ /**
4
+ * The `bunx @caelo-cms/provisioning …` commands Caelo prints — in the CLI's
5
+ * own next-step hints, `status`, and the admin's Settings → Updates page
6
+ * (issue #696 Phase 0).
7
+ *
8
+ * Every command names an exact package version. Without one, `bunx` reuses
9
+ * whatever copy of the CLI it cached first and never looks again, so an
10
+ * operator who installed months ago would upgrade with months-old upgrade
11
+ * logic (the same trap #552 fixed for the MCP shim). The version is always
12
+ * one the caller knows for certain: the running CLI's own, or the release
13
+ * the release check reported — never "whatever is newest".
14
+ */
15
+
16
+ import { parseVersion } from "./version.js";
17
+
18
+ /** npm name of the provisioning CLI. */
19
+ export const PROVISIONING_PACKAGE = "@caelo-cms/provisioning";
20
+
21
+ /**
22
+ * A hostname the `--install` flag can carry into a copy-pasted shell
23
+ * command: letters, digits, dots and hyphens only, so nothing in it can be
24
+ * read by the shell.
25
+ */
26
+ const SAFE_INSTALL_HINT = /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)*$/;
27
+
28
+ /**
29
+ * `bunx @caelo-cms/provisioning@<version> <args>`.
30
+ *
31
+ * @param version an exact release (`0.10.44`, a leading `v` is dropped);
32
+ * throws on anything that is not a version, so a tag like `latest` can
33
+ * never slip into a printed command.
34
+ * @param args the CLI arguments, already split.
35
+ * @example provisioningCommand("0.10.44", ["status"])
36
+ * // → "bunx @caelo-cms/provisioning@0.10.44 status"
37
+ */
38
+ export function provisioningCommand(version: string, args: readonly string[] = []): string {
39
+ const exact = parseVersion(version.replace(/^v/, "")).raw;
40
+ return [`bunx ${PROVISIONING_PACKAGE}@${exact}`, ...args].join(" ");
41
+ }
42
+
43
+ /**
44
+ * The upgrade command for one install, pinned twice: the CLI runs as the
45
+ * target release (its upgrade logic matches the release it installs) and
46
+ * `--version` makes it roll exactly that release, even if a newer one ships
47
+ * before the operator runs it (without the flag, `upgrade` rolls the
48
+ * registry's `latest` tag).
49
+ *
50
+ * @param args.version the release to install.
51
+ * @param args.install the install's domain (or install id); `upgrade`
52
+ * matches either against `~/.caelo-<id>/install.json`.
53
+ * @example provisioningUpgradeCommand({ version: "0.10.44", install: "example.com" })
54
+ * // → "bunx @caelo-cms/provisioning@0.10.44 upgrade --version 0.10.44 --install example.com"
55
+ */
56
+ export function provisioningUpgradeCommand(args: { version: string; install: string }): string {
57
+ const version = parseVersion(args.version.replace(/^v/, "")).raw;
58
+ if (!SAFE_INSTALL_HINT.test(args.install)) {
59
+ throw new Error(`not a domain or install id: ${JSON.stringify(args.install)}`);
60
+ }
61
+ return provisioningCommand(version, ["upgrade", "--version", version, "--install", args.install]);
62
+ }
63
+
64
+ /**
65
+ * The `--install` value for the install whose public site is `siteUrl`
66
+ * (the admin's `CAELO_SITE_URL`, which the stacks set to
67
+ * `https://<domain>` — the same domain `install.json` records).
68
+ *
69
+ * @returns the lower-cased hostname, or null when `siteUrl` is not a URL
70
+ * or its host is not a plain domain (an IP literal with a port, say).
71
+ */
72
+ export function installHintFromSiteUrl(siteUrl: string): string | null {
73
+ let host: string;
74
+ try {
75
+ host = new URL(siteUrl).hostname.toLowerCase();
76
+ } catch {
77
+ return null;
78
+ }
79
+ return SAFE_INSTALL_HINT.test(host) ? host : null;
80
+ }
package/src/version.ts CHANGED
@@ -22,7 +22,7 @@
22
22
  * follow standard SemVer.
23
23
  */
24
24
 
25
- export const CAELO_VERSION = "0.10.44";
25
+ export const CAELO_VERSION = "0.10.46";
26
26
 
27
27
  /**
28
28
  * Deprecated alias for back-compat — early P17 work spelled this
@@ -64,3 +64,33 @@ export function parseVersion(raw: string = CAELO_VERSION): CaeloVersion {
64
64
  raw,
65
65
  };
66
66
  }
67
+
68
+ /**
69
+ * True when release `latest` is newer than `current` (both SemVer
70
+ * `X.Y.Z[-pre]`; a leading `v` is ignored). A pre-release sorts before the
71
+ * same X.Y.Z stable; two pre-releases of one X.Y.Z compare as strings.
72
+ * Mirrors the ordering in scripts/release.ts so the "update available"
73
+ * notice agrees with the release pipeline. A string that is not a version
74
+ * is never newer.
75
+ *
76
+ * @example isNewerVersion("0.10.44", "0.10.43") // → true
77
+ */
78
+ export function isNewerVersion(latest: string, current: string): boolean {
79
+ const parse = (v: string): CaeloVersion | null => {
80
+ try {
81
+ return parseVersion(v.replace(/^v/, ""));
82
+ } catch {
83
+ return null;
84
+ }
85
+ };
86
+ const a = parse(latest);
87
+ const b = parse(current);
88
+ if (!a || !b) return false;
89
+ for (const k of ["major", "minor", "patch"] as const) {
90
+ if (a[k] !== b[k]) return a[k] > b[k];
91
+ }
92
+ if (a.preRelease && !b.preRelease) return false;
93
+ if (!a.preRelease && b.preRelease) return true;
94
+ if (a.preRelease && b.preRelease) return a.preRelease > b.preRelease;
95
+ return false;
96
+ }