@dogsbay/format-openapi 0.2.0-beta.12 → 0.2.0-beta.120

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.
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Which spec file a page's `:::openapi{spec}` may name. No dependencies, so
3
+ * a host can check a path without loading the spec parser
4
+ * (`@dogsbay/format-openapi/spec-path`); also exported from `./core`.
5
+ */
6
+ const SPEC_EXT = /\.(ya?ml|json)$/i;
7
+ /**
8
+ * The content-relative paths `:::openapi{spec}` on the page `slug` may mean,
9
+ * in the order to try them, or why it may name none.
10
+ *
11
+ * The spec path is CONTENT, so it is held to what content may name:
12
+ * - a file, never a URL: a page does not get to make the build fetch;
13
+ * - `.yaml`, `.yml` or `.json`;
14
+ * - inside a content root (the caller checks, after resolving symlinks).
15
+ *
16
+ * A leading `/` is the content root. A relative path is tried against the
17
+ * page's folder, then the page's own folder for an index page (slug
18
+ * `reference` may be `reference/index.md`). Importers write root-relative
19
+ * paths, which have no such ambiguity.
20
+ */
21
+ export function specCandidates(spec, slug) {
22
+ if (!spec)
23
+ return { error: "no `spec` on :::openapi" };
24
+ if (/^[a-z][a-z0-9+.-]*:/i.test(spec) || spec.startsWith("//")) {
25
+ return { error: `a page may name a spec file, not a URL (${spec})` };
26
+ }
27
+ if (/[?#]/.test(spec) || !SPEC_EXT.test(spec)) {
28
+ return { error: `not a .yaml, .yml or .json file (${spec})` };
29
+ }
30
+ const clean = spec.replace(/\\/g, "/");
31
+ if (clean.startsWith("/"))
32
+ return { paths: [normalizePath(clean)].filter(isContained) };
33
+ const dir = slug.includes("/") ? slug.slice(0, slug.lastIndexOf("/")) : "";
34
+ return { paths: [normalizePath(`${dir}/${clean}`), normalizePath(`${slug}/${clean}`)].filter(isContained) };
35
+ }
36
+ /**
37
+ * The spec file `:::openapi{spec}` on the page `slug` names, or an error.
38
+ * `lookup` answers for one content-relative path (dogsbay-ssg: its file
39
+ * map; the CLI: each content root, symlinks resolved).
40
+ */
41
+ export function findSpec(spec, slug, lookup) {
42
+ const c = specCandidates(spec, slug);
43
+ if ("error" in c)
44
+ return c;
45
+ let escaped = c.paths.length === 0;
46
+ for (const p of c.paths) {
47
+ const found = lookup(p);
48
+ if (found === "outside")
49
+ escaped = true;
50
+ else if (found)
51
+ return found;
52
+ }
53
+ return { error: escaped ? `the spec resolves outside the content root (${spec})` : `spec not found (${spec})` };
54
+ }
55
+ /** `a/./b/../c` → `a/c`; a path that climbs above the root keeps its leading `..`. */
56
+ function normalizePath(p) {
57
+ const out = [];
58
+ for (const seg of p.split("/")) {
59
+ if (!seg || seg === ".")
60
+ continue;
61
+ if (seg === ".." && out.length && out[out.length - 1] !== "..")
62
+ out.pop();
63
+ else
64
+ out.push(seg);
65
+ }
66
+ return out.join("/");
67
+ }
68
+ const isContained = (p) => p !== "" && p !== ".." && !p.startsWith("../");
69
+ //# sourceMappingURL=spec-path.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spec-path.js","sourceRoot":"","sources":["../src/spec-path.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dogsbay/format-openapi",
3
- "version": "0.2.0-beta.12",
3
+ "version": "0.2.0-beta.120",
4
4
  "description": "OpenAPI format plugin for Dogsbay — parse OpenAPI 3.x specs into ExportPage[] for the SSG pipeline",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -10,9 +10,21 @@
10
10
  "types": "./dist/index.d.ts",
11
11
  "import": "./dist/index.js"
12
12
  },
13
+ "./core": {
14
+ "types": "./dist/core.d.ts",
15
+ "import": "./dist/core.js"
16
+ },
17
+ "./spec-path": {
18
+ "types": "./dist/spec-path.d.ts",
19
+ "import": "./dist/spec-path.js"
20
+ },
13
21
  "./cli": {
14
22
  "types": "./dist/cli.d.ts",
15
23
  "import": "./dist/cli.js"
24
+ },
25
+ "./embed": {
26
+ "types": "./dist/embed.d.ts",
27
+ "import": "./dist/embed.js"
16
28
  }
17
29
  },
18
30
  "files": [
@@ -20,15 +32,18 @@
20
32
  "README.md"
21
33
  ],
22
34
  "dependencies": {
23
- "@scalar/openapi-parser": "^0.10.0",
24
- "yaml": "^2.8.3",
25
- "@dogsbay/types": "0.2.0-beta.12"
35
+ "@scalar/openapi-parser": "^0.10.17",
36
+ "markdown-it": "^14.3.0",
37
+ "yaml": "^2.9.0",
38
+ "@dogsbay/types": "0.2.0-beta.120"
26
39
  },
27
40
  "devDependencies": {
28
- "@types/node": "^25.5.0",
29
- "typescript": "^5.7.0",
30
- "vitest": "^3.0.0",
31
- "@dogsbay/format-astro": "0.2.0-beta.12"
41
+ "@types/markdown-it": "^14.1.2",
42
+ "@types/node": "^25.9.5",
43
+ "esbuild": "^0.25.0",
44
+ "typescript": "^5.9.3",
45
+ "vitest": "^4.1.10",
46
+ "@dogsbay/format-astro": "0.2.0-beta.120"
32
47
  },
33
48
  "license": "MIT",
34
49
  "repository": {