nextpress-core 1.0.3 → 2.0.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.
Files changed (211) hide show
  1. package/cli/install.js +27 -0
  2. package/{dist/acf-functions/core/acf-builder.js → lib/acf-functions/core/acf-builder.ts} +45 -17
  3. package/{dist/acf-functions/core/acf-component-autoloader.js → lib/acf-functions/core/acf-component-autoloader.ts} +13 -7
  4. package/{dist/acf-functions/core/acf-field-group-autoloader.js → lib/acf-functions/core/acf-field-group-autoloader.ts} +11 -5
  5. package/{dist/acf-functions/services/define-field-group.d.ts → lib/acf-functions/services/define-field-group.ts} +4 -1
  6. package/{dist/acf-functions/services/define-layout.d.ts → lib/acf-functions/services/define-layout.ts} +4 -1
  7. package/lib/acf-functions/services/map-fields/helpers/map-choice-object.ts +20 -0
  8. package/{dist/acf-functions/services/map-fields/map-fields.js → lib/acf-functions/services/map-fields/map-fields.ts} +128 -89
  9. package/{dist/acf-functions/types/acf-field-group.d.ts → lib/acf-functions/types/acf-field-group.ts} +49 -28
  10. package/lib/acf-functions/types/acf-field.ts +2853 -0
  11. package/lib/acf-functions/types/acf-layout.ts +22 -0
  12. package/lib/acf-functions/types/components/field-props.ts +189 -0
  13. package/{dist/acf-functions/types/components/nextpress-component.d.ts → lib/acf-functions/types/components/nextpress-component.ts} +4 -3
  14. package/lib/ambient.d.ts +16 -0
  15. package/{dist/entities/common.d.ts → lib/entities/common.ts} +6 -4
  16. package/{dist/entities/option/option.interface.d.ts → lib/entities/option/option.interface.ts} +3 -3
  17. package/{dist/entities/option/option.js → lib/entities/option/option.ts} +21 -14
  18. package/{dist/entities/post/post.interface.d.ts → lib/entities/post/post.interface.ts} +26 -21
  19. package/lib/entities/post/post.ts +209 -0
  20. package/{dist/entities/term/term.interface.d.ts → lib/entities/term/term.interface.ts} +3 -3
  21. package/lib/entities/term/term.ts +82 -0
  22. package/{dist/entities/user/user.interface.d.ts → lib/entities/user/user.interface.ts} +2 -1
  23. package/lib/entities/user/user.ts +86 -0
  24. package/{dist/globals/entity-loader/entity-loader-base.js → lib/globals/entity-loader/entity-loader-base.ts} +64 -10
  25. package/{dist/globals/entity-loader/entity-loader.interface.d.ts → lib/globals/entity-loader/entity-loader.ts} +2 -4
  26. package/lib/globals/entity-loader/option-loader.ts +56 -0
  27. package/lib/globals/entity-loader/post-loader.ts +60 -0
  28. package/lib/globals/entity-loader/term-loader.ts +60 -0
  29. package/lib/globals/entity-loader/user-loader.ts +61 -0
  30. package/lib/globals/get-field/get-field.ts +76 -0
  31. package/{dist/globals/globals.js → lib/globals/globals.ts} +8 -3
  32. package/{dist/globals/nextpress-config/nextpress-config.interface.d.ts → lib/globals/nextpress-config/nextpress-config.interface.ts} +10 -6
  33. package/lib/globals/nextpress-config/nextpress-config.ts +8 -0
  34. package/lib/globals/queried-object/queried-object.ts +124 -0
  35. package/{dist/repository/optionquery/option-query-args.d.ts → lib/repository/optionquery/option-query-args.ts} +5 -2
  36. package/lib/repository/optionquery/option-query.ts +29 -0
  37. package/{dist/repository/postquery/post-query-args.d.ts → lib/repository/postquery/post-query-args.ts} +10 -6
  38. package/lib/repository/postquery/post-query.ts +282 -0
  39. package/{dist/repository/termquery/term-query-args.d.ts → lib/repository/termquery/term-query-args.ts} +16 -6
  40. package/lib/repository/termquery/term-query.ts +244 -0
  41. package/{dist/repository/userquery/user-query-args.d.ts → lib/repository/userquery/user-query-args.ts} +19 -7
  42. package/{dist/repository/userquery/user-query.js → lib/repository/userquery/user-query.ts} +93 -76
  43. package/{dist/router/helpers.js → lib/router/helpers.ts} +4 -4
  44. package/{dist/router/nextpress-layout.js → lib/router/nextpress-layout.tsx} +28 -9
  45. package/{dist/router/routes/not-found-page.js → lib/router/nextpress-not-found-route.tsx} +7 -5
  46. package/{dist/router/nextpress-proxy.js → lib/router/nextpress-proxy.ts} +15 -3
  47. package/{dist/router/nextpress-static-params.js → lib/router/nextpress-static-params.ts} +17 -5
  48. package/{dist/router/router.js → lib/router/router.tsx} +29 -22
  49. package/{dist/router/routes/api/api-get-admin-bar.js → lib/router/routes/api/api-get-admin-bar.ts} +8 -6
  50. package/{dist/router/routes/api/api-get-draft-mode.js → lib/router/routes/api/api-get-draft-mode.ts} +15 -6
  51. package/{dist/router/routes/api/api-get-field-groups.js → lib/router/routes/api/api-get-field-groups.ts} +13 -8
  52. package/{dist/router/routes/api/api-post-revalidate.js → lib/router/routes/api/api-post-revalidate.ts} +6 -4
  53. package/{dist/router/routes/api/helpers.js → lib/router/routes/api/helpers.ts} +4 -3
  54. package/lib/router/routes/author-archive.tsx +75 -0
  55. package/lib/router/routes/post-index-page.tsx +58 -0
  56. package/lib/router/routes/singular-page.tsx +78 -0
  57. package/lib/router/routes/site-front-page.tsx +51 -0
  58. package/lib/router/routes/term-archive.tsx +93 -0
  59. package/{dist/router/types.d.ts → lib/router/types.ts} +4 -2
  60. package/{dist/services/get-menu.js → lib/services/get-menu.ts} +56 -32
  61. package/{dist/services/get-theme-mods.js → lib/services/get-theme-mods.ts} +6 -4
  62. package/{dist/services/metadata/get-blogname.js → lib/services/metadata/get-blogname.ts} +2 -2
  63. package/{dist/services/metadata/get-favicon-url.js → lib/services/metadata/get-favicon-url.ts} +5 -4
  64. package/{dist/services/metadata/get-language-attribute.js → lib/services/metadata/get-language-attribute.ts} +1 -1
  65. package/{dist/services/utilities/capitalise-first-letter.js → lib/services/utilities/capitalise-first-letter.ts} +2 -3
  66. package/{dist/services/utilities/esc-html.js → lib/services/utilities/esc-html.ts} +3 -1
  67. package/{dist/services/utilities/get-date-time-formatter.js → lib/services/utilities/get-date-time-formatter.ts} +16 -6
  68. package/{dist/services/utilities/kses-post.js → lib/services/utilities/kses-post.ts} +2 -1
  69. package/{dist/services/utilities/process-url.js → lib/services/utilities/process-url.ts} +4 -3
  70. package/{dist/template-heirarchy/_autoloader/template-autoloader.js → lib/template-heirarchy/_autoloader/template-autoloader.ts} +18 -9
  71. package/{dist/template-heirarchy/archive/archive.js → lib/template-heirarchy/archive/archive.tsx} +10 -7
  72. package/{dist/template-heirarchy/archive/author.js → lib/template-heirarchy/archive/author.tsx} +10 -7
  73. package/{dist/template-heirarchy/archive/category.js → lib/template-heirarchy/archive/category.tsx} +11 -7
  74. package/{dist/template-heirarchy/archive/posttypearchive.js → lib/template-heirarchy/archive/posttypearchive.tsx} +11 -8
  75. package/{dist/template-heirarchy/archive/tag.js → lib/template-heirarchy/archive/tag.tsx} +12 -7
  76. package/{dist/template-heirarchy/archive/taxonomy.js → lib/template-heirarchy/archive/taxonomy.tsx} +10 -7
  77. package/{dist/template-heirarchy/home/home.js → lib/template-heirarchy/home/home.tsx} +10 -7
  78. package/{dist/template-heirarchy/index.js → lib/template-heirarchy/index.tsx} +9 -5
  79. package/{dist/template-heirarchy/not-found.tsx/not-found.js → lib/template-heirarchy/not-found.tsx/not-found.tsx} +10 -7
  80. package/{dist/template-heirarchy/page/page.js → lib/template-heirarchy/page/page.tsx} +10 -7
  81. package/{dist/template-heirarchy/page/posttype.js → lib/template-heirarchy/page/posttype.tsx} +12 -8
  82. package/{dist/template-heirarchy/page/single.js → lib/template-heirarchy/page/single.tsx} +10 -7
  83. package/{dist/template-heirarchy/page/singular.js → lib/template-heirarchy/page/singular.tsx} +10 -7
  84. package/lib/ui/render-attachment-image.tsx +28 -0
  85. package/lib/ui/render-components.tsx +12 -0
  86. package/lib/ui/render-the-admin-bar.tsx +79 -0
  87. package/lib/ui/render-the-logo.tsx +24 -0
  88. package/{dist/wpdb/wpdb.interface.d.ts → lib/wpdb/wpdb.interface.ts} +20 -1
  89. package/{dist/wpdb/wpdb.js → lib/wpdb/wpdb.ts} +9 -5
  90. package/package.json +8 -15
  91. package/dist/acf-functions/core/acf-builder.d.ts +0 -51
  92. package/dist/acf-functions/core/acf-component-autoloader.d.ts +0 -11
  93. package/dist/acf-functions/core/acf-field-group-autoloader.d.ts +0 -10
  94. package/dist/acf-functions/field-props.d.ts +0 -196
  95. package/dist/acf-functions/field-props.js +0 -1
  96. package/dist/acf-functions/services/define-field-group.js +0 -10
  97. package/dist/acf-functions/services/define-layout.js +0 -10
  98. package/dist/acf-functions/services/map-fields/helpers/map-choice-object.d.ts +0 -2
  99. package/dist/acf-functions/services/map-fields/helpers/map-choice-object.js +0 -18
  100. package/dist/acf-functions/services/map-fields/map-fields.d.ts +0 -21
  101. package/dist/acf-functions/types/acf-field-group.js +0 -1
  102. package/dist/acf-functions/types/acf-field.d.ts +0 -2813
  103. package/dist/acf-functions/types/acf-field.js +0 -1
  104. package/dist/acf-functions/types/acf-layout.d.ts +0 -19
  105. package/dist/acf-functions/types/acf-layout.js +0 -1
  106. package/dist/acf-functions/types/acf-values.js +0 -1
  107. package/dist/acf-functions/types/components/field-props.d.ts +0 -196
  108. package/dist/acf-functions/types/components/field-props.js +0 -1
  109. package/dist/acf-functions/types/components/nextpress-component.js +0 -1
  110. package/dist/entities/common.js +0 -1
  111. package/dist/entities/option/option.d.ts +0 -19
  112. package/dist/entities/option/option.interface.js +0 -2
  113. package/dist/entities/post/post.d.ts +0 -50
  114. package/dist/entities/post/post.interface.js +0 -2
  115. package/dist/entities/post/post.js +0 -184
  116. package/dist/entities/term/term.d.ts +0 -28
  117. package/dist/entities/term/term.interface.js +0 -1
  118. package/dist/entities/term/term.js +0 -67
  119. package/dist/entities/user/user.d.ts +0 -27
  120. package/dist/entities/user/user.interface.js +0 -1
  121. package/dist/entities/user/user.js +0 -74
  122. package/dist/globals/entity-loader/entity-loader-base.d.ts +0 -65
  123. package/dist/globals/entity-loader/entity-loader.interface.js +0 -1
  124. package/dist/globals/entity-loader/option-loader.d.ts +0 -15
  125. package/dist/globals/entity-loader/option-loader.js +0 -31
  126. package/dist/globals/entity-loader/post-loader.d.ts +0 -21
  127. package/dist/globals/entity-loader/post-loader.js +0 -28
  128. package/dist/globals/entity-loader/term-loader.d.ts +0 -21
  129. package/dist/globals/entity-loader/term-loader.js +0 -28
  130. package/dist/globals/entity-loader/user-loader.d.ts +0 -21
  131. package/dist/globals/entity-loader/user-loader.js +0 -28
  132. package/dist/globals/get-field/get-field.d.ts +0 -18
  133. package/dist/globals/get-field/get-field.js +0 -44
  134. package/dist/globals/globals.d.ts +0 -18
  135. package/dist/globals/nextpress-config/nextpress-config.d.ts +0 -4
  136. package/dist/globals/nextpress-config/nextpress-config.interface.js +0 -1
  137. package/dist/globals/nextpress-config/nextpress-config.js +0 -2
  138. package/dist/globals/queried-object/queried-object.d.ts +0 -62
  139. package/dist/globals/queried-object/queried-object.js +0 -56
  140. package/dist/repository/optionquery/option-query-args.js +0 -1
  141. package/dist/repository/optionquery/option-query.d.ts +0 -12
  142. package/dist/repository/optionquery/option-query.js +0 -20
  143. package/dist/repository/postquery/post-query-args.js +0 -1
  144. package/dist/repository/postquery/post-query.d.ts +0 -12
  145. package/dist/repository/postquery/post-query.js +0 -272
  146. package/dist/repository/termquery/term-query-args.js +0 -1
  147. package/dist/repository/termquery/term-query.d.ts +0 -11
  148. package/dist/repository/termquery/term-query.js +0 -213
  149. package/dist/repository/userquery/user-query-args.js +0 -1
  150. package/dist/repository/userquery/user-query.d.ts +0 -12
  151. package/dist/router/helpers.d.ts +0 -14
  152. package/dist/router/nextpress-layout.d.ts +0 -11
  153. package/dist/router/nextpress-proxy.d.ts +0 -8
  154. package/dist/router/nextpress-static-params.d.ts +0 -9
  155. package/dist/router/router.d.ts +0 -23
  156. package/dist/router/routes/api/api-get-admin-bar.d.ts +0 -8
  157. package/dist/router/routes/api/api-get-draft-mode.d.ts +0 -8
  158. package/dist/router/routes/api/api-get-field-groups.d.ts +0 -7
  159. package/dist/router/routes/api/api-post-revalidate.d.ts +0 -7
  160. package/dist/router/routes/api/helpers.d.ts +0 -8
  161. package/dist/router/routes/author-archive.d.ts +0 -25
  162. package/dist/router/routes/author-archive.js +0 -49
  163. package/dist/router/routes/not-found-page.d.ts +0 -15
  164. package/dist/router/routes/post-index-page.d.ts +0 -25
  165. package/dist/router/routes/post-index-page.js +0 -33
  166. package/dist/router/routes/singular-page.d.ts +0 -29
  167. package/dist/router/routes/singular-page.js +0 -51
  168. package/dist/router/routes/site-front-page.d.ts +0 -27
  169. package/dist/router/routes/site-front-page.js +0 -26
  170. package/dist/router/routes/term-archive.d.ts +0 -29
  171. package/dist/router/routes/term-archive.js +0 -65
  172. package/dist/router/types.js +0 -1
  173. package/dist/services/get-menu.d.ts +0 -13
  174. package/dist/services/get-theme-mods.d.ts +0 -7
  175. package/dist/services/metadata/get-blogname.d.ts +0 -6
  176. package/dist/services/metadata/get-favicon-url.d.ts +0 -6
  177. package/dist/services/metadata/get-language-attribute.d.ts +0 -6
  178. package/dist/services/services.d.ts +0 -3
  179. package/dist/services/services.js +0 -3
  180. package/dist/services/utilities/capitalise-first-letter.d.ts +0 -7
  181. package/dist/services/utilities/esc-html.d.ts +0 -7
  182. package/dist/services/utilities/get-date-time-formatter.d.ts +0 -6
  183. package/dist/services/utilities/index.d.ts +0 -0
  184. package/dist/services/utilities/index.js +0 -1
  185. package/dist/services/utilities/kses-post.d.ts +0 -7
  186. package/dist/services/utilities/process-url.d.ts +0 -7
  187. package/dist/template-heirarchy/_autoloader/template-autoloader.d.ts +0 -9
  188. package/dist/template-heirarchy/archive/archive.d.ts +0 -16
  189. package/dist/template-heirarchy/archive/author.d.ts +0 -16
  190. package/dist/template-heirarchy/archive/category.d.ts +0 -16
  191. package/dist/template-heirarchy/archive/posttypearchive.d.ts +0 -24
  192. package/dist/template-heirarchy/archive/tag.d.ts +0 -16
  193. package/dist/template-heirarchy/archive/taxonomy.d.ts +0 -16
  194. package/dist/template-heirarchy/home/home.d.ts +0 -16
  195. package/dist/template-heirarchy/index.d.ts +0 -17
  196. package/dist/template-heirarchy/not-found.tsx/not-found.d.ts +0 -16
  197. package/dist/template-heirarchy/page/page.d.ts +0 -16
  198. package/dist/template-heirarchy/page/posttype.d.ts +0 -24
  199. package/dist/template-heirarchy/page/single.d.ts +0 -16
  200. package/dist/template-heirarchy/page/singular.d.ts +0 -16
  201. package/dist/ui/render-attachment-image.d.ts +0 -12
  202. package/dist/ui/render-attachment-image.js +0 -24
  203. package/dist/ui/render-components.d.ts +0 -9
  204. package/dist/ui/render-components.js +0 -7
  205. package/dist/ui/render-the-admin-bar.d.ts +0 -8
  206. package/dist/ui/render-the-admin-bar.js +0 -36
  207. package/dist/ui/render-the-logo.d.ts +0 -10
  208. package/dist/ui/render-the-logo.js +0 -16
  209. package/dist/wpdb/wpdb.d.ts +0 -3
  210. package/dist/wpdb/wpdb.interface.js +0 -5
  211. /package/{dist/acf-functions/types/acf-values.d.ts → lib/acf-functions/types/acf-values.ts} +0 -0
@@ -0,0 +1,82 @@
1
+ import { wpdb } from "nextpress/wpdb/wpdb";
2
+ import { ITerm } from "./term.interface";
3
+
4
+ /**
5
+ * Implementation of ITerm entity.
6
+ */
7
+ export class Term implements ITerm
8
+ {
9
+ constructor(
10
+ public termId: number
11
+ ) {}
12
+
13
+ /** Raw term data from database. */
14
+ private termData?: Record<string, any>;
15
+ /** Map of term meta key-value pairs. */
16
+ private metaMap?: Map<string, string>;
17
+
18
+ /**
19
+ * Retrieves array of Term instances by IDs.
20
+ *
21
+ * @param {number[]} ids - Array of term IDs to retrieve.
22
+ * @returns {Promise<Term[]>} Promise resolving to array of Term instances.
23
+ */
24
+ static async get(ids: number[]): Promise<Term[]> {
25
+ ids = ids.filter(Boolean);
26
+ if (!ids || !ids.length) return [];
27
+
28
+ const combinedData = await wpdb
29
+ .selectFrom('wpTerms as term')
30
+ .innerJoin('wpTermTaxonomy as taxonomy', 'term.termId', 'taxonomy.termId')
31
+ .where('term.termId', 'in', ids)
32
+ .select([
33
+ 'term.termId as termId',
34
+ 'term.name as name',
35
+ 'term.slug as slug',
36
+ 'term.termGroup as termGroup',
37
+ 'taxonomy.termTaxonomyId as termTaxonomyId',
38
+ 'taxonomy.taxonomy as taxonomy',
39
+ 'taxonomy.description as description',
40
+ 'taxonomy.parent as parent',
41
+ 'taxonomy.count as count'
42
+ ])
43
+ .execute();
44
+
45
+ const metaData = await wpdb
46
+ .selectFrom('wpTermmeta')
47
+ .where('termId', 'in', ids)
48
+ .where('metaKey', '=', '_nextpress_path')
49
+ .select(['termId', 'metaKey', 'metaValue'])
50
+ .execute();
51
+
52
+ const metaByTermId = new Map<number, Map<string, string>>();
53
+ for (const row of metaData) {
54
+ const termId = Number(row.termId);
55
+ if (!metaByTermId.has(termId)) {
56
+ metaByTermId.set(termId, new Map());
57
+ }
58
+ metaByTermId.get(termId)?.set(row.metaKey || '', row.metaValue || '');
59
+ }
60
+
61
+ const combinedDataMap = new Map(combinedData.map(row => [Number(row.termId), row]));
62
+
63
+ return ids.map(id => {
64
+ const instance = new Term(id);
65
+
66
+ instance.termData = combinedDataMap.get(id);
67
+ instance.metaMap = metaByTermId.get(id) || new Map<string, string>();
68
+
69
+ return instance;
70
+ });
71
+ }
72
+
73
+ get path(): string { return this.metaMap?.get('_nextpress_path') ?? ''; }
74
+ get name(): string { return this.termData?.['name'] ?? ''; }
75
+ get slug(): string { return this.termData?.['slug'] ?? ''; }
76
+ get termGroup(): number { return this.termData?.['termGroup'] ? Number(this.termData['termGroup']) : 0; }
77
+ get parent(): number { return this.termData?.['parent'] ? Number(this.termData['parent']) : 0; }
78
+ get description(): string { return this.termData?.['description'] ?? ''; }
79
+ get termTaxonomyId(): number { return this.termData?.['termTaxonomyId'] ? Number(this.termData['termTaxonomyId']) : 0; }
80
+ get count(): number { return this.termData?.['count'] ? Number(this.termData['count']) : 0; }
81
+ get taxonomy(): string { return this.termData?.['taxonomy'] ?? ''; }
82
+ }
@@ -1,5 +1,6 @@
1
1
  import { Selectable } from "kysely";
2
- import { WpUser } from "../../wpdb/wpdb.interface";
2
+ import { WpUser } from "nextpress/wpdb/wpdb.interface";
3
+
3
4
  /**
4
5
  * Represents user entity.
5
6
  */
@@ -0,0 +1,86 @@
1
+ import { unserialize } from "php-serialize";
2
+ import { IUser } from "./user.interface";
3
+ import { wpdb } from "nextpress/wpdb/wpdb";
4
+
5
+ export class User implements IUser {
6
+ constructor(
7
+ public ID: number
8
+ ) {}
9
+
10
+ /** Raw user data from database. */
11
+ private userData?: Record<string, any>;
12
+ /** Map of user meta key-value pairs. */
13
+ private metaMap?: Map<string, string>;
14
+
15
+ /**
16
+ * Retrieves array of User instances by IDs.
17
+ *
18
+ * @param {number[]} ids - Array of user IDs to retrieve.
19
+ * @returns {Promise<User[]>} Promise resolving to array of User instances.
20
+ */
21
+ static async get(ids: number[]): Promise<User[]> {
22
+ ids = ids.filter(Boolean);
23
+ if (!ids || !ids.length) return [];
24
+
25
+ const usersData = await wpdb
26
+ .selectFrom('wpUsers')
27
+ .where('ID', 'in', ids)
28
+ .selectAll()
29
+ .execute();
30
+
31
+ const metaData = await wpdb
32
+ .selectFrom('wpUsermeta')
33
+ .where('userId', 'in', ids)
34
+ .where('metaKey', 'in', [
35
+ 'wp_capabilities',
36
+ 'show_admin_bar_front'
37
+ ])
38
+ .select(['userId', 'metaKey', 'metaValue'])
39
+ .execute();
40
+
41
+ const metaByUserId = new Map<number, Map<string, string>>();
42
+ for (const row of metaData) {
43
+ const userId = Number(row.userId);
44
+ if (!metaByUserId.has(userId)) {
45
+ metaByUserId.set(userId, new Map());
46
+ }
47
+ metaByUserId.get(userId)?.set(row.metaKey || '', row.metaValue || '');
48
+ }
49
+
50
+ const userDataMap = new Map(usersData.map(user => [Number(user.ID), user]));
51
+
52
+ return ids.map(id => {
53
+ const instance = new User(id);
54
+
55
+ instance.userData = userDataMap.get(id);
56
+ instance.metaMap = metaByUserId.get(id) || new Map<string, string>();
57
+
58
+ return instance;
59
+ });
60
+ }
61
+
62
+ get roles(): string[] {
63
+ const rawCapabilities = this.metaMap?.get('wp_capabilities');
64
+ if (!rawCapabilities) return [];
65
+ try {
66
+ return Object.keys(unserialize(rawCapabilities));
67
+ } catch (error: any) {
68
+ console.warn('Error while getting user: Could not unserialize php: ', error.message);
69
+ return [];
70
+ }
71
+ }
72
+
73
+ get showAdminBar(): boolean {
74
+ return this.metaMap?.get('show_admin_bar_front') === 'true';
75
+ }
76
+
77
+ get displayName(): string { return this.userData?.['displayName'] ?? ''; }
78
+ get userActivationKey(): string { return this.userData?.['userActivationKey'] ?? ''; }
79
+ get userEmail(): string { return this.userData?.['userEmail'] ?? ''; }
80
+ get userLogin(): string { return this.userData?.['userLogin'] ?? ''; }
81
+ get userNicename(): string { return this.userData?.['userNicename'] ?? ''; }
82
+ get userPass(): string { return this.userData?.['userPass'] ?? ''; }
83
+ get userRegistered(): Date { return this.userData?.['userRegistered'] ?? new Date(); }
84
+ get userStatus(): number { return this.userData?.['userStatus'] ? Number(this.userData['userStatus']) : 0; }
85
+ get userUrl(): string { return this.userData?.['userUrl'] ?? ''; }
86
+ }
@@ -1,13 +1,50 @@
1
+ import { EntityLoader, EntityQuery } from "./entity-loader";
1
2
  import { queriedObjectState } from "../globals";
2
- export class EntityLoaderBase {
3
+
4
+ /**
5
+ * Constructor type for entity queries.
6
+ */
7
+ type QueryConstructor<TArgs> = new (args: TArgs) => EntityQuery<TArgs>;
8
+
9
+ export interface ILoaderStorage<TEntity> {
10
+ loadQueue: Set<number>;
11
+ entityCache: Map<number, TEntity>;
12
+ promisedEntities: Map<number, Promise<TEntity[]>>;
13
+ }
14
+
15
+ export abstract class EntityLoaderBase<TEntity, TArgs> implements EntityLoader<TEntity, TArgs>
16
+ {
17
+ /** Query class used to fetch entity IDs. */
18
+ protected abstract queryClass: QueryConstructor<TArgs>;
19
+
20
+ /**
21
+ * Fetches entities from the database by ID.
22
+ *
23
+ * @param {number[]} ids Array of entity IDs.
24
+ *
25
+ * @returns {Promise<TEntity[]>} Array of fetched entities.
26
+ * @throws {Error} If database fetch fails.
27
+ */
28
+ protected abstract fetchFromDatabase(ids: number[]): Promise<TEntity[]>;
29
+
30
+ /**
31
+ * Gets the ID of an entity.
32
+ *
33
+ * @param {TEntity} entity The entity.
34
+ *
35
+ * @returns {number} The entity ID.
36
+ */
37
+ protected abstract getEntityId(entity: TEntity): number;
38
+
3
39
  /**
4
40
  * Retrieves the local state for the loader from the global cache.
5
41
  *
6
42
  * @returns {ILoaderStorage<TEntity>} The loader storage.
7
43
  */
8
- getLocalState() {
44
+ private getLocalState(): ILoaderStorage<TEntity> {
9
45
  const state = queriedObjectState();
10
46
  const loaderKey = `__loader_${this.constructor.name}`;
47
+
11
48
  if (!state.loaderStates[loaderKey]) {
12
49
  state.loaderStates[loaderKey] = {
13
50
  loadQueue: new Set(),
@@ -17,12 +54,13 @@ export class EntityLoaderBase {
17
54
  }
18
55
  return state.loaderStates[loaderKey];
19
56
  }
57
+
20
58
  /**
21
59
  * Adds IDs to the loading queue.
22
60
  *
23
61
  * @param {number[]} ids Array of IDs to prime.
24
62
  */
25
- prime(ids) {
63
+ public prime(ids: number[]): void {
26
64
  const state = this.getLocalState();
27
65
  for (const id of ids) {
28
66
  if (state.loadQueue.has(id) || state.entityCache.has(id) || state.promisedEntities.has(id)) {
@@ -31,6 +69,7 @@ export class EntityLoaderBase {
31
69
  state.loadQueue.add(id);
32
70
  }
33
71
  }
72
+
34
73
  /**
35
74
  * Finds entity IDs matching the arguments and queues them for loading.
36
75
  *
@@ -39,14 +78,17 @@ export class EntityLoaderBase {
39
78
  * @returns {Promise<{ ids: number[]; count: number }>} Matching IDs and total count.
40
79
  * @throws {Error} If query execution fails.
41
80
  */
42
- async findAndPrime(args) {
43
- var _a;
81
+ public async findAndPrime(args: TArgs): Promise<{ ids: number[]; count: number }> {
44
82
  const query = new this.queryClass(args);
83
+
45
84
  const ids = await query.getIds();
46
- const count = (_a = query.getCount()) !== null && _a !== void 0 ? _a : ids.length;
85
+ const count = query.getCount() ?? ids.length;
86
+
47
87
  this.get(ids);
88
+
48
89
  return { ids, count };
49
90
  }
91
+
50
92
  /**
51
93
  * Retrieves entities by ID.
52
94
  *
@@ -55,30 +97,42 @@ export class EntityLoaderBase {
55
97
  * @returns {Promise<TEntity[]>} Array of entities.
56
98
  * @throws {Error} If entity fetching fails.
57
99
  */
58
- async get(ids) {
100
+ public async get(ids: number[]): Promise<TEntity[]> {
59
101
  const state = this.getLocalState();
102
+
60
103
  const newIds = ids.filter(id => !state.entityCache.has(id) && !state.promisedEntities.has(id));
104
+
61
105
  if (newIds.length > 0) {
62
106
  this.prime(newIds);
63
107
  }
108
+
64
109
  if (state.loadQueue.size > 0) {
65
110
  const queue = Array.from(state.loadQueue);
66
111
  state.loadQueue.clear();
112
+
67
113
  const fetchPromise = this.fetchFromDatabase(queue).then(queuedEntities => {
68
114
  queuedEntities.forEach(entity => state.entityCache.set(this.getEntityId(entity), entity));
69
115
  queue.forEach(id => state.promisedEntities.delete(id));
70
116
  return queuedEntities;
71
117
  });
118
+
72
119
  queue.forEach(id => {
73
120
  state.promisedEntities.set(id, fetchPromise);
74
121
  });
75
122
  }
76
- const activePromises = Array.from(new Set(ids
77
- .map(id => state.promisedEntities.get(id))
78
- .filter((p) => !!p)));
123
+
124
+ const activePromises = Array.from(
125
+ new Set(
126
+ ids
127
+ .map(id => state.promisedEntities.get(id))
128
+ .filter((p): p is Promise<TEntity[]> => !!p)
129
+ )
130
+ );
131
+
79
132
  if (activePromises.length > 0) {
80
133
  await Promise.all(activePromises);
81
134
  }
135
+
82
136
  return ids.flatMap(id => {
83
137
  const entity = state.entityCache.get(id);
84
138
  return entity ? [entity] : [];
@@ -18,10 +18,7 @@ export interface EntityLoader<EntityT, QueryArgsT> {
18
18
  * @returns {Promise<{ids: number[], count: number}>} Array of found IDs and the total count.
19
19
  * @throws {Error} If the query fails.
20
20
  */
21
- findAndPrime: (args: QueryArgsT) => Promise<{
22
- ids: number[];
23
- count: number;
24
- }>;
21
+ findAndPrime: (args: QueryArgsT) => Promise<{ids: number[], count: number}>;
25
22
  /**
26
23
  * Retrieves entities by their IDs.
27
24
  *
@@ -31,6 +28,7 @@ export interface EntityLoader<EntityT, QueryArgsT> {
31
28
  */
32
29
  get: (ids: number[]) => Promise<EntityT[]>;
33
30
  }
31
+
34
32
  /**
35
33
  * Defines the contract for an entity query.
36
34
  *
@@ -0,0 +1,56 @@
1
+ import { OptionQuery } from "nextpress/repository/optionquery/option-query";
2
+ import { Option } from "../../entities/option/option";
3
+ import { IOption } from "../../entities/option/option.interface";
4
+ import { OptionQueryArgs } from "../../repository/optionquery/option-query-args";
5
+ import { EntityLoader } from "./entity-loader";
6
+ import { EntityLoaderBase } from "./entity-loader-base";
7
+
8
+ class OptionLoader extends EntityLoaderBase<IOption, OptionQueryArgs> {
9
+ private static _instance: OptionLoader;
10
+
11
+ protected queryClass = OptionQuery;
12
+
13
+ private constructor() {
14
+ super();
15
+ }
16
+
17
+ public static instance(): OptionLoader {
18
+ if (!this._instance) {
19
+ this._instance = new OptionLoader();
20
+ }
21
+ return this._instance;
22
+ }
23
+
24
+ protected async fetchFromDatabase(ids: number[]): Promise<IOption[]> {
25
+ return await Option.get(ids);
26
+ }
27
+
28
+ protected getEntityId(option: IOption): number {
29
+ return option.optionId;
30
+ }
31
+ }
32
+
33
+ declare global {
34
+ /** Global instance of the OptionLoader. */
35
+ var optionLoader: EntityLoader<IOption, OptionQueryArgs>
36
+
37
+ /**
38
+ * Retrieves an option value by name.
39
+ *
40
+ * @param {string} name The option name.
41
+ *
42
+ * @returns {Promise<string | undefined>} The option value or undefined.
43
+ */
44
+ var getOption: (name: string) => Promise<string | undefined>;
45
+ }
46
+
47
+ globalThis.optionLoader = OptionLoader.instance();
48
+ globalThis.getOption = async (name) => {
49
+ const foundOptions = await optionLoader.findAndPrime({
50
+ column: 'optionName',
51
+ operand: '=',
52
+ value: name
53
+ })
54
+
55
+ return (await optionLoader.get(foundOptions.ids))[0]?.optionValue;
56
+ }
@@ -0,0 +1,60 @@
1
+ import { PostQueryArgs } from "nextpress/repository/postquery/post-query-args";
2
+ import { Post } from "../../entities/post/post";
3
+ import { IPost } from "../../entities/post/post.interface";
4
+ import { EntityLoader } from "./entity-loader";
5
+ import { EntityLoaderBase } from "./entity-loader-base";
6
+ import { PostQuery } from "nextpress/repository/postquery/post-query";
7
+
8
+ class PostLoader extends EntityLoaderBase<IPost, PostQueryArgs> {
9
+ private static _instance: PostLoader;
10
+
11
+ protected queryClass = PostQuery;
12
+
13
+ private constructor() {
14
+ super();
15
+ }
16
+
17
+ public static instance(): PostLoader {
18
+ if (!this._instance) {
19
+ this._instance = new PostLoader();
20
+ }
21
+ return this._instance;
22
+ }
23
+
24
+ protected async fetchFromDatabase(ids: number[]): Promise<IPost[]> {
25
+ return await Post.get(ids);
26
+ }
27
+
28
+ protected getEntityId(post: IPost): number {
29
+ return post.ID;
30
+ }
31
+ }
32
+
33
+ declare global {
34
+ /** Global instance of the PostLoader. */
35
+ var postLoader: EntityLoader<IPost, PostQueryArgs>
36
+ /**
37
+ * Retrieves posts by their IDs.
38
+ *
39
+ * @param {number[]} ids Array of post IDs.
40
+ * @returns {Promise<IPost[]>} Array of posts.
41
+ */
42
+ var getPosts: (ids: number[]) => Promise<IPost[]>
43
+ /**
44
+ * Retrieves a single post by ID.
45
+ *
46
+ * @param {number} id The post ID.
47
+ * @returns {Promise<IPost | undefined>} The post or undefined.
48
+ */
49
+ var getPost: (id: number) => Promise<IPost | undefined>
50
+ }
51
+
52
+ globalThis.postLoader = PostLoader.instance();
53
+ globalThis.getPosts = async (ids) => {
54
+ return await postLoader.get(ids);
55
+ }
56
+ globalThis.getPost = async (id) => {
57
+ return (await postLoader.get([id]))[0];
58
+ }
59
+
60
+ export {};
@@ -0,0 +1,60 @@
1
+ import { ITerm } from "../../entities/term/term.interface";
2
+ import { Term } from "../../entities/term/term";
3
+ import { EntityLoader } from "./entity-loader";
4
+ import { EntityLoaderBase } from "./entity-loader-base";
5
+ import { TermQueryArgs } from "nextpress/repository/termquery/term-query-args";
6
+ import { TermQuery } from "nextpress/repository/termquery/term-query";
7
+
8
+ class TermLoader extends EntityLoaderBase<ITerm, TermQueryArgs> {
9
+ private static _instance: TermLoader;
10
+
11
+ protected queryClass = TermQuery;
12
+
13
+ private constructor() {
14
+ super();
15
+ }
16
+
17
+ public static instance(): TermLoader {
18
+ if (!this._instance) {
19
+ this._instance = new TermLoader();
20
+ }
21
+ return this._instance;
22
+ }
23
+
24
+ protected async fetchFromDatabase(ids: number[]): Promise<ITerm[]> {
25
+ return await Term.get(ids);
26
+ }
27
+
28
+ protected getEntityId(term: ITerm): number {
29
+ return term.termId;
30
+ }
31
+ }
32
+
33
+ declare global {
34
+ /** Global instance of the TermLoader. */
35
+ var termLoader: EntityLoader<ITerm, TermQueryArgs>
36
+ /**
37
+ * Retrieves terms by their IDs.
38
+ *
39
+ * @param {number[]} ids Array of term IDs.
40
+ * @returns {Promise<ITerm[]>} Array of terms.
41
+ */
42
+ var getTerms: (ids: number[]) => Promise<ITerm[]>
43
+ /**
44
+ * Retrieves a single term by ID.
45
+ *
46
+ * @param {number} id The term ID.
47
+ * @returns {Promise<ITerm | undefined>} The term or undefined.
48
+ */
49
+ var getTerm: (id: number) => Promise<ITerm | undefined>
50
+ }
51
+
52
+ globalThis.termLoader = TermLoader.instance();
53
+ globalThis.getTerms = async (ids) => {
54
+ return await termLoader.get(ids);
55
+ }
56
+ globalThis.getTerm = async (id) => {
57
+ return (await termLoader.get([id]))[0];
58
+ }
59
+
60
+ export {};
@@ -0,0 +1,61 @@
1
+ import { IUser } from "../../entities/user/user.interface";
2
+ import { User } from "../../entities/user/user";
3
+ import { EntityLoader } from "./entity-loader";
4
+ import { EntityLoaderBase } from "./entity-loader-base";
5
+ import { UserQueryArgs } from "nextpress/repository/userquery/user-query-args";
6
+ import { UserQuery } from "nextpress/repository/userquery/user-query";
7
+
8
+ class UserLoader extends EntityLoaderBase<IUser, UserQueryArgs> {
9
+ private static _instance: UserLoader;
10
+
11
+ protected queryClass = UserQuery;
12
+
13
+ private constructor() {
14
+ super();
15
+ }
16
+
17
+ public static instance(): UserLoader {
18
+ if (!this._instance) {
19
+ this._instance = new UserLoader();
20
+ }
21
+ return this._instance;
22
+ }
23
+
24
+ protected async fetchFromDatabase(ids: number[]): Promise<IUser[]> {
25
+ return await User.get(ids);
26
+ }
27
+
28
+ protected getEntityId(user: IUser): number {
29
+ return user.ID;
30
+ }
31
+ }
32
+
33
+ declare global {
34
+ /** Global instance of the UserLoader. */
35
+ var userLoader: EntityLoader<IUser, UserQueryArgs>
36
+ /**
37
+ * Retrieves users by their IDs.
38
+ *
39
+ * @param {number[]} ids Array of user IDs.
40
+ * @returns {Promise<IUser[]>} Array of users.
41
+ */
42
+ var getUsers: (ids: number[]) => Promise<IUser[]>
43
+
44
+ /**
45
+ * Retrieves a single user by ID.
46
+ *
47
+ * @param {number} id The user ID.
48
+ * @returns {Promise<IUser | undefined>} The user or undefined.
49
+ */
50
+ var getUser: (id: number) => Promise<IUser | undefined>
51
+ }
52
+
53
+ globalThis.userLoader = UserLoader.instance();
54
+ globalThis.getUsers = async (ids) => {
55
+ return await userLoader.get(ids);
56
+ }
57
+ globalThis.getUser = async (id) => {
58
+ return (await userLoader.get([id]))[0];
59
+ }
60
+
61
+ export {};
@@ -0,0 +1,76 @@
1
+ import { mapField } from "../../acf-functions/services/map-fields/map-fields";
2
+ import { IFieldLocation } from "../../entities/common";
3
+ import { FieldProps } from "../../acf-functions/types/components/field-props";
4
+ import { NextpressFieldGroup } from "nextpress/acf-functions/types/acf-field-group";
5
+
6
+ /** Specifies location to retrieve fields from. */
7
+ type Location = IFieldLocation | 'options';
8
+
9
+ declare global {
10
+ /**
11
+ * Retrieves, parses, and maps an Advanced Custom Fields (ACF) value to its corresponding component properties.
12
+ *
13
+ * @param {T} fieldGroup The configuration object defining the ACF field group and its schema.
14
+ * @param {K} selector The key name of the field to retrieve.
15
+ * @param {Location} [location] The database entity or context from which to load the field data. Accepts an `IFieldLocation` object or the string `'options'`. Defaults to the current queried object if omitted.
16
+ *
17
+ * @returns {Promise<FieldProps<T>[K]>} A promise resolving to the mapped field properties.
18
+ */
19
+ var getField: <
20
+ T extends NextpressFieldGroup,
21
+ K extends keyof FieldProps<T> & string
22
+ >(
23
+ fieldGroup: T,
24
+ selector: K,
25
+ location?: Location
26
+ ) => Promise<FieldProps<T>[K]>;
27
+ }
28
+
29
+ globalThis.getField = async (fieldGroup, selector, location) => {
30
+ if (!location) {
31
+ switch(queriedObject.objectType) {
32
+ case 'post':
33
+ location = await getThePost();
34
+ break;
35
+ // TODO: Add support for Term and User
36
+ // case 'term':
37
+ // location = await getTheTerm();
38
+ // break;
39
+ // case 'user':
40
+ // location = await getTheUser();
41
+ // break;
42
+ }
43
+ }
44
+ if (!location) return [];
45
+
46
+ const values = await (async () => {
47
+ if (location === 'options') {
48
+ const prefix = 'options_';
49
+
50
+ const foundOptions = await optionLoader.findAndPrime({
51
+ column: 'optionName',
52
+ operand: 'like',
53
+ value: `${prefix}%`
54
+ })
55
+
56
+ const options = await optionLoader.get(foundOptions.ids);
57
+
58
+ return options.map(option => ({
59
+ key: option.optionName.slice(prefix.length),
60
+ value: option.optionValue
61
+ }))
62
+ }
63
+
64
+ return await location.getFields(selector);
65
+ })() ?? [];
66
+
67
+ const valueMap: Map<string, string> = values.reduce((map, value) => {
68
+ map.set(value.key, value.value);
69
+ return map;
70
+ }, new Map());
71
+
72
+ const field = fieldGroup.fields.find(field => field.name === selector);
73
+ if (!field) return;
74
+
75
+ return mapField(field, valueMap) as any;
76
+ }
@@ -1,10 +1,12 @@
1
1
  import { cache } from 'react';
2
- import './nextpress-config/nextpress-config';
2
+
3
+ import './nextpress-config/nextpress-config'
3
4
  import './entity-loader/post-loader';
4
5
  import './entity-loader/term-loader';
5
6
  import './entity-loader/user-loader';
6
7
  import './entity-loader/option-loader';
7
8
  import './get-field/get-field';
9
+
8
10
  /**
9
11
  * Initializes and returns request-scoped storage for the application state.
10
12
  * Uses React cache to prevent state bleeding across requests.
@@ -13,8 +15,11 @@ import './get-field/get-field';
13
15
  */
14
16
  export const queriedObjectState = cache(() => {
15
17
  return {
16
- currentState: null,
17
- loaderStates: {}
18
+ currentState: null as any,
19
+ loaderStates: {} as Record<string, any>
18
20
  };
19
21
  });
22
+
20
23
  import './queried-object/queried-object';
24
+
25
+ export {};