blume 1.0.0 → 1.0.2
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/CHANGELOG.md +16 -0
- package/dist/cli/index.js +29 -18
- package/dist/cli/index.js.map +8 -7
- package/dist/types/core/trim.d.ts +16 -0
- package/package.json +2 -2
- package/src/ai/mcp/discovery.ts +2 -1
- package/src/astro/templates.ts +4 -5
- package/src/components/layout/PageLayout.astro +8 -7
- package/src/components/layout/ReferenceLayout.astro +8 -10
- package/src/components/layout/RootLayout.astro +8 -7
- package/src/components/layout/head-scripts.ts +20 -10
- package/src/core/base-path.ts +4 -4
- package/src/core/trim.ts +32 -0
- package/src/openapi/references.ts +4 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# blume
|
|
2
2
|
|
|
3
|
+
## 1.0.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- d62dbd0: Harden the pre-paint inline scripts and the route-normalizing regexes against the issues CodeQL flagged.
|
|
8
|
+
|
|
9
|
+
The theme and banner scripts in `<head>` used to be built by interpolating config values into JavaScript source with `JSON.stringify`. JSON escaping isn't a code-context escape — `</script>` and U+2028/U+2029 pass straight through it — so a crafted `banner.id` or theme value could break out of the script. Both scripts are now constants and take their values from `data-*` attributes on their own `<script>` tag, which Astro HTML-escapes. `ReferenceLayout` had drifted to its own inline copies of both scripts; it now shares the same module as `RootLayout` and `PageLayout`.
|
|
10
|
+
|
|
11
|
+
Route and slug normalization used `/^\/+|\/+$/`-style patterns to trim leading and trailing separators. Those take quadratic time on a long run of the trimmed character, and they run on values that come from outside Blume (configured routes, OpenAPI spec URLs, the site origin), so a pathological config could hang the build. They're replaced by linear trimming helpers in `core/trim.ts`; behavior is unchanged.
|
|
12
|
+
|
|
13
|
+
## 1.0.1
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- 6afb56a: Declare the `blume` bin as `bin/blume.mjs` instead of `./bin/blume.mjs`. The leading `./` is redundant and some package managers normalize it away when linking the binary; dropping it keeps the published manifest consistent with what installers actually write.
|
|
18
|
+
|
|
3
19
|
## 1.0.0
|
|
4
20
|
|
|
5
21
|
### Major Changes
|
package/dist/cli/index.js
CHANGED
|
@@ -536,7 +536,7 @@ var normalizeBasePath = (input) => {
|
|
|
536
536
|
if (!input) {
|
|
537
537
|
return "";
|
|
538
538
|
}
|
|
539
|
-
const trimmed = input.trim().
|
|
539
|
+
const trimmed = input.trim().split("/").filter(Boolean).join("/");
|
|
540
540
|
return trimmed === "" ? "" : `/${trimmed}`;
|
|
541
541
|
};
|
|
542
542
|
var isInternalPath = (target) => target.startsWith("/") && !target.startsWith("//");
|
|
@@ -4127,6 +4127,23 @@ var buildMcpData = async (project) => {
|
|
|
4127
4127
|
};
|
|
4128
4128
|
};
|
|
4129
4129
|
|
|
4130
|
+
// src/core/trim.ts
|
|
4131
|
+
var trimStart = (text, char) => {
|
|
4132
|
+
let start = 0;
|
|
4133
|
+
while (start < text.length && text[start] === char) {
|
|
4134
|
+
start += 1;
|
|
4135
|
+
}
|
|
4136
|
+
return text.slice(start);
|
|
4137
|
+
};
|
|
4138
|
+
var trimEnd = (text, char) => {
|
|
4139
|
+
let end = text.length;
|
|
4140
|
+
while (end > 0 && text[end - 1] === char) {
|
|
4141
|
+
end -= 1;
|
|
4142
|
+
}
|
|
4143
|
+
return text.slice(0, end);
|
|
4144
|
+
};
|
|
4145
|
+
var trimChar = (text, char) => trimEnd(trimStart(text, char), char);
|
|
4146
|
+
|
|
4130
4147
|
// src/ai/mcp/tools.ts
|
|
4131
4148
|
var READ_ONLY = { openWorldHint: false, readOnlyHint: true };
|
|
4132
4149
|
var MCP_TOOLS = [
|
|
@@ -4159,7 +4176,7 @@ var MCP_TOOLS = [
|
|
|
4159
4176
|
// src/ai/mcp/discovery.ts
|
|
4160
4177
|
var serverUrl = (input) => {
|
|
4161
4178
|
const path = withBasePath(input.base, input.route);
|
|
4162
|
-
return input.site ? `${input.site
|
|
4179
|
+
return input.site ? `${trimEnd(input.site, "/")}${path}` : path;
|
|
4163
4180
|
};
|
|
4164
4181
|
var buildMcpDiscovery = (input) => ({
|
|
4165
4182
|
servers: [
|
|
@@ -4829,17 +4846,14 @@ import { isAbsolute as isAbsolute5, join as join16, resolve as resolve5 } from "
|
|
|
4829
4846
|
|
|
4830
4847
|
// src/openapi/references.ts
|
|
4831
4848
|
var NON_SLUG = /[^a-z0-9]+/gu;
|
|
4832
|
-
var
|
|
4833
|
-
var ROUTE_EDGES = /^\/+|\/+$/gu;
|
|
4834
|
-
var TRAILING_SLASH = /\/+$/u;
|
|
4835
|
-
var slugify = (text) => text.toLowerCase().replace(NON_SLUG, "-").replace(SLUG_EDGES, "");
|
|
4849
|
+
var slugify = (text) => trimChar(text.toLowerCase().replace(NON_SLUG, "-"), "-");
|
|
4836
4850
|
var normalizeRoute = (route) => {
|
|
4837
4851
|
const trimmed = route.trim();
|
|
4838
4852
|
const withSlash = trimmed.startsWith("/") ? trimmed : `/${trimmed}`;
|
|
4839
|
-
const noTrailing = withSlash
|
|
4853
|
+
const noTrailing = trimEnd(withSlash, "/");
|
|
4840
4854
|
return noTrailing === "" ? "/" : noTrailing;
|
|
4841
4855
|
};
|
|
4842
|
-
var routeSlug = (route) => slugify(route
|
|
4856
|
+
var routeSlug = (route) => slugify(trimChar(route, "/")) || "reference";
|
|
4843
4857
|
var sourcesOf = (block) => {
|
|
4844
4858
|
const sources = [...block.sources];
|
|
4845
4859
|
if (block.spec) {
|
|
@@ -5010,8 +5024,8 @@ var loadWithCache = async (name, cache, fetchEntries, refresh = true) => {
|
|
|
5010
5024
|
|
|
5011
5025
|
// src/openapi/model.ts
|
|
5012
5026
|
var NON_SLUG2 = /[^a-z0-9]+/gu;
|
|
5013
|
-
var
|
|
5014
|
-
var slugify2 = (text) => text.toLowerCase().replace(NON_SLUG2, "-").replace(
|
|
5027
|
+
var SLUG_EDGES = /^-+|-+$/gu;
|
|
5028
|
+
var slugify2 = (text) => text.toLowerCase().replace(NON_SLUG2, "-").replace(SLUG_EDGES, "");
|
|
5015
5029
|
var HTTP_METHODS = [
|
|
5016
5030
|
"get",
|
|
5017
5031
|
"put",
|
|
@@ -8153,12 +8167,9 @@ export function GET({ props }) {
|
|
|
8153
8167
|
});
|
|
8154
8168
|
}
|
|
8155
8169
|
`;
|
|
8156
|
-
var mcpPageFile = (route) => {
|
|
8157
|
-
const clean = route.replace(/^\/+/u, "").replace(/\/+$/u, "");
|
|
8158
|
-
return `${clean}.ts`;
|
|
8159
|
-
};
|
|
8170
|
+
var mcpPageFile = (route) => `${trimChar(route, "/")}.ts`;
|
|
8160
8171
|
var mcpEndpointTemplate = (route) => {
|
|
8161
|
-
const clean = route
|
|
8172
|
+
const clean = trimChar(route, "/");
|
|
8162
8173
|
const up = "../".repeat(clean.split("/").length);
|
|
8163
8174
|
return `// Generated by Blume. Do not edit.
|
|
8164
8175
|
import type { APIRoute } from "astro";
|
|
@@ -9095,9 +9106,9 @@ ${dark}`;
|
|
|
9095
9106
|
|
|
9096
9107
|
// src/openapi/scalar.ts
|
|
9097
9108
|
var URL_SPEC2 = /^https?:\/\//u;
|
|
9098
|
-
var
|
|
9109
|
+
var ROUTE_EDGES = /^\/+|\/+$/gu;
|
|
9099
9110
|
var referencePagePath = (route) => {
|
|
9100
|
-
const segments = route.replace(
|
|
9111
|
+
const segments = route.replace(ROUTE_EDGES, "");
|
|
9101
9112
|
return `${segments === "" ? "index" : segments}.astro`;
|
|
9102
9113
|
};
|
|
9103
9114
|
var darkModeConfig = (mode) => {
|
|
@@ -13836,5 +13847,5 @@ process.on("unhandledRejection", (error) => {
|
|
|
13836
13847
|
});
|
|
13837
13848
|
runMain(main);
|
|
13838
13849
|
|
|
13839
|
-
//# debugId=
|
|
13850
|
+
//# debugId=5F5E50EAF35B586A64756E2164756E21
|
|
13840
13851
|
//# sourceMappingURL=index.js.map
|