@momentumcms/plugins-analytics 0.3.0 → 0.4.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.
@@ -0,0 +1,206 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // libs/plugins/analytics/src/lib/collectors/block-field-injector.ts
21
+ var block_field_injector_exports = {};
22
+ __export(block_field_injector_exports, {
23
+ injectBlockAnalyticsFields: () => injectBlockAnalyticsFields
24
+ });
25
+ module.exports = __toCommonJS(block_field_injector_exports);
26
+
27
+ // libs/core/src/lib/collections/define-collection.ts
28
+ function defineCollection(config) {
29
+ const collection = {
30
+ timestamps: true,
31
+ // Enable timestamps by default
32
+ ...config
33
+ };
34
+ if (!collection.slug) {
35
+ throw new Error("Collection must have a slug");
36
+ }
37
+ if (!collection.fields || collection.fields.length === 0) {
38
+ throw new Error(`Collection "${collection.slug}" must have at least one field`);
39
+ }
40
+ if (!/^[a-z][a-z0-9-]*$/.test(collection.slug)) {
41
+ throw new Error(
42
+ `Collection slug "${collection.slug}" must be kebab-case (lowercase letters, numbers, and hyphens, starting with a letter)`
43
+ );
44
+ }
45
+ return collection;
46
+ }
47
+
48
+ // libs/core/src/lib/fields/field-builders.ts
49
+ function text(name, options = {}) {
50
+ return {
51
+ name,
52
+ type: "text",
53
+ ...options
54
+ };
55
+ }
56
+ function number(name, options = {}) {
57
+ return {
58
+ name,
59
+ type: "number",
60
+ ...options
61
+ };
62
+ }
63
+ function checkbox(name, options = {}) {
64
+ return {
65
+ name,
66
+ type: "checkbox",
67
+ ...options,
68
+ defaultValue: options.defaultValue ?? false
69
+ };
70
+ }
71
+ function group(name, options) {
72
+ return {
73
+ name,
74
+ type: "group",
75
+ ...options
76
+ };
77
+ }
78
+ function json(name, options = {}) {
79
+ return {
80
+ name,
81
+ type: "json",
82
+ ...options
83
+ };
84
+ }
85
+
86
+ // libs/core/src/lib/collections/media.collection.ts
87
+ var MediaCollection = defineCollection({
88
+ slug: "media",
89
+ labels: {
90
+ singular: "Media",
91
+ plural: "Media"
92
+ },
93
+ upload: {
94
+ mimeTypes: ["image/*", "application/pdf", "video/*", "audio/*"]
95
+ },
96
+ admin: {
97
+ useAsTitle: "filename",
98
+ defaultColumns: ["filename", "mimeType", "filesize", "createdAt"]
99
+ },
100
+ fields: [
101
+ text("filename", {
102
+ required: true,
103
+ label: "Filename",
104
+ description: "Original filename of the uploaded file"
105
+ }),
106
+ text("mimeType", {
107
+ required: true,
108
+ label: "MIME Type",
109
+ description: "File MIME type (e.g., image/jpeg, application/pdf)"
110
+ }),
111
+ number("filesize", {
112
+ label: "File Size",
113
+ description: "File size in bytes"
114
+ }),
115
+ text("path", {
116
+ label: "Storage Path",
117
+ description: "Path/key where the file is stored",
118
+ admin: {
119
+ hidden: true
120
+ }
121
+ }),
122
+ text("url", {
123
+ label: "URL",
124
+ description: "Public URL to access the file"
125
+ }),
126
+ text("alt", {
127
+ label: "Alt Text",
128
+ description: "Alternative text for accessibility"
129
+ }),
130
+ number("width", {
131
+ label: "Width",
132
+ description: "Image width in pixels (for images only)"
133
+ }),
134
+ number("height", {
135
+ label: "Height",
136
+ description: "Image height in pixels (for images only)"
137
+ }),
138
+ json("focalPoint", {
139
+ label: "Focal Point",
140
+ description: "Focal point coordinates for image cropping",
141
+ admin: {
142
+ hidden: true
143
+ }
144
+ })
145
+ ],
146
+ access: {
147
+ // Media is readable by anyone by default
148
+ read: () => true,
149
+ // Only authenticated users can create/update/delete
150
+ create: ({ req }) => !!req?.user,
151
+ update: ({ req }) => !!req?.user,
152
+ delete: ({ req }) => !!req?.user
153
+ }
154
+ });
155
+
156
+ // libs/plugins/analytics/src/lib/collectors/block-field-injector.ts
157
+ function createAnalyticsGroupField() {
158
+ return group("_analytics", {
159
+ label: "Analytics",
160
+ admin: { collapsible: true, defaultOpen: false },
161
+ fields: [
162
+ checkbox("trackImpressions", { label: "Track Impressions" }),
163
+ checkbox("trackHover", { label: "Track Hover" })
164
+ ]
165
+ });
166
+ }
167
+ function hasAnalyticsField(fields) {
168
+ return fields.some((f) => f.name === "_analytics" && f.type === "group");
169
+ }
170
+ function hasBlocks(field) {
171
+ return field.type === "blocks" && "blocks" in field;
172
+ }
173
+ function hasNestedFields(field) {
174
+ return "fields" in field && Array.isArray(field.fields);
175
+ }
176
+ function hasTabs(field) {
177
+ return field.type === "tabs" && "tabs" in field;
178
+ }
179
+ function injectIntoFields(fields) {
180
+ for (const field of fields) {
181
+ if (hasBlocks(field)) {
182
+ for (const blockConfig of field.blocks) {
183
+ if (!hasAnalyticsField(blockConfig.fields)) {
184
+ blockConfig.fields.push(createAnalyticsGroupField());
185
+ }
186
+ }
187
+ }
188
+ if ((field.type === "group" || field.type === "array" || field.type === "collapsible" || field.type === "row") && hasNestedFields(field)) {
189
+ injectIntoFields(field.fields);
190
+ }
191
+ if (hasTabs(field)) {
192
+ for (const tab of field.tabs) {
193
+ injectIntoFields(tab.fields);
194
+ }
195
+ }
196
+ }
197
+ }
198
+ function injectBlockAnalyticsFields(collections) {
199
+ for (const collection of collections) {
200
+ injectIntoFields(collection.fields);
201
+ }
202
+ }
203
+ // Annotate the CommonJS export names for ESM import in node:
204
+ 0 && (module.exports = {
205
+ injectBlockAnalyticsFields
206
+ });
@@ -0,0 +1,179 @@
1
+ // libs/core/src/lib/collections/define-collection.ts
2
+ function defineCollection(config) {
3
+ const collection = {
4
+ timestamps: true,
5
+ // Enable timestamps by default
6
+ ...config
7
+ };
8
+ if (!collection.slug) {
9
+ throw new Error("Collection must have a slug");
10
+ }
11
+ if (!collection.fields || collection.fields.length === 0) {
12
+ throw new Error(`Collection "${collection.slug}" must have at least one field`);
13
+ }
14
+ if (!/^[a-z][a-z0-9-]*$/.test(collection.slug)) {
15
+ throw new Error(
16
+ `Collection slug "${collection.slug}" must be kebab-case (lowercase letters, numbers, and hyphens, starting with a letter)`
17
+ );
18
+ }
19
+ return collection;
20
+ }
21
+
22
+ // libs/core/src/lib/fields/field-builders.ts
23
+ function text(name, options = {}) {
24
+ return {
25
+ name,
26
+ type: "text",
27
+ ...options
28
+ };
29
+ }
30
+ function number(name, options = {}) {
31
+ return {
32
+ name,
33
+ type: "number",
34
+ ...options
35
+ };
36
+ }
37
+ function checkbox(name, options = {}) {
38
+ return {
39
+ name,
40
+ type: "checkbox",
41
+ ...options,
42
+ defaultValue: options.defaultValue ?? false
43
+ };
44
+ }
45
+ function group(name, options) {
46
+ return {
47
+ name,
48
+ type: "group",
49
+ ...options
50
+ };
51
+ }
52
+ function json(name, options = {}) {
53
+ return {
54
+ name,
55
+ type: "json",
56
+ ...options
57
+ };
58
+ }
59
+
60
+ // libs/core/src/lib/collections/media.collection.ts
61
+ var MediaCollection = defineCollection({
62
+ slug: "media",
63
+ labels: {
64
+ singular: "Media",
65
+ plural: "Media"
66
+ },
67
+ upload: {
68
+ mimeTypes: ["image/*", "application/pdf", "video/*", "audio/*"]
69
+ },
70
+ admin: {
71
+ useAsTitle: "filename",
72
+ defaultColumns: ["filename", "mimeType", "filesize", "createdAt"]
73
+ },
74
+ fields: [
75
+ text("filename", {
76
+ required: true,
77
+ label: "Filename",
78
+ description: "Original filename of the uploaded file"
79
+ }),
80
+ text("mimeType", {
81
+ required: true,
82
+ label: "MIME Type",
83
+ description: "File MIME type (e.g., image/jpeg, application/pdf)"
84
+ }),
85
+ number("filesize", {
86
+ label: "File Size",
87
+ description: "File size in bytes"
88
+ }),
89
+ text("path", {
90
+ label: "Storage Path",
91
+ description: "Path/key where the file is stored",
92
+ admin: {
93
+ hidden: true
94
+ }
95
+ }),
96
+ text("url", {
97
+ label: "URL",
98
+ description: "Public URL to access the file"
99
+ }),
100
+ text("alt", {
101
+ label: "Alt Text",
102
+ description: "Alternative text for accessibility"
103
+ }),
104
+ number("width", {
105
+ label: "Width",
106
+ description: "Image width in pixels (for images only)"
107
+ }),
108
+ number("height", {
109
+ label: "Height",
110
+ description: "Image height in pixels (for images only)"
111
+ }),
112
+ json("focalPoint", {
113
+ label: "Focal Point",
114
+ description: "Focal point coordinates for image cropping",
115
+ admin: {
116
+ hidden: true
117
+ }
118
+ })
119
+ ],
120
+ access: {
121
+ // Media is readable by anyone by default
122
+ read: () => true,
123
+ // Only authenticated users can create/update/delete
124
+ create: ({ req }) => !!req?.user,
125
+ update: ({ req }) => !!req?.user,
126
+ delete: ({ req }) => !!req?.user
127
+ }
128
+ });
129
+
130
+ // libs/plugins/analytics/src/lib/collectors/block-field-injector.ts
131
+ function createAnalyticsGroupField() {
132
+ return group("_analytics", {
133
+ label: "Analytics",
134
+ admin: { collapsible: true, defaultOpen: false },
135
+ fields: [
136
+ checkbox("trackImpressions", { label: "Track Impressions" }),
137
+ checkbox("trackHover", { label: "Track Hover" })
138
+ ]
139
+ });
140
+ }
141
+ function hasAnalyticsField(fields) {
142
+ return fields.some((f) => f.name === "_analytics" && f.type === "group");
143
+ }
144
+ function hasBlocks(field) {
145
+ return field.type === "blocks" && "blocks" in field;
146
+ }
147
+ function hasNestedFields(field) {
148
+ return "fields" in field && Array.isArray(field.fields);
149
+ }
150
+ function hasTabs(field) {
151
+ return field.type === "tabs" && "tabs" in field;
152
+ }
153
+ function injectIntoFields(fields) {
154
+ for (const field of fields) {
155
+ if (hasBlocks(field)) {
156
+ for (const blockConfig of field.blocks) {
157
+ if (!hasAnalyticsField(blockConfig.fields)) {
158
+ blockConfig.fields.push(createAnalyticsGroupField());
159
+ }
160
+ }
161
+ }
162
+ if ((field.type === "group" || field.type === "array" || field.type === "collapsible" || field.type === "row") && hasNestedFields(field)) {
163
+ injectIntoFields(field.fields);
164
+ }
165
+ if (hasTabs(field)) {
166
+ for (const tab of field.tabs) {
167
+ injectIntoFields(tab.fields);
168
+ }
169
+ }
170
+ }
171
+ }
172
+ function injectBlockAnalyticsFields(collections) {
173
+ for (const collection of collections) {
174
+ injectIntoFields(collection.fields);
175
+ }
176
+ }
177
+ export {
178
+ injectBlockAnalyticsFields
179
+ };
package/package.json CHANGED
@@ -1,56 +1,61 @@
1
1
  {
2
- "name": "@momentumcms/plugins-analytics",
3
- "version": "0.3.0",
4
- "description": "Analytics and content tracking plugin for Momentum CMS",
5
- "license": "MIT",
6
- "author": "Momentum CMS Contributors",
7
- "repository": {
8
- "type": "git",
9
- "url": "https://github.com/DonaldMurillo/momentum-cms.git",
10
- "directory": "libs/plugins/analytics"
11
- },
12
- "homepage": "https://github.com/DonaldMurillo/momentum-cms#readme",
13
- "bugs": {
14
- "url": "https://github.com/DonaldMurillo/momentum-cms/issues"
15
- },
16
- "keywords": [
17
- "cms",
18
- "momentum-cms",
19
- "analytics",
20
- "tracking",
21
- "content-performance"
22
- ],
23
- "engines": {
24
- "node": ">=18"
25
- },
26
- "main": "./index.cjs",
27
- "types": "./src/index.d.ts",
28
- "dependencies": {
29
- "@angular/aria": "^21.1.2",
30
- "@angular/cdk": "^21.1.2",
31
- "@angular/common": "~21.1.0",
32
- "@angular/core": "~21.1.0",
33
- "@angular/forms": "~21.1.0",
34
- "@angular/router": "~21.1.0",
35
- "@aws-sdk/client-s3": "^3.983.0",
36
- "@aws-sdk/s3-request-presigner": "^3.983.0",
37
- "@momentumcms/core": "0.3.0",
38
- "@momentumcms/logger": "0.3.0",
39
- "@momentumcms/plugins-core": "0.3.0",
40
- "@momentumcms/server-core": "0.3.0",
41
- "@ng-icons/core": "^33.0.0",
42
- "@ng-icons/heroicons": "^33.0.0",
43
- "express": "^4.21.0",
44
- "graphql": "^16.12.0",
45
- "rxjs": "~7.8.0"
46
- },
47
- "peerDependencies": {
48
- "pg": "^8.0.0"
49
- },
50
- "peerDependenciesMeta": {
51
- "pg": {
52
- "optional": true
53
- }
54
- },
55
- "module": "./index.js"
56
- }
2
+ "name": "@momentumcms/plugins-analytics",
3
+ "version": "0.4.0",
4
+ "description": "Analytics and content tracking plugin for Momentum CMS",
5
+ "license": "MIT",
6
+ "author": "Momentum CMS Contributors",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/DonaldMurillo/momentum-cms.git",
10
+ "directory": "libs/plugins/analytics"
11
+ },
12
+ "homepage": "https://github.com/DonaldMurillo/momentum-cms#readme",
13
+ "bugs": {
14
+ "url": "https://github.com/DonaldMurillo/momentum-cms/issues"
15
+ },
16
+ "keywords": [
17
+ "cms",
18
+ "momentum-cms",
19
+ "analytics",
20
+ "tracking",
21
+ "content-performance"
22
+ ],
23
+ "engines": {
24
+ "node": ">=18"
25
+ },
26
+ "main": "./index.cjs",
27
+ "types": "./src/index.d.ts",
28
+ "exports": {
29
+ ".": {
30
+ "types": "./src/index.d.ts",
31
+ "default": "./index.cjs"
32
+ },
33
+ "./admin-routes": {
34
+ "types": "./src/lib/analytics-admin-routes.d.ts",
35
+ "default": "./lib/analytics-admin-routes.cjs"
36
+ },
37
+ "./block-fields": {
38
+ "types": "./src/lib/collectors/block-field-injector.d.ts",
39
+ "default": "./lib/collectors/block-field-injector.cjs"
40
+ },
41
+ "./client": {
42
+ "types": "./src/lib/client/tracker.d.ts",
43
+ "default": "./lib/client/tracker.cjs"
44
+ }
45
+ },
46
+ "dependencies": {
47
+ "@momentumcms/core": "0.4.0",
48
+ "@momentumcms/logger": "0.4.0",
49
+ "@momentumcms/plugins-core": "0.4.0",
50
+ "@momentumcms/server-core": "0.4.0",
51
+ "express": "^4.21.0"
52
+ },
53
+ "peerDependencies": {
54
+ "pg": "^8.0.0"
55
+ },
56
+ "peerDependenciesMeta": {
57
+ "pg": {
58
+ "optional": true
59
+ }
60
+ }
61
+ }
@@ -0,0 +1,3 @@
1
+ import type { PluginAdminRouteDescriptor } from '@momentumcms/core';
2
+
3
+ export declare const analyticsAdminRoutes: PluginAdminRouteDescriptor[];
package/CHANGELOG.md DELETED
@@ -1,99 +0,0 @@
1
- ## 0.3.0 (2026-02-20)
2
-
3
- ### 🚀 Features
4
-
5
- - add named tabs support with nested data grouping and UI improvements ([#30](https://github.com/DonaldMurillo/momentum-cms/pull/30))
6
-
7
- ### ❤️ Thank You
8
-
9
- - Claude Opus 4.6
10
- - Donald Murillo @DonaldMurillo
11
-
12
- ## 0.2.0 (2026-02-17)
13
-
14
- This was a version bump only for plugins-analytics to align it with other projects, there were no code changes.
15
-
16
- ## 0.1.10 (2026-02-17)
17
-
18
- ### 🩹 Fixes
19
-
20
- - **create-momentum-app:** add shell option to execFileSync for Windows ([#28](https://github.com/DonaldMurillo/momentum-cms/pull/28))
21
-
22
- ### ❤️ Thank You
23
-
24
- - Claude Opus 4.6
25
- - Donald Murillo @DonaldMurillo
26
-
27
- ## 0.1.9 (2026-02-16)
28
-
29
- This was a version bump only for plugins-analytics to align it with other projects, there were no code changes.
30
-
31
- ## 0.1.8 (2026-02-16)
32
-
33
- ### 🩹 Fixes
34
-
35
- - correct repository URLs and add GitHub link to CLI ([#26](https://github.com/DonaldMurillo/momentum-cms/pull/26))
36
-
37
- ### ❤️ Thank You
38
-
39
- - Claude Opus 4.6
40
- - Donald Murillo @DonaldMurillo
41
-
42
- ## 0.1.7 (2026-02-16)
43
-
44
- ### 🩹 Fixes
45
-
46
- - correct repository URLs and add GitHub link to CLI output ([f7e96bb](https://github.com/DonaldMurillo/momentum-cms/commit/f7e96bb))
47
-
48
- ### ❤️ Thank You
49
-
50
- - Claude Opus 4.6
51
- - Donald Murillo @DonaldMurillo
52
-
53
- ## 0.1.6 (2026-02-16)
54
-
55
- This was a version bump only for plugins-analytics to align it with other projects, there were no code changes.
56
-
57
- ## 0.1.5 (2026-02-16)
58
-
59
- This was a version bump only for plugins-analytics to align it with other projects, there were no code changes.
60
-
61
- ## 0.1.4 (2026-02-16)
62
-
63
- This was a version bump only for plugins-analytics to align it with other projects, there were no code changes.
64
-
65
- ## 0.1.3 (2026-02-16)
66
-
67
- This was a version bump only for plugins-analytics to align it with other projects, there were no code changes.
68
-
69
- ## 0.1.2 (2026-02-16)
70
-
71
- ### 🩹 Fixes
72
-
73
- - **release:** centralize manifestRootsToUpdate to update both source and dist ([2b8f832](https://github.com/DonaldMurillo/momentum-cms/commit/2b8f832))
74
- - **create-app:** fix Angular SSR, Analog builds, and CJS/ESM compatibility ([28d4d0a](https://github.com/DonaldMurillo/momentum-cms/commit/28d4d0a))
75
-
76
- ### ❤️ Thank You
77
-
78
- - Claude Opus 4.6
79
- - Donald Murillo @DonaldMurillo
80
-
81
- ## 0.1.1 (2026-02-16)
82
-
83
- This was a version bump only for plugins-analytics to align it with other projects, there were no code changes.
84
-
85
- ## 0.1.0 (2026-02-16)
86
-
87
- ### 🚀 Features
88
-
89
- - add tracking rules, content performance, and block analytics ([#21](https://github.com/DonaldMurillo/momentum-cms/pull/21))
90
-
91
- ### 🩹 Fixes
92
-
93
- - resolve CUD toast interceptor issues ([#17](https://github.com/DonaldMurillo/momentum-cms/pull/17), [#1](https://github.com/DonaldMurillo/momentum-cms/issues/1), [#2](https://github.com/DonaldMurillo/momentum-cms/issues/2), [#3](https://github.com/DonaldMurillo/momentum-cms/issues/3), [#4](https://github.com/DonaldMurillo/momentum-cms/issues/4))
94
-
95
- ### ❤️ Thank You
96
-
97
- - Claude Haiku 4.5
98
- - Claude Opus 4.6
99
- - Donald Murillo @DonaldMurillo
package/LICENSE DELETED
@@ -1,21 +0,0 @@
1
- MIT License
2
-
3
- Copyright (c) 2024-present Momentum CMS Contributors
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.