@unchainedshop/cockpit-api 2.2.1 → 2.3.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/client.d.ts CHANGED
@@ -39,14 +39,14 @@ export interface CockpitAPIClient {
39
39
  /**
40
40
  * Get a transformed image asset URL.
41
41
  *
42
- * **Important:** The `w` (width) or `h` (height) parameter is required by the API.
43
- * Without it, the API returns a 400 error.
42
+ * **Important:** At least one of `w` (width) or `h` (height) must be provided.
43
+ * The Cockpit CMS API requires this and returns a 400 error without it.
44
44
  *
45
45
  * @param assetId - The asset ID
46
46
  * @param queryParams - Image transformation parameters (w or h required)
47
47
  * @returns URL string to the generated image, or null if not found
48
48
  */
49
- imageAssetById(assetId: string, queryParams?: ImageAssetQueryParams): Promise<string | null>;
49
+ imageAssetById(assetId: string, queryParams: ImageAssetQueryParams): Promise<string | null>;
50
50
  getFullRouteForSlug(slug: string): Promise<string | undefined>;
51
51
  /**
52
52
  * Clear cache entries matching pattern
package/dist/index.d.ts CHANGED
@@ -26,3 +26,5 @@ export type { CockpitMenuUrl, CockpitMenuLink, CockpitMenu, } from "./methods/me
26
26
  export type { CockpitRoute, CockpitRoutesResponse, CockpitSitemapEntry, CockpitPreviewConfig, CockpitSettings, } from "./methods/routes.ts";
27
27
  export type { CockpitSearchHit, CockpitSearchResult, } from "./methods/search.ts";
28
28
  export type { CockpitHealthCheck } from "./methods/system.ts";
29
+ export { parseCockpitUrl, isCockpitPageUrl, isCockpitAssetUrl, extractPageId, extractAssetId, } from "./utils/url-protocols.ts";
30
+ export type { CockpitProtocol, ParsedCockpitUrl, } from "./utils/url-protocols.ts";
package/dist/index.js CHANGED
@@ -11,3 +11,4 @@ export { createImagePathTransformer, identityTransformer,
11
11
  FixImagePaths, } from "./transformers/image-path.js";
12
12
  export { createAssetPathTransformer, createPageLinkTransformer, composeTransformers, } from "./transformers/index.js";
13
13
  export { ImageSizeMode, MimeType } from "./methods/assets.js";
14
+ export { parseCockpitUrl, isCockpitPageUrl, isCockpitAssetUrl, extractPageId, extractAssetId, } from "./utils/url-protocols.js";
@@ -38,28 +38,38 @@ export declare enum MimeType {
38
38
  WEBP = "webp",
39
39
  BMP = "bmp"
40
40
  }
41
- export interface ImageAssetQueryParams {
41
+ /**
42
+ * Image transformation parameters for imageAssetById.
43
+ *
44
+ * At least one of `w` (width) or `h` (height) must be provided.
45
+ * The Cockpit CMS API requires this and returns a 400 error without it.
46
+ */
47
+ export type ImageAssetQueryParams = {
42
48
  m?: ImageSizeMode;
43
- w?: number;
44
- h?: number;
45
49
  q?: number;
46
50
  mime?: MimeType;
47
51
  re?: number;
48
52
  t?: string;
49
53
  o?: number;
50
- }
54
+ } & ({
55
+ w: number;
56
+ h?: number;
57
+ } | {
58
+ w?: number;
59
+ h: number;
60
+ });
51
61
  export interface AssetMethods {
52
62
  assetById<T = CockpitAsset>(assetId: string): Promise<T | null>;
53
63
  /**
54
64
  * Get a transformed image asset URL.
55
65
  *
56
- * **Important:** The `w` (width) or `h` (height) parameter is required by the API.
57
- * Without it, the API returns a 400 error.
66
+ * **Important:** At least one of `w` (width) or `h` (height) must be provided.
67
+ * The Cockpit CMS API requires this and returns a 400 error without it.
58
68
  *
59
69
  * @param assetId - The asset ID
60
70
  * @param queryParams - Image transformation parameters (w or h required)
61
71
  * @returns URL string to the generated image, or null if not found
62
72
  */
63
- imageAssetById(assetId: string, queryParams?: ImageAssetQueryParams): Promise<string | null>;
73
+ imageAssetById(assetId: string, queryParams: ImageAssetQueryParams): Promise<string | null>;
64
74
  }
65
75
  export declare function createAssetMethods(ctx: MethodContext): AssetMethods;
@@ -10,6 +10,7 @@ export interface PageByIdOptions {
10
10
  export interface PageByRouteOptions {
11
11
  locale?: string;
12
12
  populate?: number;
13
+ fallbackToDefault?: boolean;
13
14
  }
14
15
  export type CockpitPageType = "layout" | "collection" | "singleton" | "link";
15
16
  export interface CockpitPageMeta {
@@ -12,6 +12,9 @@ export function createPagesMethods(ctx) {
12
12
  });
13
13
  const result = await ctx.http.fetch(url);
14
14
  // Normalize response to always return { data, meta? }
15
+ // Note: The Cockpit /api/pages/pages endpoint returns a raw array even when skip
16
+ // is provided, unlike /api/content/items/{model} which returns { data, meta }.
17
+ // This means meta.total will not be available for pages() method.
15
18
  if (result === null) {
16
19
  return null;
17
20
  }
@@ -31,12 +34,34 @@ export function createPagesMethods(ctx) {
31
34
  },
32
35
  async pageByRoute(route, options = "default") {
33
36
  const opts = typeof options === "string" ? { locale: options } : options;
34
- const { locale = "default", populate } = opts;
37
+ const { locale = "default", populate, fallbackToDefault = false } = opts;
38
+ // Force populate: 0 to prevent route string issues
39
+ const queryOptions = { populate: populate ?? 0 };
35
40
  const url = ctx.url.build("/pages/page", {
36
41
  locale,
37
- queryParams: { route, populate },
42
+ queryParams: { route, ...queryOptions },
38
43
  });
39
- return ctx.http.fetch(url);
44
+ const result = await ctx.http.fetch(url);
45
+ // If found, return it
46
+ if (result)
47
+ return result;
48
+ // If not found and fallback enabled and not in default locale
49
+ if (fallbackToDefault && locale !== "default") {
50
+ // Try to find in default locale
51
+ const defaultUrl = ctx.url.build("/pages/page", {
52
+ locale: "default",
53
+ queryParams: { route, ...queryOptions },
54
+ });
55
+ const defaultResult = await ctx.http.fetch(defaultUrl);
56
+ // If found in default, get by ID in target locale
57
+ if (defaultResult?._id != null && defaultResult._id !== "") {
58
+ return this.pageById(defaultResult._id, {
59
+ locale,
60
+ populate: queryOptions.populate,
61
+ });
62
+ }
63
+ }
64
+ return null;
40
65
  },
41
66
  };
42
67
  }
@@ -28,7 +28,7 @@ export interface CockpitSettings {
28
28
  logo?: CockpitAsset | null;
29
29
  small?: CockpitAsset | null;
30
30
  favicon?: CockpitAsset | null;
31
- [key: string]: CockpitAsset | null | undefined;
31
+ [key: string]: CockpitAsset | null;
32
32
  };
33
33
  scripts?: {
34
34
  header?: string | null;
@@ -3,3 +3,4 @@
3
3
  */
4
4
  export { getTenantIds, resolveApiKey } from "./tenant.ts";
5
5
  export { generateCmsRouteReplacements, generateCollectionAndSingletonSlugRouteMap, } from "./route-map.ts";
6
+ export { parseCockpitUrl, isCockpitPageUrl, isCockpitAssetUrl, extractPageId, extractAssetId, } from "./url-protocols.ts";
@@ -3,3 +3,4 @@
3
3
  */
4
4
  export { getTenantIds, resolveApiKey } from "./tenant.js";
5
5
  export { generateCmsRouteReplacements, generateCollectionAndSingletonSlugRouteMap, } from "./route-map.js";
6
+ export { parseCockpitUrl, isCockpitPageUrl, isCockpitAssetUrl, extractPageId, extractAssetId, } from "./url-protocols.js";
@@ -0,0 +1,91 @@
1
+ /**
2
+ * URL protocol parsing utilities for Cockpit CMS
3
+ *
4
+ * Provides utilities to parse and work with Cockpit CMS URL protocols:
5
+ * - pages://id - References to pages by ID
6
+ * - assets://id - References to assets by ID
7
+ */
8
+ export type CockpitProtocol = "pages" | "assets" | "external";
9
+ export interface ParsedCockpitUrl {
10
+ protocol: CockpitProtocol;
11
+ id: string;
12
+ original: string;
13
+ }
14
+ /**
15
+ * Parses a Cockpit CMS URL and extracts protocol and ID information.
16
+ *
17
+ * @param url - The URL to parse (e.g., "pages://123", "assets://456", or "https://example.com")
18
+ * @returns Parsed URL object with protocol, id, and original URL, or null if invalid
19
+ *
20
+ * @example
21
+ * ```typescript
22
+ * parseCockpitUrl("pages://abc123")
23
+ * // { protocol: "pages", id: "abc123", original: "pages://abc123" }
24
+ *
25
+ * parseCockpitUrl("assets://xyz789")
26
+ * // { protocol: "assets", id: "xyz789", original: "assets://xyz789" }
27
+ *
28
+ * parseCockpitUrl("https://example.com")
29
+ * // { protocol: "external", id: "https://example.com", original: "https://example.com" }
30
+ *
31
+ * parseCockpitUrl(null)
32
+ * // null
33
+ * ```
34
+ */
35
+ export declare function parseCockpitUrl(url: string | null | undefined): ParsedCockpitUrl | null;
36
+ /**
37
+ * Checks if a URL is a Cockpit page reference (pages://id).
38
+ *
39
+ * @param url - The URL to check
40
+ * @returns True if the URL uses the pages:// protocol
41
+ *
42
+ * @example
43
+ * ```typescript
44
+ * isCockpitPageUrl("pages://123") // true
45
+ * isCockpitPageUrl("assets://456") // false
46
+ * isCockpitPageUrl("https://example.com") // false
47
+ * ```
48
+ */
49
+ export declare function isCockpitPageUrl(url: string | null | undefined): boolean;
50
+ /**
51
+ * Checks if a URL is a Cockpit asset reference (assets://id).
52
+ *
53
+ * @param url - The URL to check
54
+ * @returns True if the URL uses the assets:// protocol
55
+ *
56
+ * @example
57
+ * ```typescript
58
+ * isCockpitAssetUrl("assets://456") // true
59
+ * isCockpitAssetUrl("pages://123") // false
60
+ * isCockpitAssetUrl("https://example.com") // false
61
+ * ```
62
+ */
63
+ export declare function isCockpitAssetUrl(url: string | null | undefined): boolean;
64
+ /**
65
+ * Extracts the page ID from a Cockpit page URL.
66
+ *
67
+ * @param url - The URL to extract from
68
+ * @returns The page ID if valid pages:// URL, null otherwise
69
+ *
70
+ * @example
71
+ * ```typescript
72
+ * extractPageId("pages://abc123") // "abc123"
73
+ * extractPageId("assets://456") // null
74
+ * extractPageId("https://example.com") // null
75
+ * ```
76
+ */
77
+ export declare function extractPageId(url: string | null | undefined): string | null;
78
+ /**
79
+ * Extracts the asset ID from a Cockpit asset URL.
80
+ *
81
+ * @param url - The URL to extract from
82
+ * @returns The asset ID if valid assets:// URL, null otherwise
83
+ *
84
+ * @example
85
+ * ```typescript
86
+ * extractAssetId("assets://xyz789") // "xyz789"
87
+ * extractAssetId("pages://123") // null
88
+ * extractAssetId("https://example.com") // null
89
+ * ```
90
+ */
91
+ export declare function extractAssetId(url: string | null | undefined): string | null;
@@ -0,0 +1,110 @@
1
+ /**
2
+ * URL protocol parsing utilities for Cockpit CMS
3
+ *
4
+ * Provides utilities to parse and work with Cockpit CMS URL protocols:
5
+ * - pages://id - References to pages by ID
6
+ * - assets://id - References to assets by ID
7
+ */
8
+ /**
9
+ * Parses a Cockpit CMS URL and extracts protocol and ID information.
10
+ *
11
+ * @param url - The URL to parse (e.g., "pages://123", "assets://456", or "https://example.com")
12
+ * @returns Parsed URL object with protocol, id, and original URL, or null if invalid
13
+ *
14
+ * @example
15
+ * ```typescript
16
+ * parseCockpitUrl("pages://abc123")
17
+ * // { protocol: "pages", id: "abc123", original: "pages://abc123" }
18
+ *
19
+ * parseCockpitUrl("assets://xyz789")
20
+ * // { protocol: "assets", id: "xyz789", original: "assets://xyz789" }
21
+ *
22
+ * parseCockpitUrl("https://example.com")
23
+ * // { protocol: "external", id: "https://example.com", original: "https://example.com" }
24
+ *
25
+ * parseCockpitUrl(null)
26
+ * // null
27
+ * ```
28
+ */
29
+ export function parseCockpitUrl(url) {
30
+ if (url == null || typeof url !== "string")
31
+ return null;
32
+ const trimmed = url.trim();
33
+ if (trimmed === "")
34
+ return null;
35
+ if (trimmed.startsWith("pages://")) {
36
+ const id = trimmed.slice(8).split("?")[0] ?? "";
37
+ return { protocol: "pages", id, original: trimmed };
38
+ }
39
+ if (trimmed.startsWith("assets://")) {
40
+ const id = trimmed.slice(9).split("?")[0] ?? "";
41
+ return { protocol: "assets", id, original: trimmed };
42
+ }
43
+ return { protocol: "external", id: trimmed, original: trimmed };
44
+ }
45
+ /**
46
+ * Checks if a URL is a Cockpit page reference (pages://id).
47
+ *
48
+ * @param url - The URL to check
49
+ * @returns True if the URL uses the pages:// protocol
50
+ *
51
+ * @example
52
+ * ```typescript
53
+ * isCockpitPageUrl("pages://123") // true
54
+ * isCockpitPageUrl("assets://456") // false
55
+ * isCockpitPageUrl("https://example.com") // false
56
+ * ```
57
+ */
58
+ export function isCockpitPageUrl(url) {
59
+ return parseCockpitUrl(url)?.protocol === "pages";
60
+ }
61
+ /**
62
+ * Checks if a URL is a Cockpit asset reference (assets://id).
63
+ *
64
+ * @param url - The URL to check
65
+ * @returns True if the URL uses the assets:// protocol
66
+ *
67
+ * @example
68
+ * ```typescript
69
+ * isCockpitAssetUrl("assets://456") // true
70
+ * isCockpitAssetUrl("pages://123") // false
71
+ * isCockpitAssetUrl("https://example.com") // false
72
+ * ```
73
+ */
74
+ export function isCockpitAssetUrl(url) {
75
+ return parseCockpitUrl(url)?.protocol === "assets";
76
+ }
77
+ /**
78
+ * Extracts the page ID from a Cockpit page URL.
79
+ *
80
+ * @param url - The URL to extract from
81
+ * @returns The page ID if valid pages:// URL, null otherwise
82
+ *
83
+ * @example
84
+ * ```typescript
85
+ * extractPageId("pages://abc123") // "abc123"
86
+ * extractPageId("assets://456") // null
87
+ * extractPageId("https://example.com") // null
88
+ * ```
89
+ */
90
+ export function extractPageId(url) {
91
+ const parsed = parseCockpitUrl(url);
92
+ return parsed?.protocol === "pages" ? parsed.id : null;
93
+ }
94
+ /**
95
+ * Extracts the asset ID from a Cockpit asset URL.
96
+ *
97
+ * @param url - The URL to extract from
98
+ * @returns The asset ID if valid assets:// URL, null otherwise
99
+ *
100
+ * @example
101
+ * ```typescript
102
+ * extractAssetId("assets://xyz789") // "xyz789"
103
+ * extractAssetId("pages://123") // null
104
+ * extractAssetId("https://example.com") // null
105
+ * ```
106
+ */
107
+ export function extractAssetId(url) {
108
+ const parsed = parseCockpitUrl(url);
109
+ return parsed?.protocol === "assets" ? parsed.id : null;
110
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unchainedshop/cockpit-api",
3
- "version": "2.2.1",
3
+ "version": "2.3.0",
4
4
  "description": "A package to interact with the Cockpit CMS API, including functionalities to handle GraphQL requests and various CMS content manipulations.",
5
5
  "main": "dist/index.js",
6
6
  "homepage": "https://unchained.shop",