@dotcms/client 1.0.0-next.6 → 1.0.1

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.
Files changed (51) hide show
  1. package/.eslintrc.json +18 -0
  2. package/jest.config.ts +15 -0
  3. package/package.json +7 -24
  4. package/project.json +73 -0
  5. package/src/lib/client/client.spec.ts +147 -0
  6. package/src/lib/client/client.ts +125 -0
  7. package/src/lib/client/content/builders/collection/collection.spec.ts +514 -0
  8. package/src/lib/client/content/builders/collection/{collection.d.ts → collection.ts} +210 -19
  9. package/src/lib/client/content/builders/query/lucene-syntax/{Equals.d.ts → Equals.ts} +45 -11
  10. package/src/lib/client/content/builders/query/lucene-syntax/{Field.d.ts → Field.ts} +13 -5
  11. package/src/lib/client/content/builders/query/lucene-syntax/{NotOperand.d.ts → NotOperand.ts} +13 -5
  12. package/src/lib/client/content/builders/query/lucene-syntax/{Operand.d.ts → Operand.ts} +21 -7
  13. package/src/lib/client/content/builders/query/query.spec.ts +159 -0
  14. package/src/lib/client/content/builders/query/{query.d.ts → query.ts} +16 -5
  15. package/src/lib/client/content/builders/query/utils/{index.d.ts → index.ts} +49 -12
  16. package/src/lib/client/content/{content-api.d.ts → content-api.ts} +14 -4
  17. package/src/lib/client/content/shared/{const.d.ts → const.ts} +5 -3
  18. package/src/lib/client/content/shared/{types.d.ts → types.ts} +18 -2
  19. package/src/lib/client/content/shared/{utils.d.ts → utils.ts} +9 -1
  20. package/src/lib/client/models/{index.d.ts → index.ts} +8 -1
  21. package/src/lib/client/navigation/navigation-api.spec.ts +167 -0
  22. package/src/lib/client/navigation/navigation-api.ts +62 -0
  23. package/src/lib/client/page/page-api.spec.ts +359 -0
  24. package/src/lib/client/page/page-api.ts +197 -0
  25. package/src/lib/client/page/utils.ts +291 -0
  26. package/src/lib/utils/graphql/transforms.spec.ts +250 -0
  27. package/src/lib/utils/graphql/transforms.ts +128 -0
  28. package/tsconfig.json +22 -0
  29. package/tsconfig.lib.json +13 -0
  30. package/tsconfig.spec.json +9 -0
  31. package/index.cjs.d.ts +0 -1
  32. package/index.cjs.default.js +0 -1
  33. package/index.cjs.js +0 -1592
  34. package/index.cjs.mjs +0 -2
  35. package/index.esm.d.ts +0 -1
  36. package/index.esm.js +0 -1590
  37. package/internal.cjs.d.ts +0 -1
  38. package/internal.cjs.default.js +0 -1
  39. package/internal.cjs.js +0 -85
  40. package/internal.cjs.mjs +0 -2
  41. package/internal.esm.d.ts +0 -1
  42. package/internal.esm.js +0 -83
  43. package/src/lib/client/client.d.ts +0 -56
  44. package/src/lib/client/navigation/navigation-api.d.ts +0 -14
  45. package/src/lib/client/page/page-api.d.ts +0 -95
  46. package/src/lib/client/page/utils.d.ts +0 -41
  47. package/src/lib/utils/graphql/transforms.d.ts +0 -13
  48. /package/src/{index.d.ts → index.ts} +0 -0
  49. /package/src/{internal.d.ts → internal.ts} +0 -0
  50. /package/src/lib/client/content/builders/query/lucene-syntax/{index.d.ts → index.ts} +0 -0
  51. /package/src/lib/utils/{index.d.ts → index.ts} +0 -0
package/.eslintrc.json ADDED
@@ -0,0 +1,18 @@
1
+ {
2
+ "extends": ["../../../.eslintrc.base.json"],
3
+ "ignorePatterns": ["!**/*"],
4
+ "overrides": [
5
+ {
6
+ "files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
7
+ "rules": {}
8
+ },
9
+ {
10
+ "files": ["*.ts", "*.tsx"],
11
+ "rules": {}
12
+ },
13
+ {
14
+ "files": ["*.js", "*.jsx"],
15
+ "rules": {}
16
+ }
17
+ ]
18
+ }
package/jest.config.ts ADDED
@@ -0,0 +1,15 @@
1
+ /* eslint-disable */
2
+ export default {
3
+ displayName: 'sdk-client',
4
+ preset: '../../../jest.preset.js',
5
+ transform: {
6
+ '^.+\\.[tj]s$': [
7
+ 'ts-jest',
8
+ {
9
+ tsconfig: '<rootDir>/tsconfig.spec.json'
10
+ }
11
+ ]
12
+ },
13
+ moduleFileExtensions: ['ts', 'js', 'html'],
14
+ coverageDirectory: '../../../coverage/libs/sdk/client'
15
+ };
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@dotcms/client",
3
- "version": "1.0.0-next.6",
3
+ "version": "1.0.1",
4
4
  "description": "Official JavaScript library for interacting with DotCMS REST APIs.",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "git+https://github.com/dotCMS/core.git#main"
8
8
  },
9
9
  "dependencies": {
10
- "consola": "^3.4.2"
10
+ "consola": "^3.4.2"
11
11
  },
12
12
  "devDependencies": {
13
13
  "@dotcms/types": "latest"
@@ -24,27 +24,13 @@
24
24
  ],
25
25
  "exports": {
26
26
  "./package.json": "./package.json",
27
- ".": {
28
- "module": "./index.esm.js",
29
- "types": "./index.esm.d.ts",
30
- "import": "./index.cjs.mjs",
31
- "default": "./index.cjs.js"
32
- },
33
- "./internal": {
34
- "module": "./internal.esm.js",
35
- "types": "./internal.esm.d.ts",
36
- "import": "./internal.cjs.mjs",
37
- "default": "./internal.cjs.js"
38
- }
27
+ ".": "./src/index.ts",
28
+ "./internal": "./src/internal.ts"
39
29
  },
40
30
  "typesVersions": {
41
31
  "*": {
42
- ".": [
43
- "./src/index.d.ts"
44
- ],
45
- "internal": [
46
- "./src/internal.d.ts"
47
- ]
32
+ ".": ["./src/index.d.ts"],
33
+ "internal": ["./src/internal.d.ts"]
48
34
  }
49
35
  },
50
36
  "author": "dotcms <dev@dotcms.com>",
@@ -52,8 +38,5 @@
52
38
  "bugs": {
53
39
  "url": "https://github.com/dotCMS/core/issues"
54
40
  },
55
- "homepage": "https://github.com/dotCMS/core/tree/main/core-web/libs/sdk/client/README.md",
56
- "module": "./index.esm.js",
57
- "main": "./index.cjs.js",
58
- "types": "./index.esm.d.ts"
41
+ "homepage": "https://github.com/dotCMS/core/tree/main/core-web/libs/sdk/client/README.md"
59
42
  }
package/project.json ADDED
@@ -0,0 +1,73 @@
1
+ {
2
+ "name": "sdk-client",
3
+ "$schema": "../../../node_modules/nx/schemas/project-schema.json",
4
+ "sourceRoot": "libs/sdk/client/src",
5
+ "projectType": "library",
6
+ "targets": {
7
+ "build": {
8
+ "executor": "@nx/rollup:rollup",
9
+ "outputs": ["{options.outputPath}"],
10
+ "options": {
11
+ "format": ["esm", "cjs"],
12
+ "compiler": "tsc",
13
+ "additionalEntryPoints": ["libs/sdk/client/src/internal.ts"],
14
+ "generateExportsField": true,
15
+ "outputPath": "dist/libs/sdk/client",
16
+ "assets": [{ "input": "libs/sdk/client", "output": ".", "glob": "*.md" }],
17
+ "main": "libs/sdk/client/src/index.ts",
18
+ "tsConfig": "libs/sdk/client/tsconfig.lib.json"
19
+ }
20
+ },
21
+ "build:js": {
22
+ "executor": "@nx/esbuild:esbuild",
23
+ "outputs": ["{options.outputPath}"],
24
+ "options": {
25
+ "outputPath": "../dotCMS/src/main/webapp/html/js/editor-js",
26
+ "outputFileName": "sdk-editor",
27
+ "format": ["esm"],
28
+ "tsConfig": "libs/sdk/client/tsconfig.lib.json",
29
+ "project": "libs/sdk/client/package.json",
30
+ "entryFile": "libs/sdk/client/src/lib/deprecated/editor/sdk-editor-vtl.ts",
31
+ "external": ["react/jsx-runtime"],
32
+ "rollupConfig": "@nrwl/react/plugins/bundle-rollup",
33
+ "compiler": "tsc",
34
+ "extractCss": false,
35
+ "minify": true
36
+ }
37
+ },
38
+ "publish": {
39
+ "executor": "nx:run-commands",
40
+ "options": {
41
+ "command": "node tools/scripts/publish.mjs sdk-client {args.ver} {args.tag}"
42
+ },
43
+ "dependsOn": ["build"]
44
+ },
45
+ "nx-release-publish": {
46
+ "options": {
47
+ "packageRoot": "dist/libs/sdk/client"
48
+ }
49
+ },
50
+ "lint": {
51
+ "executor": "@nx/eslint:lint",
52
+ "outputs": ["{options.outputFile}"],
53
+ "options": {
54
+ "lintFilePatterns": ["libs/sdk/client/**/*.ts"]
55
+ }
56
+ },
57
+ "test": {
58
+ "executor": "@nrwl/jest:jest",
59
+ "outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
60
+ "options": {
61
+ "jestConfig": "libs/sdk/client/jest.config.ts",
62
+ "passWithNoTests": true
63
+ },
64
+ "configurations": {
65
+ "ci": {
66
+ "ci": true,
67
+ "codeCoverage": true
68
+ }
69
+ }
70
+ }
71
+ },
72
+ "tags": []
73
+ }
@@ -0,0 +1,147 @@
1
+ import { DotCMSClientConfig, RequestOptions } from '@dotcms/types';
2
+
3
+ import { createDotCMSClient } from './client';
4
+ import { Content } from './content/content-api';
5
+ import { NavigationClient } from './navigation/navigation-api';
6
+ import { PageClient } from './page/page-api';
7
+
8
+ // Mock the dependencies
9
+ jest.mock('./content/content-api');
10
+ jest.mock('./navigation/navigation-api');
11
+ jest.mock('./page/page-api');
12
+
13
+ describe('DotCMSClient', () => {
14
+ const originalTypeError = global.TypeError;
15
+ const mockTypeError = jest.fn().mockImplementation((...args) => new originalTypeError(...args));
16
+ const validConfig: DotCMSClientConfig = {
17
+ dotcmsUrl: 'https://demo.dotcms.com',
18
+ authToken: 'test-token',
19
+ siteId: 'test-site',
20
+ requestOptions: {
21
+ headers: {
22
+ 'Content-Type': 'application/json'
23
+ }
24
+ }
25
+ };
26
+
27
+ beforeEach(() => {
28
+ jest.clearAllMocks();
29
+ global.TypeError = mockTypeError as unknown as ErrorConstructor;
30
+ });
31
+
32
+ afterAll(() => {
33
+ global.TypeError = originalTypeError;
34
+ });
35
+
36
+ it('should initialize sub-clients with correct parameters', () => {
37
+ createDotCMSClient(validConfig);
38
+
39
+ const expectedRequestOptions: RequestOptions = {
40
+ headers: {
41
+ 'Content-Type': 'application/json',
42
+ Authorization: 'Bearer test-token'
43
+ }
44
+ };
45
+
46
+ expect(PageClient).toHaveBeenCalledWith(
47
+ expect.objectContaining({
48
+ dotcmsUrl: 'https://demo.dotcms.com',
49
+ authToken: 'test-token',
50
+ siteId: 'test-site'
51
+ }),
52
+ expectedRequestOptions
53
+ );
54
+
55
+ expect(Content).toHaveBeenCalledWith(expectedRequestOptions, 'https://demo.dotcms.com');
56
+
57
+ expect(NavigationClient).toHaveBeenCalledWith(
58
+ expect.objectContaining({
59
+ dotcmsUrl: 'https://demo.dotcms.com',
60
+ authToken: 'test-token',
61
+ siteId: 'test-site'
62
+ }),
63
+ expectedRequestOptions
64
+ );
65
+ });
66
+
67
+ it('should add authorization header to request options', () => {
68
+ const configWithoutHeaders: DotCMSClientConfig = {
69
+ dotcmsUrl: 'https://demo.dotcms.com',
70
+ authToken: 'test-token'
71
+ };
72
+
73
+ createDotCMSClient(configWithoutHeaders);
74
+
75
+ expect(PageClient).toHaveBeenCalledWith(
76
+ expect.anything(),
77
+ expect.objectContaining({
78
+ headers: {
79
+ Authorization: 'Bearer test-token'
80
+ }
81
+ })
82
+ );
83
+ });
84
+
85
+ it('should preserve existing headers when adding authorization', () => {
86
+ createDotCMSClient(validConfig);
87
+
88
+ expect(PageClient).toHaveBeenCalledWith(
89
+ expect.anything(),
90
+ expect.objectContaining({
91
+ headers: {
92
+ 'Content-Type': 'application/json',
93
+ Authorization: 'Bearer test-token'
94
+ }
95
+ })
96
+ );
97
+ });
98
+
99
+ describe('validation and normalization', () => {
100
+ it('should throw TypeError when dotcmsUrl is invalid', () => {
101
+ const invalidConfig = {
102
+ ...validConfig,
103
+ dotcmsUrl: 'invalid-url'
104
+ };
105
+
106
+ try {
107
+ createDotCMSClient(invalidConfig);
108
+ fail('Expected TypeError to be thrown');
109
+ } catch (error) {
110
+ // This is expected, verify the error
111
+ }
112
+
113
+ expect(mockTypeError).toHaveBeenCalledWith(
114
+ "Invalid configuration - 'dotcmsUrl' must be a valid URL"
115
+ );
116
+ });
117
+
118
+ it('should throw TypeError when authToken is missing', () => {
119
+ const invalidConfig = {
120
+ ...validConfig,
121
+ authToken: ''
122
+ };
123
+
124
+ try {
125
+ createDotCMSClient(invalidConfig);
126
+ fail('Expected TypeError to be thrown');
127
+ } catch (error) {
128
+ // This is expected, verify the error
129
+ }
130
+
131
+ expect(mockTypeError).toHaveBeenCalledWith(
132
+ "Invalid configuration - 'authToken' is required"
133
+ );
134
+ });
135
+
136
+ it('should extract origin from dotcmsUrl', () => {
137
+ const configWithPath = {
138
+ ...validConfig,
139
+ dotcmsUrl: 'https://demo.dotcms.com/some/path'
140
+ };
141
+
142
+ createDotCMSClient(configWithPath);
143
+
144
+ expect(Content).toHaveBeenCalledWith(expect.anything(), 'https://demo.dotcms.com');
145
+ });
146
+ });
147
+ });
@@ -0,0 +1,125 @@
1
+ import { consola } from 'consola';
2
+
3
+ import { DotCMSClientConfig, RequestOptions } from '@dotcms/types';
4
+
5
+ import { Content } from './content/content-api';
6
+ import { NavigationClient } from './navigation/navigation-api';
7
+ import { PageClient } from './page/page-api';
8
+
9
+ /**
10
+ * Parses a string into a URL object.
11
+ *
12
+ * @param url - The URL string to parse
13
+ * @returns A URL object if parsing is successful, undefined otherwise
14
+ */
15
+ function parseURL(url: string): URL | undefined {
16
+ try {
17
+ return new URL(url);
18
+ } catch {
19
+ consola.error('[DotCMS Client]: Invalid URL:', url);
20
+
21
+ return undefined;
22
+ }
23
+ }
24
+
25
+ /**
26
+ * Default configuration for the DotCMS client.
27
+ */
28
+ const defaultConfig: DotCMSClientConfig = {
29
+ dotcmsUrl: '',
30
+ authToken: '',
31
+ requestOptions: {}
32
+ };
33
+
34
+ /**
35
+ * Client for interacting with the DotCMS REST API.
36
+ * Provides access to content, page, and navigation functionality.
37
+ */
38
+ class DotCMSClient {
39
+ private config: DotCMSClientConfig;
40
+ private requestOptions!: RequestOptions;
41
+
42
+ /**
43
+ * Client for content-related operations.
44
+ */
45
+ content: Content;
46
+
47
+ /**
48
+ * Client for page-related operations.
49
+ */
50
+ page: PageClient;
51
+
52
+ /**
53
+ * Client for navigation-related operations.
54
+ */
55
+ nav: NavigationClient;
56
+
57
+ /**
58
+ * Creates a new DotCMS client instance.
59
+ *
60
+ * @param config - Configuration options for the client
61
+ * @throws Warning if dotcmsUrl is invalid or authToken is missing
62
+ */
63
+ constructor(config: DotCMSClientConfig = defaultConfig) {
64
+ this.config = config;
65
+ this.requestOptions = this.createAuthenticatedRequestOptions(this.config);
66
+
67
+ // Initialize clients
68
+ this.page = new PageClient(this.config, this.requestOptions);
69
+ this.nav = new NavigationClient(this.config, this.requestOptions);
70
+ this.content = new Content(this.requestOptions, this.config.dotcmsUrl);
71
+ }
72
+
73
+ /**
74
+ * Creates request options with authentication headers.
75
+ *
76
+ * @param config - The client configuration
77
+ * @returns Request options with authorization headers
78
+ */
79
+ private createAuthenticatedRequestOptions(config: DotCMSClientConfig): RequestOptions {
80
+ return {
81
+ ...config.requestOptions,
82
+ headers: {
83
+ ...config.requestOptions?.headers,
84
+ Authorization: `Bearer ${config.authToken}`
85
+ }
86
+ };
87
+ }
88
+ }
89
+
90
+ /**
91
+ * Creates and returns a new DotCMS client instance.
92
+ *
93
+ * @param config - Configuration options for the client
94
+ * @returns A configured DotCMS client instance
95
+ * @example
96
+ * ```typescript
97
+ * const client = dotCMSCreateClient({
98
+ * dotcmsUrl: 'https://demo.dotcms.com',
99
+ * authToken: 'your-auth-token'
100
+ * });
101
+ *
102
+ * // Use the client to fetch content
103
+ * const pages = await client.page.get('/about-us');
104
+ * ```
105
+ */
106
+ export const createDotCMSClient = (clientConfig: DotCMSClientConfig): DotCMSClient => {
107
+ const { dotcmsUrl, authToken } = clientConfig || {};
108
+ const instanceUrl = parseURL(dotcmsUrl)?.origin;
109
+
110
+ if (!instanceUrl) {
111
+ throw new TypeError("Invalid configuration - 'dotcmsUrl' must be a valid URL");
112
+ }
113
+
114
+ if (!authToken) {
115
+ throw new TypeError("Invalid configuration - 'authToken' is required");
116
+ }
117
+
118
+ const config = {
119
+ ...clientConfig,
120
+ authToken,
121
+ dotcmsUrl: instanceUrl
122
+ };
123
+
124
+ return new DotCMSClient(config);
125
+ };