@agility/management-sdk 0.1.40 → 0.2.0-beta.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/README.md CHANGED
@@ -15,7 +15,7 @@
15
15
  ## About the Management API SDK
16
16
 
17
17
  - Provides a facility to developers to use the new Agility Management API more effectively.
18
- - Provides methods to perform operations on Assets, Batches, Containers, Content, Models, Pages, and Users.
18
+ - Provides methods to perform operations on Assets, Batches, Containers, Content, Models, Pages, and Users, and to search an instance.
19
19
  - **Content and Page Creation** - Create individual or multiple content items and pages (which automatically get added to batches).
20
20
  - **Essential batch workflow operations** - Perform publish, unpublish, approve, decline, and request approval operations on existing batches.
21
21
  - Ability to generate Content in bulk for a Website.
@@ -145,6 +145,10 @@ console.log('Content retrieved:', contentItem.fields.title);
145
145
  - **[PageMethods](./docs/page-methods.md)** - Page management operations (18 functions)
146
146
  - [getPage](./docs/page-methods.md#getpage), [getPageByPath](./docs/page-methods.md#getpagebypath), [getPageHistory](./docs/page-methods.md#getpagehistory), [getPageComments](./docs/page-methods.md#getpagecomments), [getPageList](./docs/page-methods.md#getpagelist), [getPageListByPageTemplateID](./docs/page-methods.md#getpagelistbypagetemplateid), [getPageListByPage](./docs/page-methods.md#getpagelistbypage), [getPageListByPageAndPageTemplateID](./docs/page-methods.md#getpagelistbypageandpagetemplateid), [getPageTree](./docs/page-methods.md#getpagetree), [getPageTemplateList](./docs/page-methods.md#getpagetemplatelist), [getPageSecurity](./docs/page-methods.md#getpagesecurity), [getPageItemTemplateList](./docs/page-methods.md#getpageitemtemplatelist), [getPageContentZones](./docs/page-methods.md#getpagecontentzones), [savePage](./docs/page-methods.md#savepage), [savePageSecurity](./docs/page-methods.md#savepagesecurity), [movePageItem](./docs/page-methods.md#movepageitem), [deletePage](./docs/page-methods.md#deletepage), [batchWorkflowPages](./docs/page-methods.md#batchworkflowpages)
147
147
 
148
+ ### Search
149
+ - **[SearchMethods](./docs/search-methods.md)** - Search everything in an instance (1 function)
150
+ - [search](./docs/search-methods.md#search)
151
+
148
152
  ### User Management
149
153
  - **[InstanceMethods](./docs/instance-methods.md)** - Instance-level operations (2 functions)
150
154
  - [getLocales](./docs/instance-methods.md#getlocales), [getFetchApiStatus](./docs/instance-methods.md#getfetchapistatus)
@@ -9,6 +9,7 @@ import { Options } from "./models/options";
9
9
  import { ServerUserMethods } from "./apiMethods/serverUserMethods";
10
10
  import { WebhookMethods } from "./apiMethods/webhookMethods";
11
11
  import { InstanceMethods } from "./apiMethods/instanceMethods";
12
+ import { SearchMethods } from "./apiMethods/searchMethods";
12
13
  export declare class ApiClient {
13
14
  _options: Options;
14
15
  contentMethods: ContentMethods;
@@ -19,6 +20,7 @@ export declare class ApiClient {
19
20
  instanceMethods: InstanceMethods;
20
21
  modelMethods: ModelMethods;
21
22
  pageMethods: PageMethods;
23
+ searchMethods: SearchMethods;
22
24
  serverUserMethods: ServerUserMethods;
23
25
  webhookMethods: WebhookMethods;
24
26
  constructor(options: Options);
package/dist/apiClient.js CHANGED
@@ -11,6 +11,7 @@ var pageMethods_1 = require("./apiMethods/pageMethods");
11
11
  var serverUserMethods_1 = require("./apiMethods/serverUserMethods");
12
12
  var webhookMethods_1 = require("./apiMethods/webhookMethods");
13
13
  var instanceMethods_1 = require("./apiMethods/instanceMethods");
14
+ var searchMethods_1 = require("./apiMethods/searchMethods");
14
15
  var ApiClient = /** @class */ (function () {
15
16
  function ApiClient(options) {
16
17
  this._options = options;
@@ -22,6 +23,7 @@ var ApiClient = /** @class */ (function () {
22
23
  this.instanceMethods = new instanceMethods_1.InstanceMethods(this._options);
23
24
  this.modelMethods = new modelMethods_1.ModelMethods(this._options);
24
25
  this.pageMethods = new pageMethods_1.PageMethods(this._options);
26
+ this.searchMethods = new searchMethods_1.SearchMethods(this._options);
25
27
  this.serverUserMethods = new serverUserMethods_1.ServerUserMethods(this._options);
26
28
  this.webhookMethods = new webhookMethods_1.WebhookMethods(this._options);
27
29
  }
@@ -0,0 +1,16 @@
1
+ import { Options } from "../models/options";
2
+ import { SearchRequest, SearchResult } from "../models/search";
3
+ import { ClientInstance } from "./clientInstance";
4
+ export declare class SearchMethods {
5
+ _options: Options;
6
+ _clientInstance: ClientInstance;
7
+ constructor(options: Options);
8
+ /**
9
+ * Search everything in an instance: content items, components, pages, assets, models and containers.
10
+ * Makes one request and never retries.
11
+ *
12
+ * Throws `SearchNotAvailableException` when search is not available for the instance yet (HTTP 501),
13
+ * and `Exception` otherwise, for example with `statusCode` 400 for a blank query or an unknown kind or state.
14
+ */
15
+ search(guid: string, request: SearchRequest): Promise<SearchResult>;
16
+ }
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __generator = (this && this.__generator) || function (thisArg, body) {
12
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
13
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
14
+ function verb(n) { return function (v) { return step([n, v]); }; }
15
+ function step(op) {
16
+ if (f) throw new TypeError("Generator is already executing.");
17
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
18
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
19
+ if (y = 0, t) op = [op[0] & 2, t.value];
20
+ switch (op[0]) {
21
+ case 0: case 1: t = op; break;
22
+ case 4: _.label++; return { value: op[1], done: false };
23
+ case 5: _.label++; y = op[1]; op = [0]; continue;
24
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
25
+ default:
26
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
27
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
28
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
29
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
30
+ if (t[2]) _.ops.pop();
31
+ _.trys.pop(); continue;
32
+ }
33
+ op = body.call(thisArg, _);
34
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
35
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36
+ }
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.SearchMethods = void 0;
40
+ var exception_1 = require("../models/exception");
41
+ var searchNotAvailableException_1 = require("../models/searchNotAvailableException");
42
+ var clientInstance_1 = require("./clientInstance");
43
+ var SearchMethods = /** @class */ (function () {
44
+ function SearchMethods(options) {
45
+ this._options = options;
46
+ this._clientInstance = new clientInstance_1.ClientInstance(this._options);
47
+ }
48
+ /**
49
+ * Search everything in an instance: content items, components, pages, assets, models and containers.
50
+ * Makes one request and never retries.
51
+ *
52
+ * Throws `SearchNotAvailableException` when search is not available for the instance yet (HTTP 501),
53
+ * and `Exception` otherwise, for example with `statusCode` 400 for a blank query or an unknown kind or state.
54
+ */
55
+ SearchMethods.prototype.search = function (guid, request) {
56
+ return __awaiter(this, void 0, void 0, function () {
57
+ var apiPath, resp, err_1;
58
+ var _a;
59
+ return __generator(this, function (_b) {
60
+ switch (_b.label) {
61
+ case 0:
62
+ _b.trys.push([0, 2, , 3]);
63
+ apiPath = "search";
64
+ return [4 /*yield*/, this._clientInstance.executePost(apiPath, guid, this._options.token, request)];
65
+ case 1:
66
+ resp = _b.sent();
67
+ return [2 /*return*/, resp.data];
68
+ case 2:
69
+ err_1 = _b.sent();
70
+ if (((_a = err_1 === null || err_1 === void 0 ? void 0 : err_1.response) === null || _a === void 0 ? void 0 : _a.status) === 501) {
71
+ throw new searchNotAvailableException_1.SearchNotAvailableException("Unable to search the instance.", err_1);
72
+ }
73
+ throw new exception_1.Exception("Unable to search the instance.", err_1);
74
+ case 3: return [2 /*return*/];
75
+ }
76
+ });
77
+ });
78
+ };
79
+ return SearchMethods;
80
+ }());
81
+ exports.SearchMethods = SearchMethods;
package/dist/index.d.ts CHANGED
@@ -14,7 +14,10 @@ export * from "./models/media";
14
14
  export * from "./models/model";
15
15
  export * from "./models/notification";
16
16
  export * from "./models/pageItem";
17
+ export * from "./models/geo";
17
18
  export * from "./models/pagedResult";
19
+ export * from "./models/search";
20
+ export * from "./models/searchNotAvailableException";
18
21
  export * from "./models/sitemap";
19
22
  export * from "./models/webhook";
20
23
  export * from "./models/webhookHistory";
package/dist/index.js CHANGED
@@ -30,7 +30,10 @@ __exportStar(require("./models/media"), exports);
30
30
  __exportStar(require("./models/model"), exports);
31
31
  __exportStar(require("./models/notification"), exports);
32
32
  __exportStar(require("./models/pageItem"), exports);
33
+ __exportStar(require("./models/geo"), exports);
33
34
  __exportStar(require("./models/pagedResult"), exports);
35
+ __exportStar(require("./models/search"), exports);
36
+ __exportStar(require("./models/searchNotAvailableException"), exports);
34
37
  __exportStar(require("./models/sitemap"), exports);
35
38
  __exportStar(require("./models/webhook"), exports);
36
39
  __exportStar(require("./models/webhookHistory"), exports);
@@ -1,3 +1,4 @@
1
+ import { GeoProperties } from "./geo";
1
2
  export declare class ContentItem {
2
3
  contentID: number;
3
4
  properties: ContentItemProperties;
@@ -5,6 +6,17 @@ export declare class ContentItem {
5
6
  [key: string]: any;
6
7
  };
7
8
  seo: SeoProperties | null;
9
+ /**
10
+ * GEO / AEO properties of the page this item generates. Only items in a list that backs a
11
+ * dynamic page carry them. On save, three states:
12
+ * - left out (`undefined`): everything stored is kept;
13
+ * - `null`: the whole block is cleared;
14
+ * - an object: each property in it is applied (a property set to `null` clears just that
15
+ * property, one left out is kept; see `GeoProperties`).
16
+ *
17
+ * Absent from responses when the item has no GEO data.
18
+ */
19
+ geo?: GeoProperties | null;
8
20
  scripts: ContentScripts | null;
9
21
  }
10
22
  export declare class ContentItemProperties {
@@ -24,6 +36,20 @@ export declare class SeoProperties {
24
36
  metaHTML: string | null;
25
37
  menuVisible: boolean | null;
26
38
  sitemapVisible: boolean | null;
39
+ /** The page's `<title>`, when it differs from the page title. */
40
+ title?: string | null;
41
+ /** The page's canonical URL override. */
42
+ canonicalUrl?: string | null;
43
+ /** The page's robots directives. */
44
+ robots?: SeoRobots | null;
45
+ /** The page's social share (Open Graph) image: an absolute http(s) URL or a site-relative path. */
46
+ ogImage?: string | null;
47
+ }
48
+ export declare class SeoRobots {
49
+ /** Whether search engines may index the page. */
50
+ index?: boolean | null;
51
+ /** Whether search engines may follow the page's links. */
52
+ follow?: boolean | null;
27
53
  }
28
54
  export declare class ContentScripts {
29
55
  top: string | null;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ContentList = exports.ContentScripts = exports.SeoProperties = exports.ContentItemProperties = exports.ContentItem = void 0;
3
+ exports.ContentList = exports.ContentScripts = exports.SeoRobots = exports.SeoProperties = exports.ContentItemProperties = exports.ContentItem = void 0;
4
4
  var ContentItem = /** @class */ (function () {
5
5
  function ContentItem() {
6
6
  }
@@ -19,6 +19,12 @@ var SeoProperties = /** @class */ (function () {
19
19
  return SeoProperties;
20
20
  }());
21
21
  exports.SeoProperties = SeoProperties;
22
+ var SeoRobots = /** @class */ (function () {
23
+ function SeoRobots() {
24
+ }
25
+ return SeoRobots;
26
+ }());
27
+ exports.SeoRobots = SeoRobots;
22
28
  var ContentScripts = /** @class */ (function () {
23
29
  function ContentScripts() {
24
30
  }
@@ -0,0 +1,38 @@
1
+ /**
2
+ * GEO / AEO (generative and answer engine optimization) properties of a page, or of a content item
3
+ * in a list that backs a dynamic page (`ContentItem.geo`, the item's own values).
4
+ *
5
+ * Writes are three-state, per property:
6
+ * - property left out (`undefined`), or the whole `geo` left out: the stored value is kept;
7
+ * - property set to `null`: the stored value is cleared;
8
+ * - property set to a value: the stored value is replaced.
9
+ *
10
+ * To clear the whole block, save the page with `geo: null`.
11
+ *
12
+ * `JSON.stringify` drops `undefined`, so a page read with `getPage` (or an item read with
13
+ * `getContentItem`), changed elsewhere and saved keeps its GEO data. Only set a property to `null`
14
+ * when you mean to clear it.
15
+ * Responses leave out properties that aren't set.
16
+ */
17
+ export declare class GeoProperties {
18
+ /** The schema.org page type. Defaults to `WebPage` when not set. */
19
+ schemaType?: GeoSchemaType | null;
20
+ /** A short, answer-first plain-text summary of the page. */
21
+ summary?: string | null;
22
+ /** Editor-supplied JSON-LD (an object, which may hold an `@graph`, or an array of objects). Must be valid JSON. */
23
+ structuredData?: {
24
+ [key: string]: any;
25
+ } | {
26
+ [key: string]: any;
27
+ }[] | null;
28
+ /** The page's AI-engine settings. */
29
+ ai?: GeoAiProperties | null;
30
+ }
31
+ /** The schema.org page types a page can declare. */
32
+ export type GeoSchemaType = "WebPage" | "AboutPage" | "ContactPage" | "CollectionPage" | "FAQPage" | "ItemPage" | "ProfilePage" | (string & {});
33
+ export declare class GeoAiProperties {
34
+ /** Whether the page is listed in llms.txt: `inherit` (follow sitemap visibility), `include` or `exclude`. */
35
+ llmsInclude?: "inherit" | "include" | "exclude" | null;
36
+ /** Whether AI crawlers may crawl the page: `inherit` (follow the site policy) or `block`. */
37
+ crawl?: "inherit" | "block" | null;
38
+ }
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GeoAiProperties = exports.GeoProperties = void 0;
4
+ /**
5
+ * GEO / AEO (generative and answer engine optimization) properties of a page, or of a content item
6
+ * in a list that backs a dynamic page (`ContentItem.geo`, the item's own values).
7
+ *
8
+ * Writes are three-state, per property:
9
+ * - property left out (`undefined`), or the whole `geo` left out: the stored value is kept;
10
+ * - property set to `null`: the stored value is cleared;
11
+ * - property set to a value: the stored value is replaced.
12
+ *
13
+ * To clear the whole block, save the page with `geo: null`.
14
+ *
15
+ * `JSON.stringify` drops `undefined`, so a page read with `getPage` (or an item read with
16
+ * `getContentItem`), changed elsewhere and saved keeps its GEO data. Only set a property to `null`
17
+ * when you mean to clear it.
18
+ * Responses leave out properties that aren't set.
19
+ */
20
+ var GeoProperties = /** @class */ (function () {
21
+ function GeoProperties() {
22
+ }
23
+ return GeoProperties;
24
+ }());
25
+ exports.GeoProperties = GeoProperties;
26
+ var GeoAiProperties = /** @class */ (function () {
27
+ function GeoAiProperties() {
28
+ }
29
+ return GeoAiProperties;
30
+ }());
31
+ exports.GeoAiProperties = GeoAiProperties;
@@ -1,4 +1,5 @@
1
1
  import { SeoProperties } from "./contentItem";
2
+ import { GeoProperties } from "./geo";
2
3
  export declare class PageItem {
3
4
  pageID: number | null;
4
5
  name: string | null;
@@ -12,6 +13,16 @@ export declare class PageItem {
12
13
  excludeFromOutputCache: boolean | null;
13
14
  visible: PageVisible | null;
14
15
  seo: SeoProperties | null;
16
+ /**
17
+ * GEO / AEO properties. On save, three states:
18
+ * - left out (`undefined`): everything stored is kept;
19
+ * - `null`: the whole block is cleared;
20
+ * - an object: each property in it is applied (a property set to `null` clears just that
21
+ * property, one left out is kept; see `GeoProperties`).
22
+ *
23
+ * Absent from responses when the page has no GEO data.
24
+ */
25
+ geo?: GeoProperties | null;
15
26
  scripts: PageScripts | null;
16
27
  dynamic: PageDynamic | null;
17
28
  properties: PageItemProperties | null;
@@ -0,0 +1,114 @@
1
+ /**
2
+ * A search across everything in an instance: content items, components, pages, assets, models and
3
+ * containers. Only `query` is required.
4
+ *
5
+ * Results are limited to what the caller may see: content, pages and containers for everyone,
6
+ * components and models with Develop or Manage, assets with Edit or Delete. Content and pages in
7
+ * containers or pages the caller can't read are left out.
8
+ */
9
+ export declare class SearchRequest {
10
+ /**
11
+ * The text to search for. Words match as prefixes ("newsl" finds "newsletter") and every word must
12
+ * match; text in double quotes matches as an exact phrase. A number also matches content, page,
13
+ * asset and model IDs exactly. A blank query is rejected (HTTP 400).
14
+ */
15
+ query: string;
16
+ /**
17
+ * The kinds of result to return. Defaults to every kind the caller may see. An unknown kind is
18
+ * rejected (HTTP 400). The facet counts always cover every kind the caller may see, whatever this is.
19
+ */
20
+ kinds?: SearchKind[] | null;
21
+ /** Only search content, components and pages in this locale (for example `en-us`). Omit it, or pass `*`, for every locale. */
22
+ locale?: string | null;
23
+ /** Only return content in these containers, by reference name. Limits the search to content kinds. */
24
+ containers?: string[] | null;
25
+ /** Only return content and components of these models, by reference name. Limits the search to content kinds. */
26
+ models?: string[] | null;
27
+ /** Only return content in this state. An unknown state is rejected (HTTP 400). Limits the search to content kinds. */
28
+ state?: SearchState | null;
29
+ /** Only return results modified on or after this date (an ISO 8601 string, or a `Date`). */
30
+ modifiedAfter?: string | Date | null;
31
+ /** Results to skip, for paging. Defaults to 0. */
32
+ skip?: number | null;
33
+ /** Results to return. Defaults to 25; the API clamps it to 1..100. */
34
+ take?: number | null;
35
+ }
36
+ /** A kind of search result. */
37
+ export type SearchKind = "content" | "component" | "page" | "asset" | "model" | "container" | (string & {});
38
+ /** A content state to filter on. `any` is the same as leaving it out. */
39
+ export type SearchState = "staging" | "published" | "unpublished" | "any";
40
+ /** The result of a search. */
41
+ export declare class SearchResult {
42
+ /** The query as it was searched. */
43
+ query: string | null;
44
+ /** True when nothing matched every word, so the results match ANY of the words instead. */
45
+ relaxed: boolean;
46
+ /**
47
+ * How many results there are of each kind the caller may see, keyed by kind, whichever kinds were
48
+ * requested. So it can drive tabs.
49
+ */
50
+ facets: {
51
+ [kind: string]: SearchFacet;
52
+ } | null;
53
+ /** How many results there are across the requested kinds. */
54
+ total: number;
55
+ /** The requested page of results, best match first. */
56
+ hits: SearchHit[] | null;
57
+ /** How far behind the search index is. */
58
+ indexing?: SearchIndexing | null;
59
+ }
60
+ /** The number of results of one kind. */
61
+ export declare class SearchFacet {
62
+ count: number;
63
+ /** True when there are more results than were counted; show the count as a minimum ("N+"). */
64
+ capped: boolean;
65
+ }
66
+ /** How far behind the search index is. */
67
+ export declare class SearchIndexing {
68
+ /** Changes not yet searchable. Usually 0; high after a big import. */
69
+ pending: number;
70
+ /** True while the instance is being indexed in the background: search again shortly. */
71
+ catchingUp: boolean;
72
+ }
73
+ /** One search result. Properties that don't apply to the result's kind are null or left out. */
74
+ export declare class SearchHit {
75
+ kind: SearchKind | null;
76
+ /** Content Item, List Item, Component, Page, Asset, Content Model, Component Model, Content List or Single Item. */
77
+ typeLabel?: string | null;
78
+ /** The result's display name. */
79
+ name?: string | null;
80
+ /** Where the result lives: its container, page path, folder or model reference name. */
81
+ context?: string | null;
82
+ /** The matching text, HTML-encoded, with each matched word wrapped in `<mark>`. */
83
+ snippet?: string | null;
84
+ /** Which fields matched: field names, or `_title`, `_id`, `_attachment`, `_file`, `_model`, `_container`. */
85
+ matchedFields?: string[] | null;
86
+ /** The relevance score the results are ordered by. Higher is better. */
87
+ score: number;
88
+ /** The locale of a content, component or page result. Null for assets and models. */
89
+ languageCode?: string | null;
90
+ /** The state of a content, component or page result (Staging, Published, ...). */
91
+ state?: string | null;
92
+ modifiedDate?: string | null;
93
+ modifiedBy?: string | null;
94
+ /** A path to open the result in the Content Manager, relative to the instance (for example `content/list-12/listitem-34`). */
95
+ viewLink?: string | null;
96
+ /** The content ID of a content item, component or page's content. */
97
+ contentID?: number | null;
98
+ /** The ID of the container a content item or component lives in. */
99
+ containerID?: number | null;
100
+ containerReferenceName?: string | null;
101
+ /** The page ID of a page, or of a page a component sits on. */
102
+ pageID?: number | null;
103
+ pagePath?: string | null;
104
+ channel?: string | null;
105
+ mediaID?: number | null;
106
+ /** The asset's URL. */
107
+ url?: string | null;
108
+ /** The asset's MIME type. */
109
+ contentType?: string | null;
110
+ /** The asset's size in bytes. */
111
+ size?: number | null;
112
+ modelID?: number | null;
113
+ modelReferenceName?: string | null;
114
+ }
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SearchHit = exports.SearchIndexing = exports.SearchFacet = exports.SearchResult = exports.SearchRequest = void 0;
4
+ /**
5
+ * A search across everything in an instance: content items, components, pages, assets, models and
6
+ * containers. Only `query` is required.
7
+ *
8
+ * Results are limited to what the caller may see: content, pages and containers for everyone,
9
+ * components and models with Develop or Manage, assets with Edit or Delete. Content and pages in
10
+ * containers or pages the caller can't read are left out.
11
+ */
12
+ var SearchRequest = /** @class */ (function () {
13
+ function SearchRequest() {
14
+ }
15
+ return SearchRequest;
16
+ }());
17
+ exports.SearchRequest = SearchRequest;
18
+ /** The result of a search. */
19
+ var SearchResult = /** @class */ (function () {
20
+ function SearchResult() {
21
+ }
22
+ return SearchResult;
23
+ }());
24
+ exports.SearchResult = SearchResult;
25
+ /** The number of results of one kind. */
26
+ var SearchFacet = /** @class */ (function () {
27
+ function SearchFacet() {
28
+ }
29
+ return SearchFacet;
30
+ }());
31
+ exports.SearchFacet = SearchFacet;
32
+ /** How far behind the search index is. */
33
+ var SearchIndexing = /** @class */ (function () {
34
+ function SearchIndexing() {
35
+ }
36
+ return SearchIndexing;
37
+ }());
38
+ exports.SearchIndexing = SearchIndexing;
39
+ /** One search result. Properties that don't apply to the result's kind are null or left out. */
40
+ var SearchHit = /** @class */ (function () {
41
+ function SearchHit() {
42
+ }
43
+ return SearchHit;
44
+ }());
45
+ exports.SearchHit = SearchHit;
@@ -0,0 +1,12 @@
1
+ import { Exception } from "./exception";
2
+ /**
3
+ * Thrown by `searchMethods.search` when the API answers 501: search is not available for this
4
+ * instance yet. It isn't a transient failure, so don't retry it; fall back to listing or filtering
5
+ * content instead.
6
+ *
7
+ * Check with `err instanceof SearchNotAvailableException`, or `err.name === "SearchNotAvailableException"`
8
+ * when more than one copy of the SDK may be loaded. `statusCode` is 501.
9
+ */
10
+ export declare class SearchNotAvailableException extends Exception {
11
+ constructor(message: string, inner?: Error);
12
+ }
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ var __extends = (this && this.__extends) || (function () {
3
+ var extendStatics = function (d, b) {
4
+ extendStatics = Object.setPrototypeOf ||
5
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
6
+ function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
7
+ return extendStatics(d, b);
8
+ };
9
+ return function (d, b) {
10
+ if (typeof b !== "function" && b !== null)
11
+ throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
12
+ extendStatics(d, b);
13
+ function __() { this.constructor = d; }
14
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
15
+ };
16
+ })();
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.SearchNotAvailableException = void 0;
19
+ var exception_1 = require("./exception");
20
+ /**
21
+ * Thrown by `searchMethods.search` when the API answers 501: search is not available for this
22
+ * instance yet. It isn't a transient failure, so don't retry it; fall back to listing or filtering
23
+ * content instead.
24
+ *
25
+ * Check with `err instanceof SearchNotAvailableException`, or `err.name === "SearchNotAvailableException"`
26
+ * when more than one copy of the SDK may be loaded. `statusCode` is 501.
27
+ */
28
+ var SearchNotAvailableException = /** @class */ (function (_super) {
29
+ __extends(SearchNotAvailableException, _super);
30
+ function SearchNotAvailableException(message, inner) {
31
+ var _this = _super.call(this, message, inner) || this;
32
+ // The SDK compiles to ES5, where a subclass of Error loses its prototype; restore it so
33
+ // `instanceof SearchNotAvailableException` works.
34
+ Object.setPrototypeOf(_this, SearchNotAvailableException.prototype);
35
+ _this.name = "SearchNotAvailableException";
36
+ _this.statusCode = 501;
37
+ return _this;
38
+ }
39
+ return SearchNotAvailableException;
40
+ }(exception_1.Exception));
41
+ exports.SearchNotAvailableException = SearchNotAvailableException;
@@ -337,6 +337,16 @@ const contentItems = [
337
337
  const savedIds = await client.contentMethods.saveContentItems(contentItems, 'your-guid', 'en-us');
338
338
  ```
339
339
 
340
+ ### GEO / AEO on dynamic page list items
341
+
342
+ An item in a list that backs a dynamic page can carry a top-level `geo` object (`schemaType`, `summary`, `structuredData`, `ai`), the same shape as a page's `geo` (see [savePage](./page-methods.md#savepage)). `saveContentItem` and `saveContentItems` send it as given, with the same three states: leave `geo` (or a property in it) out to keep what's stored, set a property to `null` to clear it, send `geo: null` to clear the whole block. Items in other lists don't carry `geo`, and `getContentItem` leaves it out when the item has none.
343
+
344
+ ```typescript
345
+ const item = await client.contentMethods.getContentItem(123, 'your-guid', 'en-us');
346
+ item.geo = { ...item.geo, summary: 'The post in one sentence.', ai: { crawl: 'block' } };
347
+ await client.contentMethods.saveContentItem(item, 'your-guid', 'en-us');
348
+ ```
349
+
340
350
  ---
341
351
 
342
352
  ## getContentItems
@@ -525,6 +525,38 @@ console.log('Batch created with ID:', batchId);
525
525
  **Error Handling:**
526
526
  - Throws `Exception` when validation fails or save operation fails
527
527
 
528
+ **GEO / AEO and the extra SEO properties:**
529
+
530
+ A page can carry a top-level `geo` object (`schemaType`, `summary`, `structuredData`, `ai`) and four more `seo` properties (`title`, `canonicalUrl`, `robots`, `ogImage`). On save, each of these properties has three states:
531
+
532
+ | In the object you save | Effect |
533
+ |---|---|
534
+ | Property left out (`undefined`), or the whole `geo` left out | The stored value is kept |
535
+ | `geo: null` | The whole `geo` block is cleared |
536
+ | Property set to `null` | The stored value is cleared |
537
+ | Property set to a value | The stored value is replaced |
538
+
539
+ `savePage` sends the object as JSON, and `JSON.stringify` drops `undefined`, so a read-modify-save that doesn't touch these properties keeps them. Don't set them to `null` unless you mean to clear them. Responses leave out any property that isn't set.
540
+
541
+ ```typescript
542
+ const page = await apiClient.pageMethods.getPage(123, guid, locale);
543
+ page.geo = {
544
+ ...page.geo,
545
+ schemaType: 'AboutPage',
546
+ summary: 'Who we are, in two sentences.',
547
+ structuredData: { '@context': 'https://schema.org', '@type': 'Organization', name: 'Example' },
548
+ ai: { llmsInclude: 'include' }
549
+ };
550
+ page.seo = { ...page.seo, title: 'About us | Example', robots: { index: true, follow: true } };
551
+ await apiClient.pageMethods.savePage(page, guid, locale);
552
+
553
+ // Clear the summary only; everything else in geo is kept
554
+ await apiClient.pageMethods.savePage({ ...page, geo: { summary: null } }, guid, locale);
555
+
556
+ // Clear all of geo
557
+ await apiClient.pageMethods.savePage({ ...page, geo: null }, guid, locale);
558
+ ```
559
+
528
560
  ### savePageSecurity
529
561
 
530
562
  Updates security settings for a specific page.
@@ -0,0 +1,129 @@
1
+ # Agility CMS & Management API TypeScript SDK
2
+
3
+ ## SearchMethods
4
+
5
+ This class searches everything in an instance in one call: content items, components, pages, assets, models and containers. Results are ranked across kinds, best match first, and come with a count per kind so they can drive tabs.
6
+
7
+ **Important Notes:**
8
+ - Words match as prefixes (`newsl` finds `newsletter`) and every word must match; text in double quotes matches as an exact phrase. A number also matches content, page, asset and model IDs exactly
9
+ - If nothing matches every word, the results match **any** of the words instead and `relaxed` is `true`
10
+ - You only see what your permissions allow: content, pages and containers for everyone; components and models need Develop or Manage; assets need Edit or Delete; content and pages in containers or pages you can't read are left out. The API applies this, so there's nothing to filter on the client
11
+ - Changes are searchable a few seconds after they are saved
12
+ - Search is not yet available on every instance. When it isn't, `search` throws a [`SearchNotAvailableException`](#searchnotavailableexception)
13
+
14
+ ### Function List
15
+ - [search](#search) - Searches an instance
16
+
17
+ ### Reference
18
+ - [The SearchRequest object](#the-searchrequest-object)
19
+ - [The SearchResult object](#the-searchresult-object)
20
+ - [SearchNotAvailableException](#searchnotavailableexception)
21
+
22
+ ---
23
+
24
+ ### search
25
+
26
+ Searches an instance. Makes one request and never retries.
27
+
28
+ | Parameter | Type | Required | Description |
29
+ |-----------|------|----------|-------------|
30
+ | `guid` | `string` | Yes | Current website GUID |
31
+ | `request` | `SearchRequest` | Yes | What to search for, and optional filters and paging. Only `query` is required |
32
+
33
+ **Returns:** `Promise<SearchResult>`
34
+
35
+ **Usage Example:**
36
+ ```typescript
37
+ import * as mgmtApi from '@agility/management-sdk';
38
+
39
+ const result = await apiClient.searchMethods.search(guid, { query: 'newsletter' });
40
+
41
+ console.log(`${result.total} results${result.relaxed ? ' (matching any word)' : ''}`);
42
+ for (const [kind, facet] of Object.entries(result.facets ?? {})) {
43
+ console.log(`${kind}: ${facet.count}${facet.capped ? '+' : ''}`);
44
+ }
45
+ result.hits?.forEach(hit => {
46
+ console.log(`[${hit.typeLabel}] ${hit.name} in ${hit.context} -> ${hit.viewLink}`);
47
+ });
48
+
49
+ // Only published content and pages in en-us, second page of 10
50
+ const page2 = await apiClient.searchMethods.search(guid, {
51
+ query: '"spring sale"',
52
+ kinds: ['content', 'page'],
53
+ locale: 'en-us',
54
+ state: 'published',
55
+ skip: 10,
56
+ take: 10
57
+ });
58
+ ```
59
+
60
+ **Error Handling:**
61
+ - Throws `SearchNotAvailableException` (`statusCode` 501) when search is not available for the instance yet
62
+ - Throws `Exception` with `statusCode` 400 for a blank query, an unknown kind or an unknown state
63
+ - Throws `Exception` when the search fails for any other reason
64
+
65
+ ---
66
+
67
+ ### The SearchRequest object
68
+
69
+ | Property | Type | Description |
70
+ |----------|------|-------------|
71
+ | `query` | `string` | **Required.** The text to search for |
72
+ | `kinds` | `SearchKind[]` | Any of `content`, `component`, `page`, `asset`, `model`, `container`. Defaults to every kind you can see. The facet counts always cover every kind you can see, whatever this is |
73
+ | `locale` | `string` | Only search content, components and pages in this locale (for example `en-us`). Omit it, or pass `*`, for every locale |
74
+ | `containers` | `string[]` | Only return content in these containers, by reference name. Limits the search to content kinds |
75
+ | `models` | `string[]` | Only return content and components of these models, by reference name. Limits the search to content kinds |
76
+ | `state` | `SearchState` | `staging`, `published`, `unpublished` or `any`. Limits the search to content kinds |
77
+ | `modifiedAfter` | `string \| Date` | Only return results modified on or after this date |
78
+ | `skip` | `number` | Results to skip, for paging (default: 0) |
79
+ | `take` | `number` | Results to return (default: 25, at most 100) |
80
+
81
+ ### The SearchResult object
82
+
83
+ | Property | Type | Description |
84
+ |----------|------|-------------|
85
+ | `query` | `string` | The query as it was searched |
86
+ | `relaxed` | `boolean` | `true` when nothing matched every word, so the results match any of the words |
87
+ | `facets` | `{ [kind: string]: SearchFacet }` | `{ count, capped }` for each kind you can see, whichever kinds you asked for. When `capped` is `true` there are more than `count`: show it as "N+" |
88
+ | `total` | `number` | How many results there are across the requested kinds |
89
+ | `hits` | `SearchHit[]` | The requested page of results, best match first |
90
+ | `indexing` | `SearchIndexing` | `{ pending, catchingUp }`: `pending` is the number of changes not yet searchable (usually 0, high after a big import); `catchingUp` is `true` while the instance is being indexed in the background, so search again shortly |
91
+
92
+ Each `SearchHit` has a `kind`, `typeLabel`, `name`, `context` (its container, page path, folder or model reference name), `snippet` (HTML-encoded, with matched words wrapped in `<mark>`), `matchedFields`, `score`, and a `viewLink` to open it in the Content Manager, relative to the instance. The IDs and details that apply to its kind are set too: `contentID`, `containerID`, `containerReferenceName`, `pageID`, `pagePath`, `channel`, `languageCode`, `state`, `modifiedDate`, `modifiedBy`, `mediaID`, `url`, `contentType`, `size`, `modelID` and `modelReferenceName`. The rest are `null` or left out.
93
+
94
+ ### SearchNotAvailableException
95
+
96
+ Thrown when the API answers 501: search is not available for this instance yet. It isn't a transient failure, so don't retry it.
97
+
98
+ ```typescript
99
+ import { SearchNotAvailableException } from '@agility/management-sdk';
100
+
101
+ try {
102
+ const result = await apiClient.searchMethods.search(guid, { query: 'newsletter' });
103
+ } catch (err) {
104
+ if (err instanceof SearchNotAvailableException) {
105
+ // Fall back to listing or filtering content instead.
106
+ } else {
107
+ throw err;
108
+ }
109
+ }
110
+ ```
111
+
112
+ When more than one copy of the SDK may be loaded, check `err.name === 'SearchNotAvailableException'` instead. `err.statusCode` is `501`.
113
+
114
+ ---
115
+
116
+ ## Navigation
117
+ - [← Back to Main Documentation](../README.md)
118
+ - [Authentication & Setup](./auth.md)
119
+ - [AssetMethods](./asset-methods.md)
120
+ - [BatchMethods](./batch-methods.md)
121
+ - [ContainerMethods](./container-methods.md)
122
+ - [ContentMethods](./content-methods.md)
123
+ - [InstanceMethods](./instance-methods.md)
124
+ - [InstanceUserMethods](./instance-user-methods.md)
125
+ - [ModelMethods](./model-methods.md)
126
+ - [PageMethods](./page-methods.md)
127
+ - **SearchMethods** *(current)*
128
+ - [ServerUserMethods](./server-user-methods.md)
129
+ - [WebhookMethods](./webhook-methods.md)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agility/management-sdk",
3
- "version": "0.1.40",
3
+ "version": "0.2.0-beta.2",
4
4
  "description": "Agility CMS Tyescript SDK for Management API.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -15,7 +15,7 @@
15
15
  "clean": "git clean -Xf && rm -rf ./dist",
16
16
  "build": "tsc",
17
17
  "prepare": "yarn build",
18
- "test": "echo \"Error: no test specified\" && exit 1"
18
+ "test": "tsc && node --test 'test/**/*.test.js'"
19
19
  },
20
20
  "keywords": [
21
21
  "typescript",