@byline/core 0.9.3

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 (283) hide show
  1. package/LICENSE +373 -0
  2. package/README.md +17 -0
  3. package/dist/@types/admin-types.d.ts +275 -0
  4. package/dist/@types/admin-types.d.ts.map +1 -0
  5. package/dist/@types/admin-types.js +18 -0
  6. package/dist/@types/admin-types.js.map +1 -0
  7. package/dist/@types/collection-types.d.ts +816 -0
  8. package/dist/@types/collection-types.d.ts.map +1 -0
  9. package/dist/@types/collection-types.js +217 -0
  10. package/dist/@types/collection-types.js.map +1 -0
  11. package/dist/@types/db-types.d.ts +463 -0
  12. package/dist/@types/db-types.d.ts.map +1 -0
  13. package/dist/@types/db-types.js +2 -0
  14. package/dist/@types/db-types.js.map +1 -0
  15. package/dist/@types/field-data-types.d.ts +147 -0
  16. package/dist/@types/field-data-types.d.ts.map +1 -0
  17. package/dist/@types/field-data-types.js +38 -0
  18. package/dist/@types/field-data-types.js.map +1 -0
  19. package/dist/@types/field-types.d.ts +579 -0
  20. package/dist/@types/field-types.d.ts.map +1 -0
  21. package/dist/@types/field-types.js +32 -0
  22. package/dist/@types/field-types.js.map +1 -0
  23. package/dist/@types/index.d.ts +18 -0
  24. package/dist/@types/index.d.ts.map +1 -0
  25. package/dist/@types/index.js +18 -0
  26. package/dist/@types/index.js.map +1 -0
  27. package/dist/@types/populate-types.d.ts +54 -0
  28. package/dist/@types/populate-types.d.ts.map +1 -0
  29. package/dist/@types/populate-types.js +9 -0
  30. package/dist/@types/populate-types.js.map +1 -0
  31. package/dist/@types/query-predicate.d.ts +74 -0
  32. package/dist/@types/query-predicate.d.ts.map +1 -0
  33. package/dist/@types/query-predicate.js +9 -0
  34. package/dist/@types/query-predicate.js.map +1 -0
  35. package/dist/@types/site-config.d.ts +212 -0
  36. package/dist/@types/site-config.d.ts.map +1 -0
  37. package/dist/@types/site-config.js +9 -0
  38. package/dist/@types/site-config.js.map +1 -0
  39. package/dist/@types/storage-types.d.ts +86 -0
  40. package/dist/@types/storage-types.d.ts.map +1 -0
  41. package/dist/@types/storage-types.js +9 -0
  42. package/dist/@types/storage-types.js.map +1 -0
  43. package/dist/@types/store-types.d.ts +134 -0
  44. package/dist/@types/store-types.d.ts.map +1 -0
  45. package/dist/@types/store-types.js +24 -0
  46. package/dist/@types/store-types.js.map +1 -0
  47. package/dist/@types/type-utils.d.ts +17 -0
  48. package/dist/@types/type-utils.d.ts.map +1 -0
  49. package/dist/@types/type-utils.js +9 -0
  50. package/dist/@types/type-utils.js.map +1 -0
  51. package/dist/auth/apply-before-read.d.ts +36 -0
  52. package/dist/auth/apply-before-read.d.ts.map +1 -0
  53. package/dist/auth/apply-before-read.js +68 -0
  54. package/dist/auth/apply-before-read.js.map +1 -0
  55. package/dist/auth/apply-before-read.test.node.d.ts +9 -0
  56. package/dist/auth/apply-before-read.test.node.d.ts.map +1 -0
  57. package/dist/auth/apply-before-read.test.node.js +144 -0
  58. package/dist/auth/apply-before-read.test.node.js.map +1 -0
  59. package/dist/auth/assert-actor-can-perform.d.ts +39 -0
  60. package/dist/auth/assert-actor-can-perform.d.ts.map +1 -0
  61. package/dist/auth/assert-actor-can-perform.js +64 -0
  62. package/dist/auth/assert-actor-can-perform.js.map +1 -0
  63. package/dist/auth/assert-actor-can-perform.test.node.d.ts +9 -0
  64. package/dist/auth/assert-actor-can-perform.test.node.d.ts.map +1 -0
  65. package/dist/auth/assert-actor-can-perform.test.node.js +119 -0
  66. package/dist/auth/assert-actor-can-perform.test.node.js.map +1 -0
  67. package/dist/auth/index.d.ts +11 -0
  68. package/dist/auth/index.d.ts.map +1 -0
  69. package/dist/auth/index.js +11 -0
  70. package/dist/auth/index.js.map +1 -0
  71. package/dist/auth/register-collection-abilities.d.ts +40 -0
  72. package/dist/auth/register-collection-abilities.d.ts.map +1 -0
  73. package/dist/auth/register-collection-abilities.js +87 -0
  74. package/dist/auth/register-collection-abilities.js.map +1 -0
  75. package/dist/auth/register-collection-abilities.test.node.d.ts +9 -0
  76. package/dist/auth/register-collection-abilities.test.node.d.ts.map +1 -0
  77. package/dist/auth/register-collection-abilities.test.node.js +124 -0
  78. package/dist/auth/register-collection-abilities.test.node.js.map +1 -0
  79. package/dist/config/config.d.ts +10 -0
  80. package/dist/config/config.d.ts.map +1 -0
  81. package/dist/config/config.js +108 -0
  82. package/dist/config/config.js.map +1 -0
  83. package/dist/config/routes.d.ts +16 -0
  84. package/dist/config/routes.d.ts.map +1 -0
  85. package/dist/config/routes.js +26 -0
  86. package/dist/config/routes.js.map +1 -0
  87. package/dist/config/validate-admin-configs.d.ts +33 -0
  88. package/dist/config/validate-admin-configs.d.ts.map +1 -0
  89. package/dist/config/validate-admin-configs.js +250 -0
  90. package/dist/config/validate-admin-configs.js.map +1 -0
  91. package/dist/config/validate-admin-configs.test.node.d.ts +9 -0
  92. package/dist/config/validate-admin-configs.test.node.d.ts.map +1 -0
  93. package/dist/config/validate-admin-configs.test.node.js +224 -0
  94. package/dist/config/validate-admin-configs.test.node.js.map +1 -0
  95. package/dist/config/validate-collections.d.ts +33 -0
  96. package/dist/config/validate-collections.d.ts.map +1 -0
  97. package/dist/config/validate-collections.js +70 -0
  98. package/dist/config/validate-collections.js.map +1 -0
  99. package/dist/config/validate-collections.test.node.d.ts +9 -0
  100. package/dist/config/validate-collections.test.node.d.ts.map +1 -0
  101. package/dist/config/validate-collections.test.node.js +149 -0
  102. package/dist/config/validate-collections.test.node.js.map +1 -0
  103. package/dist/core.d.ts +89 -0
  104. package/dist/core.d.ts.map +1 -0
  105. package/dist/core.js +99 -0
  106. package/dist/core.js.map +1 -0
  107. package/dist/defaults/default-values.d.ts +13 -0
  108. package/dist/defaults/default-values.d.ts.map +1 -0
  109. package/dist/defaults/default-values.js +60 -0
  110. package/dist/defaults/default-values.js.map +1 -0
  111. package/dist/index.d.ts +20 -0
  112. package/dist/index.d.ts.map +1 -0
  113. package/dist/index.js +36 -0
  114. package/dist/index.js.map +1 -0
  115. package/dist/lib/errors.d.ts +98 -0
  116. package/dist/lib/errors.d.ts.map +1 -0
  117. package/dist/lib/errors.js +134 -0
  118. package/dist/lib/errors.js.map +1 -0
  119. package/dist/lib/logger.d.ts +62 -0
  120. package/dist/lib/logger.d.ts.map +1 -0
  121. package/dist/lib/logger.js +120 -0
  122. package/dist/lib/logger.js.map +1 -0
  123. package/dist/lib/registry.d.ts +65 -0
  124. package/dist/lib/registry.d.ts.map +1 -0
  125. package/dist/lib/registry.js +133 -0
  126. package/dist/lib/registry.js.map +1 -0
  127. package/dist/logger/index.d.ts +3 -0
  128. package/dist/logger/index.d.ts.map +1 -0
  129. package/dist/logger/index.js +3 -0
  130. package/dist/logger/index.js.map +1 -0
  131. package/dist/patches/apply-patches.d.ts +21 -0
  132. package/dist/patches/apply-patches.d.ts.map +1 -0
  133. package/dist/patches/apply-patches.js +357 -0
  134. package/dist/patches/apply-patches.js.map +1 -0
  135. package/dist/patches/index.d.ts +3 -0
  136. package/dist/patches/index.d.ts.map +1 -0
  137. package/dist/patches/index.js +4 -0
  138. package/dist/patches/index.js.map +1 -0
  139. package/dist/patches/patch-types.d.ts +82 -0
  140. package/dist/patches/patch-types.d.ts.map +1 -0
  141. package/dist/patches/patch-types.js +3 -0
  142. package/dist/patches/patch-types.js.map +1 -0
  143. package/dist/patches/patch.test.node.d.ts +2 -0
  144. package/dist/patches/patch.test.node.d.ts.map +1 -0
  145. package/dist/patches/patch.test.node.js +193 -0
  146. package/dist/patches/patch.test.node.js.map +1 -0
  147. package/dist/query/parse-where.d.ts +100 -0
  148. package/dist/query/parse-where.d.ts.map +1 -0
  149. package/dist/query/parse-where.js +352 -0
  150. package/dist/query/parse-where.js.map +1 -0
  151. package/dist/query/parse-where.test.node.d.ts +9 -0
  152. package/dist/query/parse-where.test.node.d.ts.map +1 -0
  153. package/dist/query/parse-where.test.node.js +581 -0
  154. package/dist/query/parse-where.test.node.js.map +1 -0
  155. package/dist/schemas/zod/builder.d.ts +466 -0
  156. package/dist/schemas/zod/builder.d.ts.map +1 -0
  157. package/dist/schemas/zod/builder.js +276 -0
  158. package/dist/schemas/zod/builder.js.map +1 -0
  159. package/dist/schemas/zod/cache.d.ts +14 -0
  160. package/dist/schemas/zod/cache.d.ts.map +1 -0
  161. package/dist/schemas/zod/cache.js +40 -0
  162. package/dist/schemas/zod/cache.js.map +1 -0
  163. package/dist/schemas/zod/index.d.ts +4 -0
  164. package/dist/schemas/zod/index.d.ts.map +1 -0
  165. package/dist/schemas/zod/index.js +4 -0
  166. package/dist/schemas/zod/index.js.map +1 -0
  167. package/dist/schemas/zod/types.d.ts +13 -0
  168. package/dist/schemas/zod/types.d.ts.map +1 -0
  169. package/dist/schemas/zod/types.js +2 -0
  170. package/dist/schemas/zod/types.js.map +1 -0
  171. package/dist/services/collection-bootstrap.d.ts +46 -0
  172. package/dist/services/collection-bootstrap.d.ts.map +1 -0
  173. package/dist/services/collection-bootstrap.js +108 -0
  174. package/dist/services/collection-bootstrap.js.map +1 -0
  175. package/dist/services/collection-bootstrap.test.node.d.ts +9 -0
  176. package/dist/services/collection-bootstrap.test.node.d.ts.map +1 -0
  177. package/dist/services/collection-bootstrap.test.node.js +208 -0
  178. package/dist/services/collection-bootstrap.test.node.js.map +1 -0
  179. package/dist/services/document-lifecycle.d.ts +245 -0
  180. package/dist/services/document-lifecycle.d.ts.map +1 -0
  181. package/dist/services/document-lifecycle.js +481 -0
  182. package/dist/services/document-lifecycle.js.map +1 -0
  183. package/dist/services/document-lifecycle.test.node.d.ts +9 -0
  184. package/dist/services/document-lifecycle.test.node.d.ts.map +1 -0
  185. package/dist/services/document-lifecycle.test.node.js +781 -0
  186. package/dist/services/document-lifecycle.test.node.js.map +1 -0
  187. package/dist/services/document-read.d.ts +26 -0
  188. package/dist/services/document-read.d.ts.map +1 -0
  189. package/dist/services/document-read.js +60 -0
  190. package/dist/services/document-read.js.map +1 -0
  191. package/dist/services/field-upload.d.ts +100 -0
  192. package/dist/services/field-upload.d.ts.map +1 -0
  193. package/dist/services/field-upload.js +328 -0
  194. package/dist/services/field-upload.js.map +1 -0
  195. package/dist/services/field-upload.test.node.d.ts +9 -0
  196. package/dist/services/field-upload.test.node.d.ts.map +1 -0
  197. package/dist/services/field-upload.test.node.js +337 -0
  198. package/dist/services/field-upload.test.node.js.map +1 -0
  199. package/dist/services/index.d.ts +10 -0
  200. package/dist/services/index.d.ts.map +1 -0
  201. package/dist/services/index.js +11 -0
  202. package/dist/services/index.js.map +1 -0
  203. package/dist/services/populate.d.ts +299 -0
  204. package/dist/services/populate.d.ts.map +1 -0
  205. package/dist/services/populate.js +484 -0
  206. package/dist/services/populate.js.map +1 -0
  207. package/dist/services/populate.test.node.d.ts +9 -0
  208. package/dist/services/populate.test.node.d.ts.map +1 -0
  209. package/dist/services/populate.test.node.js +910 -0
  210. package/dist/services/populate.test.node.js.map +1 -0
  211. package/dist/services/relation-projection.d.ts +52 -0
  212. package/dist/services/relation-projection.d.ts.map +1 -0
  213. package/dist/services/relation-projection.js +81 -0
  214. package/dist/services/relation-projection.js.map +1 -0
  215. package/dist/services/richtext-populate.d.ts +87 -0
  216. package/dist/services/richtext-populate.d.ts.map +1 -0
  217. package/dist/services/richtext-populate.js +189 -0
  218. package/dist/services/richtext-populate.js.map +1 -0
  219. package/dist/services/richtext-populate.test.node.d.ts +9 -0
  220. package/dist/services/richtext-populate.test.node.d.ts.map +1 -0
  221. package/dist/services/richtext-populate.test.node.js +197 -0
  222. package/dist/services/richtext-populate.test.node.js.map +1 -0
  223. package/dist/storage/collection-fingerprint.d.ts +21 -0
  224. package/dist/storage/collection-fingerprint.d.ts.map +1 -0
  225. package/dist/storage/collection-fingerprint.js +172 -0
  226. package/dist/storage/collection-fingerprint.js.map +1 -0
  227. package/dist/storage/collection-fingerprint.test.node.d.ts +9 -0
  228. package/dist/storage/collection-fingerprint.test.node.d.ts.map +1 -0
  229. package/dist/storage/collection-fingerprint.test.node.js +256 -0
  230. package/dist/storage/collection-fingerprint.test.node.js.map +1 -0
  231. package/dist/storage/field-store-map.d.ts +59 -0
  232. package/dist/storage/field-store-map.d.ts.map +1 -0
  233. package/dist/storage/field-store-map.js +75 -0
  234. package/dist/storage/field-store-map.js.map +1 -0
  235. package/dist/storage/field-store-map.test.node.d.ts +9 -0
  236. package/dist/storage/field-store-map.test.node.d.ts.map +1 -0
  237. package/dist/storage/field-store-map.test.node.js +117 -0
  238. package/dist/storage/field-store-map.test.node.js.map +1 -0
  239. package/dist/storage/index.d.ts +10 -0
  240. package/dist/storage/index.d.ts.map +1 -0
  241. package/dist/storage/index.js +10 -0
  242. package/dist/storage/index.js.map +1 -0
  243. package/dist/utils/normalise-dates.d.ts +15 -0
  244. package/dist/utils/normalise-dates.d.ts.map +1 -0
  245. package/dist/utils/normalise-dates.js +22 -0
  246. package/dist/utils/normalise-dates.js.map +1 -0
  247. package/dist/utils/slugify.d.ts +56 -0
  248. package/dist/utils/slugify.d.ts.map +1 -0
  249. package/dist/utils/slugify.js +91 -0
  250. package/dist/utils/slugify.js.map +1 -0
  251. package/dist/utils/slugify.test.node.d.ts +9 -0
  252. package/dist/utils/slugify.test.node.d.ts.map +1 -0
  253. package/dist/utils/slugify.test.node.js +86 -0
  254. package/dist/utils/slugify.test.node.js.map +1 -0
  255. package/dist/utils/storage-utils.d.ts +36 -0
  256. package/dist/utils/storage-utils.d.ts.map +1 -0
  257. package/dist/utils/storage-utils.js +38 -0
  258. package/dist/utils/storage-utils.js.map +1 -0
  259. package/dist/utils/utils.general.d.ts +64 -0
  260. package/dist/utils/utils.general.d.ts.map +1 -0
  261. package/dist/utils/utils.general.js +219 -0
  262. package/dist/utils/utils.general.js.map +1 -0
  263. package/dist/validation/index.d.ts +9 -0
  264. package/dist/validation/index.d.ts.map +1 -0
  265. package/dist/validation/index.js +9 -0
  266. package/dist/validation/index.js.map +1 -0
  267. package/dist/validation/shared.d.ts +36 -0
  268. package/dist/validation/shared.d.ts.map +1 -0
  269. package/dist/validation/shared.js +42 -0
  270. package/dist/validation/shared.js.map +1 -0
  271. package/dist/workflow/index.d.ts +2 -0
  272. package/dist/workflow/index.d.ts.map +1 -0
  273. package/dist/workflow/index.js +3 -0
  274. package/dist/workflow/index.js.map +1 -0
  275. package/dist/workflow/workflow.d.ts +40 -0
  276. package/dist/workflow/workflow.d.ts.map +1 -0
  277. package/dist/workflow/workflow.js +96 -0
  278. package/dist/workflow/workflow.js.map +1 -0
  279. package/dist/workflow/workflow.test.node.d.ts +2 -0
  280. package/dist/workflow/workflow.test.node.d.ts.map +1 -0
  281. package/dist/workflow/workflow.test.node.js +198 -0
  282. package/dist/workflow/workflow.test.node.js.map +1 -0
  283. package/package.json +88 -0
@@ -0,0 +1,119 @@
1
+ /**
2
+ * This Source Code is subject to the terms of the Mozilla Public
3
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
4
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
+ *
6
+ * Copyright (c) Infonomic Company Limited
7
+ */
8
+ import { AdminAuth, AuthError, AuthErrorCodes, createRequestContext, createSuperAdminContext, } from '@byline/auth';
9
+ import { describe, expect, it } from 'vitest';
10
+ import { assertActorCanPerform } from './assert-actor-can-perform.js';
11
+ describe('assertActorCanPerform', () => {
12
+ describe('missing context', () => {
13
+ it('throws ERR_UNAUTHENTICATED when context is undefined', () => {
14
+ try {
15
+ assertActorCanPerform(undefined, 'pages', 'read');
16
+ expect.fail('expected ERR_UNAUTHENTICATED');
17
+ }
18
+ catch (err) {
19
+ expect(err).toBeInstanceOf(AuthError);
20
+ expect(err.code).toBe(AuthErrorCodes.UNAUTHENTICATED);
21
+ }
22
+ });
23
+ });
24
+ describe('null actor (anonymous)', () => {
25
+ it('permits read with readMode: published', () => {
26
+ const ctx = createRequestContext({ actor: null, readMode: 'published' });
27
+ expect(() => assertActorCanPerform(ctx, 'pages', 'read')).not.toThrow();
28
+ });
29
+ it('rejects read with readMode: any', () => {
30
+ const ctx = createRequestContext({ actor: null, readMode: 'any' });
31
+ try {
32
+ assertActorCanPerform(ctx, 'pages', 'read');
33
+ expect.fail('expected ERR_UNAUTHENTICATED');
34
+ }
35
+ catch (err) {
36
+ expect(err.code).toBe(AuthErrorCodes.UNAUTHENTICATED);
37
+ expect(err.message).toMatch(/readMode.*published/);
38
+ }
39
+ });
40
+ it('rejects read when readMode is unset', () => {
41
+ const ctx = createRequestContext({ actor: null });
42
+ try {
43
+ assertActorCanPerform(ctx, 'pages', 'read');
44
+ expect.fail('expected ERR_UNAUTHENTICATED');
45
+ }
46
+ catch (err) {
47
+ expect(err.code).toBe(AuthErrorCodes.UNAUTHENTICATED);
48
+ }
49
+ });
50
+ it('rejects every non-read verb regardless of readMode', () => {
51
+ const ctx = createRequestContext({ actor: null, readMode: 'published' });
52
+ for (const verb of ['create', 'update', 'delete', 'publish', 'changeStatus']) {
53
+ try {
54
+ assertActorCanPerform(ctx, 'pages', verb);
55
+ expect.fail(`expected ERR_UNAUTHENTICATED for ${verb}`);
56
+ }
57
+ catch (err) {
58
+ expect(err.code).toBe(AuthErrorCodes.UNAUTHENTICATED);
59
+ }
60
+ }
61
+ });
62
+ });
63
+ describe('actor with abilities', () => {
64
+ it('permits the verb when the specific ability is held', () => {
65
+ const actor = new AdminAuth({
66
+ id: 'editor-1',
67
+ abilities: ['collections.pages.update'],
68
+ });
69
+ const ctx = createRequestContext({ actor });
70
+ expect(() => assertActorCanPerform(ctx, 'pages', 'update')).not.toThrow();
71
+ });
72
+ it('throws ERR_FORBIDDEN when the specific ability is missing', () => {
73
+ const actor = new AdminAuth({
74
+ id: 'editor-1',
75
+ abilities: ['collections.pages.read'],
76
+ });
77
+ const ctx = createRequestContext({ actor });
78
+ try {
79
+ assertActorCanPerform(ctx, 'pages', 'publish');
80
+ expect.fail('expected ERR_FORBIDDEN');
81
+ }
82
+ catch (err) {
83
+ expect(err.code).toBe(AuthErrorCodes.FORBIDDEN);
84
+ expect(err.message).toContain('collections.pages.publish');
85
+ }
86
+ });
87
+ it('checks the ability against the specific collectionPath', () => {
88
+ const actor = new AdminAuth({
89
+ id: 'editor-1',
90
+ abilities: ['collections.pages.update'], // has update for 'pages' only
91
+ });
92
+ const ctx = createRequestContext({ actor });
93
+ expect(() => assertActorCanPerform(ctx, 'pages', 'update')).not.toThrow();
94
+ try {
95
+ assertActorCanPerform(ctx, 'news', 'update');
96
+ expect.fail('expected ERR_FORBIDDEN — wrong collection');
97
+ }
98
+ catch (err) {
99
+ expect(err.code).toBe(AuthErrorCodes.FORBIDDEN);
100
+ expect(err.message).toContain('collections.news.update');
101
+ }
102
+ });
103
+ });
104
+ describe('super-admin', () => {
105
+ it('passes every verb on every collection without explicit abilities', () => {
106
+ const ctx = createSuperAdminContext();
107
+ const verbs = ['read', 'create', 'update', 'delete', 'publish', 'changeStatus'];
108
+ for (const verb of verbs) {
109
+ expect(() => assertActorCanPerform(ctx, 'any-collection', verb)).not.toThrow();
110
+ }
111
+ });
112
+ it('passes even when readMode would normally reject a null actor', () => {
113
+ // Super-admin doesn't care about readMode at this layer.
114
+ const ctx = createSuperAdminContext();
115
+ expect(() => assertActorCanPerform(ctx, 'pages', 'read')).not.toThrow();
116
+ });
117
+ });
118
+ });
119
+ //# sourceMappingURL=assert-actor-can-perform.test.node.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assert-actor-can-perform.test.node.js","sourceRoot":"","sources":["../../src/auth/assert-actor-can-perform.test.node.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,SAAS,EACT,SAAS,EACT,cAAc,EACd,oBAAoB,EACpB,uBAAuB,GACxB,MAAM,cAAc,CAAA;AACrB,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAA;AAE7C,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAA;AAErE,QAAQ,CAAC,uBAAuB,EAAE,GAAG,EAAE;IACrC,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;QAC/B,EAAE,CAAC,sDAAsD,EAAE,GAAG,EAAE;YAC9D,IAAI,CAAC;gBACH,qBAAqB,CAAC,SAAS,EAAE,OAAO,EAAE,MAAM,CAAC,CAAA;gBACjD,MAAM,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAA;YAC7C,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,CAAC,GAAG,CAAC,CAAC,cAAc,CAAC,SAAS,CAAC,CAAA;gBACrC,MAAM,CAAE,GAAiB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,eAAe,CAAC,CAAA;YACtE,CAAC;QACH,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,QAAQ,CAAC,wBAAwB,EAAE,GAAG,EAAE;QACtC,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;YAC/C,MAAM,GAAG,GAAG,oBAAoB,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC,CAAA;YACxE,MAAM,CAAC,GAAG,EAAE,CAAC,qBAAqB,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,CAAA;QACzE,CAAC,CAAC,CAAA;QAEF,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;YACzC,MAAM,GAAG,GAAG,oBAAoB,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAA;YAClE,IAAI,CAAC;gBACH,qBAAqB,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,CAAC,CAAA;gBAC3C,MAAM,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAA;YAC7C,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,CAAE,GAAiB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,eAAe,CAAC,CAAA;gBACpE,MAAM,CAAE,GAAiB,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,qBAAqB,CAAC,CAAA;YACnE,CAAC;QACH,CAAC,CAAC,CAAA;QAEF,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;YAC7C,MAAM,GAAG,GAAG,oBAAoB,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;YACjD,IAAI,CAAC;gBACH,qBAAqB,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,CAAC,CAAA;gBAC3C,MAAM,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAA;YAC7C,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,CAAE,GAAiB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,eAAe,CAAC,CAAA;YACtE,CAAC;QACH,CAAC,CAAC,CAAA;QAEF,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;YAC5D,MAAM,GAAG,GAAG,oBAAoB,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC,CAAA;YACxE,KAAK,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,cAAc,CAAU,EAAE,CAAC;gBACtF,IAAI,CAAC;oBACH,qBAAqB,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,CAAC,CAAA;oBACzC,MAAM,CAAC,IAAI,CAAC,oCAAoC,IAAI,EAAE,CAAC,CAAA;gBACzD,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,MAAM,CAAE,GAAiB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,eAAe,CAAC,CAAA;gBACtE,CAAC;YACH,CAAC;QACH,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,QAAQ,CAAC,sBAAsB,EAAE,GAAG,EAAE;QACpC,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;YAC5D,MAAM,KAAK,GAAG,IAAI,SAAS,CAAC;gBAC1B,EAAE,EAAE,UAAU;gBACd,SAAS,EAAE,CAAC,0BAA0B,CAAC;aACxC,CAAC,CAAA;YACF,MAAM,GAAG,GAAG,oBAAoB,CAAC,EAAE,KAAK,EAAE,CAAC,CAAA;YAC3C,MAAM,CAAC,GAAG,EAAE,CAAC,qBAAqB,CAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,CAAA;QAC3E,CAAC,CAAC,CAAA;QAEF,EAAE,CAAC,2DAA2D,EAAE,GAAG,EAAE;YACnE,MAAM,KAAK,GAAG,IAAI,SAAS,CAAC;gBAC1B,EAAE,EAAE,UAAU;gBACd,SAAS,EAAE,CAAC,wBAAwB,CAAC;aACtC,CAAC,CAAA;YACF,MAAM,GAAG,GAAG,oBAAoB,CAAC,EAAE,KAAK,EAAE,CAAC,CAAA;YAC3C,IAAI,CAAC;gBACH,qBAAqB,CAAC,GAAG,EAAE,OAAO,EAAE,SAAS,CAAC,CAAA;gBAC9C,MAAM,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAA;YACvC,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,CAAE,GAAiB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,CAAA;gBAC9D,MAAM,CAAE,GAAiB,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,2BAA2B,CAAC,CAAA;YAC3E,CAAC;QACH,CAAC,CAAC,CAAA;QAEF,EAAE,CAAC,wDAAwD,EAAE,GAAG,EAAE;YAChE,MAAM,KAAK,GAAG,IAAI,SAAS,CAAC;gBAC1B,EAAE,EAAE,UAAU;gBACd,SAAS,EAAE,CAAC,0BAA0B,CAAC,EAAE,8BAA8B;aACxE,CAAC,CAAA;YACF,MAAM,GAAG,GAAG,oBAAoB,CAAC,EAAE,KAAK,EAAE,CAAC,CAAA;YAC3C,MAAM,CAAC,GAAG,EAAE,CAAC,qBAAqB,CAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,CAAA;YACzE,IAAI,CAAC;gBACH,qBAAqB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAA;gBAC5C,MAAM,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAAA;YAC1D,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,CAAE,GAAiB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,CAAA;gBAC9D,MAAM,CAAE,GAAiB,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,yBAAyB,CAAC,CAAA;YACzE,CAAC;QACH,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;QAC3B,EAAE,CAAC,kEAAkE,EAAE,GAAG,EAAE;YAC1E,MAAM,GAAG,GAAG,uBAAuB,EAAE,CAAA;YACrC,MAAM,KAAK,GAAG,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,cAAc,CAAU,CAAA;YACxF,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,MAAM,CAAC,GAAG,EAAE,CAAC,qBAAqB,CAAC,GAAG,EAAE,gBAAgB,EAAE,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,CAAA;YAChF,CAAC;QACH,CAAC,CAAC,CAAA;QAEF,EAAE,CAAC,8DAA8D,EAAE,GAAG,EAAE;YACtE,yDAAyD;YACzD,MAAM,GAAG,GAAG,uBAAuB,EAAE,CAAA;YACrC,MAAM,CAAC,GAAG,EAAE,CAAC,qBAAqB,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,CAAA;QACzE,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * This Source Code is subject to the terms of the Mozilla Public
3
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
4
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
+ *
6
+ * Copyright (c) Infonomic Company Limited
7
+ */
8
+ export { applyBeforeRead } from './apply-before-read.js';
9
+ export { assertActorCanPerform } from './assert-actor-can-perform.js';
10
+ export { COLLECTION_ABILITY_VERBS, type CollectionAbilityVerb, collectionAbilityKey, registerCollectionAbilities, } from './register-collection-abilities.js';
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AACxD,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAA;AACrE,OAAO,EACL,wBAAwB,EACxB,KAAK,qBAAqB,EAC1B,oBAAoB,EACpB,2BAA2B,GAC5B,MAAM,oCAAoC,CAAA"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * This Source Code is subject to the terms of the Mozilla Public
3
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
4
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
+ *
6
+ * Copyright (c) Infonomic Company Limited
7
+ */
8
+ export { applyBeforeRead } from './apply-before-read.js';
9
+ export { assertActorCanPerform } from './assert-actor-can-perform.js';
10
+ export { COLLECTION_ABILITY_VERBS, collectionAbilityKey, registerCollectionAbilities, } from './register-collection-abilities.js';
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AACxD,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAA;AACrE,OAAO,EACL,wBAAwB,EAExB,oBAAoB,EACpB,2BAA2B,GAC5B,MAAM,oCAAoC,CAAA"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * This Source Code is subject to the terms of the Mozilla Public
3
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
4
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
+ *
6
+ * Copyright (c) Infonomic Company Limited
7
+ */
8
+ import type { AbilityRegistry } from '@byline/auth';
9
+ import type { CollectionDefinition } from '../@types/index.js';
10
+ /**
11
+ * Auto-register the CRUD + workflow abilities contributed by a collection.
12
+ *
13
+ * Every registered collection contributes exactly six abilities, all in
14
+ * the `collections.<path>` group:
15
+ *
16
+ * - `collections.<path>.read` — enumerate / fetch documents
17
+ * - `collections.<path>.create` — create new documents
18
+ * - `collections.<path>.update` — modify existing documents
19
+ * - `collections.<path>.delete` — delete documents (soft or hard)
20
+ * - `collections.<path>.publish` — transition a document into the
21
+ * `published` status
22
+ * - `collections.<path>.changeStatus` — any other workflow transition
23
+ * (draft → custom state, etc.)
24
+ *
25
+ * Registration is unconditional: every collection in Byline has a workflow
26
+ * (the default `draft → published → archived` one when not explicitly
27
+ * configured), so `publish` and `changeStatus` always apply. Keeping the
28
+ * six-ability contract uniform makes the role editor UI predictable and
29
+ * avoids hidden conditional logic downstream.
30
+ *
31
+ * Called from `initBylineCore()` for each declared collection. See
32
+ * docs/analysis/AUTHN-AUTHZ-ANALYSIS.md §3 and Phase 1.
33
+ */
34
+ export declare function registerCollectionAbilities(registry: AbilityRegistry, definition: CollectionDefinition): void;
35
+ /** The ability suffixes that every collection contributes. Exposed for contract tests. */
36
+ export declare const COLLECTION_ABILITY_VERBS: readonly ["read", "create", "update", "delete", "publish", "changeStatus"];
37
+ export type CollectionAbilityVerb = (typeof COLLECTION_ABILITY_VERBS)[number];
38
+ /** Compute the full ability key for a collection path and verb. */
39
+ export declare function collectionAbilityKey(path: string, verb: CollectionAbilityVerb): string;
40
+ //# sourceMappingURL=register-collection-abilities.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register-collection-abilities.d.ts","sourceRoot":"","sources":["../../src/auth/register-collection-abilities.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAEnD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAA;AAE9D;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,2BAA2B,CACzC,QAAQ,EAAE,eAAe,EACzB,UAAU,EAAE,oBAAoB,GAC/B,IAAI,CA0CN;AAED,0FAA0F;AAC1F,eAAO,MAAM,wBAAwB,4EAO3B,CAAA;AAEV,MAAM,MAAM,qBAAqB,GAAG,CAAC,OAAO,wBAAwB,CAAC,CAAC,MAAM,CAAC,CAAA;AAE7E,mEAAmE;AACnE,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,qBAAqB,GAAG,MAAM,CAEtF"}
@@ -0,0 +1,87 @@
1
+ /**
2
+ * This Source Code is subject to the terms of the Mozilla Public
3
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
4
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
+ *
6
+ * Copyright (c) Infonomic Company Limited
7
+ */
8
+ /**
9
+ * Auto-register the CRUD + workflow abilities contributed by a collection.
10
+ *
11
+ * Every registered collection contributes exactly six abilities, all in
12
+ * the `collections.<path>` group:
13
+ *
14
+ * - `collections.<path>.read` — enumerate / fetch documents
15
+ * - `collections.<path>.create` — create new documents
16
+ * - `collections.<path>.update` — modify existing documents
17
+ * - `collections.<path>.delete` — delete documents (soft or hard)
18
+ * - `collections.<path>.publish` — transition a document into the
19
+ * `published` status
20
+ * - `collections.<path>.changeStatus` — any other workflow transition
21
+ * (draft → custom state, etc.)
22
+ *
23
+ * Registration is unconditional: every collection in Byline has a workflow
24
+ * (the default `draft → published → archived` one when not explicitly
25
+ * configured), so `publish` and `changeStatus` always apply. Keeping the
26
+ * six-ability contract uniform makes the role editor UI predictable and
27
+ * avoids hidden conditional logic downstream.
28
+ *
29
+ * Called from `initBylineCore()` for each declared collection. See
30
+ * docs/analysis/AUTHN-AUTHZ-ANALYSIS.md §3 and Phase 1.
31
+ */
32
+ export function registerCollectionAbilities(registry, definition) {
33
+ const path = definition.path;
34
+ const group = `collections.${path}`;
35
+ const base = `collections.${path}`;
36
+ const { singular, plural } = definition.labels;
37
+ registry.register({
38
+ key: `${base}.read`,
39
+ label: `Read ${plural}`,
40
+ group,
41
+ source: 'collection',
42
+ });
43
+ registry.register({
44
+ key: `${base}.create`,
45
+ label: `Create ${singular}`,
46
+ group,
47
+ source: 'collection',
48
+ });
49
+ registry.register({
50
+ key: `${base}.update`,
51
+ label: `Update ${singular}`,
52
+ group,
53
+ source: 'collection',
54
+ });
55
+ registry.register({
56
+ key: `${base}.delete`,
57
+ label: `Delete ${singular}`,
58
+ group,
59
+ source: 'collection',
60
+ });
61
+ registry.register({
62
+ key: `${base}.publish`,
63
+ label: `Publish ${plural}`,
64
+ group,
65
+ source: 'collection',
66
+ });
67
+ registry.register({
68
+ key: `${base}.changeStatus`,
69
+ label: `Change status of ${plural}`,
70
+ group,
71
+ source: 'collection',
72
+ });
73
+ }
74
+ /** The ability suffixes that every collection contributes. Exposed for contract tests. */
75
+ export const COLLECTION_ABILITY_VERBS = [
76
+ 'read',
77
+ 'create',
78
+ 'update',
79
+ 'delete',
80
+ 'publish',
81
+ 'changeStatus',
82
+ ];
83
+ /** Compute the full ability key for a collection path and verb. */
84
+ export function collectionAbilityKey(path, verb) {
85
+ return `collections.${path}.${verb}`;
86
+ }
87
+ //# sourceMappingURL=register-collection-abilities.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register-collection-abilities.js","sourceRoot":"","sources":["../../src/auth/register-collection-abilities.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,UAAU,2BAA2B,CACzC,QAAyB,EACzB,UAAgC;IAEhC,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAA;IAC5B,MAAM,KAAK,GAAG,eAAe,IAAI,EAAE,CAAA;IACnC,MAAM,IAAI,GAAG,eAAe,IAAI,EAAE,CAAA;IAClC,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,MAAM,CAAA;IAE9C,QAAQ,CAAC,QAAQ,CAAC;QAChB,GAAG,EAAE,GAAG,IAAI,OAAO;QACnB,KAAK,EAAE,QAAQ,MAAM,EAAE;QACvB,KAAK;QACL,MAAM,EAAE,YAAY;KACrB,CAAC,CAAA;IACF,QAAQ,CAAC,QAAQ,CAAC;QAChB,GAAG,EAAE,GAAG,IAAI,SAAS;QACrB,KAAK,EAAE,UAAU,QAAQ,EAAE;QAC3B,KAAK;QACL,MAAM,EAAE,YAAY;KACrB,CAAC,CAAA;IACF,QAAQ,CAAC,QAAQ,CAAC;QAChB,GAAG,EAAE,GAAG,IAAI,SAAS;QACrB,KAAK,EAAE,UAAU,QAAQ,EAAE;QAC3B,KAAK;QACL,MAAM,EAAE,YAAY;KACrB,CAAC,CAAA;IACF,QAAQ,CAAC,QAAQ,CAAC;QAChB,GAAG,EAAE,GAAG,IAAI,SAAS;QACrB,KAAK,EAAE,UAAU,QAAQ,EAAE;QAC3B,KAAK;QACL,MAAM,EAAE,YAAY;KACrB,CAAC,CAAA;IACF,QAAQ,CAAC,QAAQ,CAAC;QAChB,GAAG,EAAE,GAAG,IAAI,UAAU;QACtB,KAAK,EAAE,WAAW,MAAM,EAAE;QAC1B,KAAK;QACL,MAAM,EAAE,YAAY;KACrB,CAAC,CAAA;IACF,QAAQ,CAAC,QAAQ,CAAC;QAChB,GAAG,EAAE,GAAG,IAAI,eAAe;QAC3B,KAAK,EAAE,oBAAoB,MAAM,EAAE;QACnC,KAAK;QACL,MAAM,EAAE,YAAY;KACrB,CAAC,CAAA;AACJ,CAAC;AAED,0FAA0F;AAC1F,MAAM,CAAC,MAAM,wBAAwB,GAAG;IACtC,MAAM;IACN,QAAQ;IACR,QAAQ;IACR,QAAQ;IACR,SAAS;IACT,cAAc;CACN,CAAA;AAIV,mEAAmE;AACnE,MAAM,UAAU,oBAAoB,CAAC,IAAY,EAAE,IAA2B;IAC5E,OAAO,eAAe,IAAI,IAAI,IAAI,EAAE,CAAA;AACtC,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * This Source Code is subject to the terms of the Mozilla Public
3
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
4
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
+ *
6
+ * Copyright (c) Infonomic Company Limited
7
+ */
8
+ export {};
9
+ //# sourceMappingURL=register-collection-abilities.test.node.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register-collection-abilities.test.node.d.ts","sourceRoot":"","sources":["../../src/auth/register-collection-abilities.test.node.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
@@ -0,0 +1,124 @@
1
+ /**
2
+ * This Source Code is subject to the terms of the Mozilla Public
3
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
4
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
+ *
6
+ * Copyright (c) Infonomic Company Limited
7
+ */
8
+ import { AbilityRegistry } from '@byline/auth';
9
+ import { describe, expect, it } from 'vitest';
10
+ import { COLLECTION_ABILITY_VERBS, collectionAbilityKey, registerCollectionAbilities, } from './register-collection-abilities.js';
11
+ function pageCollection() {
12
+ return {
13
+ path: 'pages',
14
+ labels: { singular: 'Page', plural: 'Pages' },
15
+ fields: [{ name: 'title', type: 'text' }],
16
+ };
17
+ }
18
+ function newsCollection() {
19
+ return {
20
+ path: 'news',
21
+ labels: { singular: 'News Item', plural: 'News' },
22
+ fields: [{ name: 'title', type: 'text' }],
23
+ workflow: {
24
+ statuses: [
25
+ { name: 'draft' },
26
+ { name: 'in_review' },
27
+ { name: 'published' },
28
+ { name: 'archived' },
29
+ ],
30
+ },
31
+ };
32
+ }
33
+ describe('registerCollectionAbilities', () => {
34
+ it('registers exactly the six CRUD + workflow abilities for a collection', () => {
35
+ const registry = new AbilityRegistry();
36
+ registerCollectionAbilities(registry, pageCollection());
37
+ const keys = registry.list().map((d) => d.key);
38
+ expect(keys).toEqual([
39
+ 'collections.pages.read',
40
+ 'collections.pages.create',
41
+ 'collections.pages.update',
42
+ 'collections.pages.delete',
43
+ 'collections.pages.publish',
44
+ 'collections.pages.changeStatus',
45
+ ]);
46
+ });
47
+ it('places every ability under the same `collections.<path>` group', () => {
48
+ const registry = new AbilityRegistry();
49
+ registerCollectionAbilities(registry, pageCollection());
50
+ const buckets = registry.byGroup();
51
+ expect(buckets.size).toBe(1);
52
+ expect(buckets.get('collections.pages')?.length).toBe(6);
53
+ });
54
+ it('derives labels from the collection singular/plural labels', () => {
55
+ const registry = new AbilityRegistry();
56
+ registerCollectionAbilities(registry, pageCollection());
57
+ expect(registry.get('collections.pages.read')?.label).toBe('Read Pages');
58
+ expect(registry.get('collections.pages.create')?.label).toBe('Create Page');
59
+ expect(registry.get('collections.pages.update')?.label).toBe('Update Page');
60
+ expect(registry.get('collections.pages.delete')?.label).toBe('Delete Page');
61
+ expect(registry.get('collections.pages.publish')?.label).toBe('Publish Pages');
62
+ expect(registry.get('collections.pages.changeStatus')?.label).toBe('Change status of Pages');
63
+ });
64
+ it('tags every ability with source: "collection"', () => {
65
+ const registry = new AbilityRegistry();
66
+ registerCollectionAbilities(registry, pageCollection());
67
+ for (const descriptor of registry.list()) {
68
+ expect(descriptor.source).toBe('collection');
69
+ }
70
+ });
71
+ it('registers the same six-ability shape regardless of workflow complexity', () => {
72
+ const registry = new AbilityRegistry();
73
+ registerCollectionAbilities(registry, newsCollection());
74
+ expect(registry.list().map((d) => d.key)).toEqual([
75
+ 'collections.news.read',
76
+ 'collections.news.create',
77
+ 'collections.news.update',
78
+ 'collections.news.delete',
79
+ 'collections.news.publish',
80
+ 'collections.news.changeStatus',
81
+ ]);
82
+ });
83
+ it('is idempotent — calling twice leaves the registry with the same six entries', () => {
84
+ const registry = new AbilityRegistry();
85
+ const collection = pageCollection();
86
+ registerCollectionAbilities(registry, collection);
87
+ registerCollectionAbilities(registry, collection);
88
+ expect(registry.size).toBe(6);
89
+ });
90
+ it('keeps multiple collections isolated in distinct groups', () => {
91
+ const registry = new AbilityRegistry();
92
+ registerCollectionAbilities(registry, pageCollection());
93
+ registerCollectionAbilities(registry, newsCollection());
94
+ const buckets = registry.byGroup();
95
+ expect(buckets.size).toBe(2);
96
+ expect(buckets.get('collections.pages')?.length).toBe(6);
97
+ expect(buckets.get('collections.news')?.length).toBe(6);
98
+ expect(registry.size).toBe(12);
99
+ });
100
+ });
101
+ describe('COLLECTION_ABILITY_VERBS / collectionAbilityKey', () => {
102
+ it('COLLECTION_ABILITY_VERBS exposes the canonical verb list in registration order', () => {
103
+ expect(COLLECTION_ABILITY_VERBS).toEqual([
104
+ 'read',
105
+ 'create',
106
+ 'update',
107
+ 'delete',
108
+ 'publish',
109
+ 'changeStatus',
110
+ ]);
111
+ });
112
+ it('collectionAbilityKey composes a flat dotted key', () => {
113
+ expect(collectionAbilityKey('pages', 'publish')).toBe('collections.pages.publish');
114
+ expect(collectionAbilityKey('news', 'changeStatus')).toBe('collections.news.changeStatus');
115
+ });
116
+ it('matches the keys produced by registerCollectionAbilities', () => {
117
+ const registry = new AbilityRegistry();
118
+ registerCollectionAbilities(registry, pageCollection());
119
+ for (const verb of COLLECTION_ABILITY_VERBS) {
120
+ expect(registry.has(collectionAbilityKey('pages', verb))).toBe(true);
121
+ }
122
+ });
123
+ });
124
+ //# sourceMappingURL=register-collection-abilities.test.node.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register-collection-abilities.test.node.js","sourceRoot":"","sources":["../../src/auth/register-collection-abilities.test.node.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { ClientConfig, CollectionAdminConfig, CollectionDefinition, ServerConfig } from '../@types/index.js';
2
+ export declare const getCollectionDefinition: (path: string) => CollectionDefinition | null;
3
+ export declare const getCollectionAdminConfig: (slug: string) => CollectionAdminConfig | null;
4
+ export declare function defineClientConfig(config: ClientConfig): void;
5
+ export declare function defineServerConfig(config: ServerConfig): void;
6
+ export declare function getClientConfig(): ClientConfig;
7
+ export declare function getServerConfig(): ServerConfig;
8
+ export declare function defineBylineCore(core: unknown): void;
9
+ export declare function getBylineCoreUnsafe(): unknown;
10
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/config/config.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,YAAY,EACZ,qBAAqB,EACrB,oBAAoB,EACpB,YAAY,EACb,MAAM,mBAAmB,CAAA;AAmC1B,eAAO,MAAM,uBAAuB,GAAI,MAAM,MAAM,KAAG,oBAAoB,GAAG,IAS7E,CAAA;AAED,eAAO,MAAM,wBAAwB,GAAI,MAAM,MAAM,KAAG,qBAAqB,GAAG,IAI/E,CAAA;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,YAAY,QAItD;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,YAAY,QAGtD;AAED,wBAAgB,eAAe,IAAI,YAAY,CAqB9C;AAED,wBAAgB,eAAe,IAAI,YAAY,CAW9C;AAYD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAEpD;AAED,wBAAgB,mBAAmB,IAAI,OAAO,CAW7C"}
@@ -0,0 +1,108 @@
1
+ import { validateAdminConfigs } from './validate-admin-configs.js';
2
+ import { validateCollections } from './validate-collections.js';
3
+ // ---------------------------------------------------------------------------
4
+ // Global config storage
5
+ // ---------------------------------------------------------------------------
6
+ // Store config instances on `globalThis` so that every copy of this module
7
+ // (which can happen in Vite SSR when workspace-linked packages are resolved
8
+ // through different module graphs) shares the same state.
9
+ // ---------------------------------------------------------------------------
10
+ const BYLINE_SERVER_CONFIG = Symbol.for('__byline_server_config__');
11
+ const BYLINE_CLIENT_CONFIG = Symbol.for('__byline_client_config__');
12
+ const BYLINE_CORE = Symbol.for('__byline_core__');
13
+ function getServerConfigInstance() {
14
+ return globalThis[BYLINE_SERVER_CONFIG] ?? null;
15
+ }
16
+ function setServerConfigInstance(config) {
17
+ ;
18
+ globalThis[BYLINE_SERVER_CONFIG] = config;
19
+ }
20
+ function getClientConfigInstance() {
21
+ return globalThis[BYLINE_CLIENT_CONFIG] ?? null;
22
+ }
23
+ function setClientConfigInstance(config) {
24
+ ;
25
+ globalThis[BYLINE_CLIENT_CONFIG] = config;
26
+ }
27
+ function getBylineCoreInstance() {
28
+ return globalThis[BYLINE_CORE] ?? null;
29
+ }
30
+ function setBylineCoreInstance(core) {
31
+ ;
32
+ globalThis[BYLINE_CORE] = core;
33
+ }
34
+ export const getCollectionDefinition = (path) => {
35
+ const config = getClientConfigInstance() ?? getServerConfigInstance();
36
+ if (config == null) {
37
+ throw new Error('Byline has not been configured yet. Please call defineClientConfig or defineServerConfig in your admin/server config first.');
38
+ }
39
+ return config.collections.find((collection) => collection.path === path) ?? null;
40
+ };
41
+ export const getCollectionAdminConfig = (slug) => {
42
+ const clientConfig = getClientConfigInstance();
43
+ if (clientConfig == null)
44
+ return null;
45
+ return clientConfig.admin?.find((admin) => admin.slug === slug) ?? null;
46
+ };
47
+ export function defineClientConfig(config) {
48
+ validateCollections(config.collections);
49
+ validateAdminConfigs(config.admin, config.collections);
50
+ setClientConfigInstance(config);
51
+ }
52
+ export function defineServerConfig(config) {
53
+ validateCollections(config.collections);
54
+ setServerConfigInstance(config);
55
+ }
56
+ export function getClientConfig() {
57
+ const clientConfig = getClientConfigInstance();
58
+ if (clientConfig != null) {
59
+ return clientConfig;
60
+ }
61
+ // During SSR the client entry has not run yet, but the server config
62
+ // carries the same collection definitions. Return a compatible object
63
+ // so route loaders and components work in both contexts.
64
+ const serverConfig = getServerConfigInstance();
65
+ if (serverConfig != null) {
66
+ return {
67
+ serverURL: serverConfig.serverURL,
68
+ i18n: serverConfig.i18n,
69
+ routes: serverConfig.routes,
70
+ collections: serverConfig.collections,
71
+ admin: [],
72
+ };
73
+ }
74
+ throw new Error('Byline has not been configured yet. Please call defineClientConfig in byline.config.ts first.');
75
+ }
76
+ export function getServerConfig() {
77
+ if (typeof globalThis !== 'undefined' && 'window' in globalThis) {
78
+ throw new Error('getServerConfig cannot be called on the client.');
79
+ }
80
+ const serverConfig = getServerConfigInstance();
81
+ if (serverConfig == null) {
82
+ throw new Error('Byline has not been configured yet. Please call defineServerConfig in byline.config.ts first.');
83
+ }
84
+ return serverConfig;
85
+ }
86
+ // ---------------------------------------------------------------------------
87
+ // BylineCore singleton — the composed runtime returned by `initBylineCore`.
88
+ // Server-side packages that need post-init state (the abilities registry,
89
+ // the resolved admin store) read it here rather than importing the host's
90
+ // host server config module directly. Stored as `unknown` to avoid a
91
+ // circular type dependency between `config.ts` and `core.ts`; consumers
92
+ // import the typed `getBylineCore<TAdminStore>()` re-export from
93
+ // `core.ts`.
94
+ // ---------------------------------------------------------------------------
95
+ export function defineBylineCore(core) {
96
+ setBylineCoreInstance(core);
97
+ }
98
+ export function getBylineCoreUnsafe() {
99
+ if (typeof globalThis !== 'undefined' && 'window' in globalThis) {
100
+ throw new Error('getBylineCore cannot be called on the client.');
101
+ }
102
+ const core = getBylineCoreInstance();
103
+ if (core == null) {
104
+ throw new Error('BylineCore has not been initialised yet. Please call initBylineCore() in your server config first.');
105
+ }
106
+ return core;
107
+ }
108
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * This Source Code is subject to the terms of the Mozilla Public
3
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
4
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
+ *
6
+ * Copyright (c) Infonomic Company Limited
7
+ */
8
+ import type { RoutesConfig } from '../@types/site-config.js';
9
+ /**
10
+ * Merge a user-supplied (potentially partial) routes config with the
11
+ * built-in defaults. Empty / unset keys fall back to `'/admin'` and
12
+ * `'/api'`. Returns a fully-populated `RoutesConfig` so consumers don't
13
+ * need null checks at every call site.
14
+ */
15
+ export declare function resolveRoutes(routes?: Partial<RoutesConfig>): RoutesConfig;
16
+ //# sourceMappingURL=routes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/config/routes.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAA;AAS3D;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,YAAY,CAK1E"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * This Source Code is subject to the terms of the Mozilla Public
3
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
4
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
+ *
6
+ * Copyright (c) Infonomic Company Limited
7
+ */
8
+ /** Default route segments. Installations override either key on the
9
+ * config object; callers read the merged shape via `resolveRoutes()`. */
10
+ const DEFAULT_ROUTES = {
11
+ admin: '/admin',
12
+ api: '/api',
13
+ };
14
+ /**
15
+ * Merge a user-supplied (potentially partial) routes config with the
16
+ * built-in defaults. Empty / unset keys fall back to `'/admin'` and
17
+ * `'/api'`. Returns a fully-populated `RoutesConfig` so consumers don't
18
+ * need null checks at every call site.
19
+ */
20
+ export function resolveRoutes(routes) {
21
+ return {
22
+ admin: routes?.admin ?? DEFAULT_ROUTES.admin,
23
+ api: routes?.api ?? DEFAULT_ROUTES.api,
24
+ };
25
+ }
26
+ //# sourceMappingURL=routes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routes.js","sourceRoot":"","sources":["../../src/config/routes.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH;yEACyE;AACzE,MAAM,cAAc,GAAiB;IACnC,KAAK,EAAE,QAAQ;IACf,GAAG,EAAE,MAAM;CACZ,CAAA;AAED;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,MAA8B;IAC1D,OAAO;QACL,KAAK,EAAE,MAAM,EAAE,KAAK,IAAI,cAAc,CAAC,KAAK;QAC5C,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,cAAc,CAAC,GAAG;KACvC,CAAA;AACH,CAAC"}