@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 +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/provisioning-command.d.ts +40 -0
- package/dist/provisioning-command.d.ts.map +1 -0
- package/dist/provisioning-command.js +75 -0
- package/dist/provisioning-command.js.map +1 -0
- package/dist/version.d.ts +13 -2
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +36 -1
- package/dist/version.js.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +8 -1
- package/src/provisioning-command.test.ts +78 -0
- package/src/provisioning-command.ts +80 -0
- package/src/version.ts +31 -1
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
|
package/dist/index.d.ts.map
CHANGED
|
@@ -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,
|
|
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,
|
|
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.
|
|
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.
|
|
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
|
package/dist/version.d.ts.map
CHANGED
|
@@ -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.
|
|
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
|
package/dist/version.js.map
CHANGED
|
@@ -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.
|
|
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 {
|
|
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.
|
|
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
|
+
}
|