@haverstack/core 0.40.0 → 0.42.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 (287) hide show
  1. package/README.md +121 -59
  2. package/dist/access.d.ts +34 -36
  3. package/dist/access.d.ts.map +1 -1
  4. package/dist/access.js +65 -42
  5. package/dist/access.js.map +1 -1
  6. package/dist/{combine.d.ts → adapter/combine.d.ts} +8 -1
  7. package/dist/adapter/combine.d.ts.map +1 -0
  8. package/dist/{combine.js → adapter/combine.js} +7 -0
  9. package/dist/adapter/combine.js.map +1 -0
  10. package/dist/{adapter-entry.d.ts → adapter/index.d.ts} +6 -5
  11. package/dist/adapter/index.d.ts.map +1 -0
  12. package/dist/{adapter-entry.js → adapter/index.js} +5 -4
  13. package/dist/adapter/index.js.map +1 -0
  14. package/dist/{sort.d.ts → adapter/sort.d.ts} +20 -20
  15. package/dist/adapter/sort.d.ts.map +1 -0
  16. package/dist/{sort.js → adapter/sort.js} +37 -27
  17. package/dist/adapter/sort.js.map +1 -0
  18. package/dist/associations/identity.d.ts +93 -0
  19. package/dist/associations/identity.d.ts.map +1 -0
  20. package/dist/associations/identity.js +198 -0
  21. package/dist/associations/identity.js.map +1 -0
  22. package/dist/associations/validation.d.ts +90 -0
  23. package/dist/associations/validation.d.ts.map +1 -0
  24. package/dist/associations/validation.js +339 -0
  25. package/dist/associations/validation.js.map +1 -0
  26. package/dist/attachment-records.d.ts +48 -0
  27. package/dist/attachment-records.d.ts.map +1 -0
  28. package/dist/attachment-records.js +52 -0
  29. package/dist/attachment-records.js.map +1 -0
  30. package/dist/collection.d.ts +182 -0
  31. package/dist/collection.d.ts.map +1 -0
  32. package/dist/collection.js +407 -0
  33. package/dist/collection.js.map +1 -0
  34. package/dist/content-match.d.ts +25 -0
  35. package/dist/content-match.d.ts.map +1 -0
  36. package/dist/content-match.js +51 -0
  37. package/dist/content-match.js.map +1 -0
  38. package/dist/content-translation.d.ts +42 -0
  39. package/dist/content-translation.d.ts.map +1 -0
  40. package/dist/content-translation.js +108 -0
  41. package/dist/content-translation.js.map +1 -0
  42. package/dist/did/did.d.ts.map +1 -0
  43. package/dist/{did.js → did/did.js} +3 -4
  44. package/dist/did/did.js.map +1 -0
  45. package/dist/{did-entry.d.ts → did/index.d.ts} +1 -1
  46. package/dist/did/index.d.ts.map +1 -0
  47. package/dist/{did-entry.js → did/index.js} +3 -3
  48. package/dist/did/index.js.map +1 -0
  49. package/dist/errors.d.ts +36 -63
  50. package/dist/errors.d.ts.map +1 -1
  51. package/dist/errors.js +35 -58
  52. package/dist/errors.js.map +1 -1
  53. package/dist/grants.d.ts +20 -43
  54. package/dist/grants.d.ts.map +1 -1
  55. package/dist/grants.js +71 -134
  56. package/dist/grants.js.map +1 -1
  57. package/dist/id.d.ts +13 -31
  58. package/dist/id.d.ts.map +1 -1
  59. package/dist/id.js +13 -31
  60. package/dist/id.js.map +1 -1
  61. package/dist/index.d.ts +14 -8
  62. package/dist/index.d.ts.map +1 -1
  63. package/dist/index.js +9 -5
  64. package/dist/index.js.map +1 -1
  65. package/dist/install.d.ts +141 -0
  66. package/dist/install.d.ts.map +1 -0
  67. package/dist/install.js +219 -0
  68. package/dist/install.js.map +1 -0
  69. package/dist/merge.d.ts.map +1 -1
  70. package/dist/merge.js +5 -11
  71. package/dist/merge.js.map +1 -1
  72. package/dist/migration-steps.d.ts +102 -0
  73. package/dist/migration-steps.d.ts.map +1 -0
  74. package/dist/migration-steps.js +293 -0
  75. package/dist/migration-steps.js.map +1 -0
  76. package/dist/query-validation.d.ts +28 -94
  77. package/dist/query-validation.d.ts.map +1 -1
  78. package/dist/query-validation.js +156 -336
  79. package/dist/query-validation.js.map +1 -1
  80. package/dist/record-changes.d.ts +2 -117
  81. package/dist/record-changes.d.ts.map +1 -1
  82. package/dist/record-changes.js +10 -212
  83. package/dist/record-changes.js.map +1 -1
  84. package/dist/schema.d.ts +18 -7
  85. package/dist/schema.d.ts.map +1 -1
  86. package/dist/schema.js +59 -30
  87. package/dist/schema.js.map +1 -1
  88. package/dist/scoped-stack/authority.d.ts +156 -0
  89. package/dist/scoped-stack/authority.d.ts.map +1 -0
  90. package/dist/scoped-stack/authority.js +384 -0
  91. package/dist/scoped-stack/authority.js.map +1 -0
  92. package/dist/scoped-stack/scoped-stack.d.ts +338 -0
  93. package/dist/scoped-stack/scoped-stack.d.ts.map +1 -0
  94. package/dist/scoped-stack/scoped-stack.js +776 -0
  95. package/dist/scoped-stack/scoped-stack.js.map +1 -0
  96. package/dist/scoped-stack/subscription.d.ts +55 -0
  97. package/dist/scoped-stack/subscription.d.ts.map +1 -0
  98. package/dist/scoped-stack/subscription.js +110 -0
  99. package/dist/scoped-stack/subscription.js.map +1 -0
  100. package/dist/stack/attachments.d.ts +24 -0
  101. package/dist/stack/attachments.d.ts.map +1 -0
  102. package/dist/stack/attachments.js +113 -0
  103. package/dist/stack/attachments.js.map +1 -0
  104. package/dist/{changes.d.ts → stack/changes.d.ts} +29 -65
  105. package/dist/stack/changes.d.ts.map +1 -0
  106. package/dist/{changes.js → stack/changes.js} +32 -66
  107. package/dist/stack/changes.js.map +1 -0
  108. package/dist/stack/client.d.ts +271 -0
  109. package/dist/stack/client.d.ts.map +1 -0
  110. package/dist/stack/client.js +9 -0
  111. package/dist/stack/client.js.map +1 -0
  112. package/dist/stack/identity-bindings.d.ts.map +1 -0
  113. package/dist/{identity-bindings.js → stack/identity-bindings.js} +8 -14
  114. package/dist/stack/identity-bindings.js.map +1 -0
  115. package/dist/stack/install-app.d.ts +22 -0
  116. package/dist/stack/install-app.d.ts.map +1 -0
  117. package/dist/stack/install-app.js +260 -0
  118. package/dist/stack/install-app.js.map +1 -0
  119. package/dist/stack/integrity.d.ts +94 -0
  120. package/dist/stack/integrity.d.ts.map +1 -0
  121. package/dist/stack/integrity.js +268 -0
  122. package/dist/stack/integrity.js.map +1 -0
  123. package/dist/{limits.d.ts → stack/limits.d.ts} +2 -5
  124. package/dist/stack/limits.d.ts.map +1 -0
  125. package/dist/{limits.js → stack/limits.js} +3 -6
  126. package/dist/stack/limits.js.map +1 -0
  127. package/dist/stack/migrations.d.ts +59 -0
  128. package/dist/stack/migrations.d.ts.map +1 -0
  129. package/dist/stack/migrations.js +141 -0
  130. package/dist/stack/migrations.js.map +1 -0
  131. package/dist/{stack-reads.d.ts → stack/reads.d.ts} +33 -6
  132. package/dist/stack/reads.d.ts.map +1 -0
  133. package/dist/{stack-reads.js → stack/reads.js} +49 -7
  134. package/dist/stack/reads.js.map +1 -0
  135. package/dist/stack/record-id.d.ts +35 -0
  136. package/dist/stack/record-id.d.ts.map +1 -0
  137. package/dist/stack/record-id.js +82 -0
  138. package/dist/stack/record-id.js.map +1 -0
  139. package/dist/stack/stack.d.ts +438 -0
  140. package/dist/stack/stack.d.ts.map +1 -0
  141. package/dist/stack/stack.js +1366 -0
  142. package/dist/stack/stack.js.map +1 -0
  143. package/dist/stack/system-types.d.ts +16 -0
  144. package/dist/stack/system-types.d.ts.map +1 -0
  145. package/dist/stack/system-types.js +111 -0
  146. package/dist/stack/system-types.js.map +1 -0
  147. package/dist/stack/type-grants.d.ts +20 -0
  148. package/dist/stack/type-grants.d.ts.map +1 -0
  149. package/dist/stack/type-grants.js +69 -0
  150. package/dist/stack/type-grants.js.map +1 -0
  151. package/dist/stack/write-expectation.d.ts +78 -0
  152. package/dist/stack/write-expectation.d.ts.map +1 -0
  153. package/dist/stack/write-expectation.js +71 -0
  154. package/dist/stack/write-expectation.js.map +1 -0
  155. package/dist/testing.d.ts +21 -26
  156. package/dist/testing.d.ts.map +1 -1
  157. package/dist/testing.js +50 -70
  158. package/dist/testing.js.map +1 -1
  159. package/dist/type-handle.d.ts +67 -78
  160. package/dist/type-handle.d.ts.map +1 -1
  161. package/dist/type-handle.js +44 -111
  162. package/dist/type-handle.js.map +1 -1
  163. package/dist/types/adapter.d.ts +223 -0
  164. package/dist/types/adapter.d.ts.map +1 -0
  165. package/dist/types/adapter.js +5 -0
  166. package/dist/types/adapter.js.map +1 -0
  167. package/dist/types/associations.d.ts +156 -0
  168. package/dist/types/associations.d.ts.map +1 -0
  169. package/dist/types/associations.js +13 -0
  170. package/dist/types/associations.js.map +1 -0
  171. package/dist/types/capabilities.d.ts +89 -0
  172. package/dist/types/capabilities.d.ts.map +1 -0
  173. package/dist/types/capabilities.js +5 -0
  174. package/dist/types/capabilities.js.map +1 -0
  175. package/dist/types/events.d.ts +155 -0
  176. package/dist/types/events.d.ts.map +1 -0
  177. package/dist/types/events.js +5 -0
  178. package/dist/types/events.js.map +1 -0
  179. package/dist/types/ids.d.ts +43 -0
  180. package/dist/types/ids.d.ts.map +1 -0
  181. package/dist/types/ids.js +5 -0
  182. package/dist/types/ids.js.map +1 -0
  183. package/dist/types/index.d.ts +19 -0
  184. package/dist/types/index.d.ts.map +1 -0
  185. package/dist/types/index.js +19 -0
  186. package/dist/types/index.js.map +1 -0
  187. package/dist/types/journal.d.ts +47 -0
  188. package/dist/types/journal.d.ts.map +1 -0
  189. package/dist/types/journal.js +5 -0
  190. package/dist/types/journal.js.map +1 -0
  191. package/dist/types/query.d.ts +185 -0
  192. package/dist/types/query.d.ts.map +1 -0
  193. package/dist/types/query.js +10 -0
  194. package/dist/types/query.js.map +1 -0
  195. package/dist/types/records.d.ts +76 -0
  196. package/dist/types/records.d.ts.map +1 -0
  197. package/dist/types/records.js +5 -0
  198. package/dist/types/records.js.map +1 -0
  199. package/dist/types/schema.d.ts +74 -0
  200. package/dist/types/schema.d.ts.map +1 -0
  201. package/dist/types/schema.js +5 -0
  202. package/dist/types/schema.js.map +1 -0
  203. package/dist/types/system.d.ts +161 -0
  204. package/dist/types/system.d.ts.map +1 -0
  205. package/dist/types/system.js +32 -0
  206. package/dist/types/system.js.map +1 -0
  207. package/dist/types/tokens.d.ts +39 -0
  208. package/dist/types/tokens.d.ts.map +1 -0
  209. package/dist/types/tokens.js +5 -0
  210. package/dist/types/tokens.js.map +1 -0
  211. package/dist/validate.d.ts +29 -70
  212. package/dist/validate.d.ts.map +1 -1
  213. package/dist/validate.js +65 -97
  214. package/dist/validate.js.map +1 -1
  215. package/dist/{attachment-download.d.ts → wire/attachment-download.d.ts} +0 -57
  216. package/dist/wire/attachment-download.d.ts.map +1 -0
  217. package/dist/{attachment-download.js → wire/attachment-download.js} +0 -61
  218. package/dist/wire/attachment-download.js.map +1 -0
  219. package/dist/{auth.d.ts → wire/auth.d.ts} +5 -8
  220. package/dist/wire/auth.d.ts.map +1 -0
  221. package/dist/{auth.js → wire/auth.js} +5 -8
  222. package/dist/wire/auth.js.map +1 -0
  223. package/dist/{wire-body.d.ts → wire/body.d.ts} +13 -5
  224. package/dist/wire/body.d.ts.map +1 -0
  225. package/dist/{wire-body.js → wire/body.js} +65 -7
  226. package/dist/wire/body.js.map +1 -0
  227. package/dist/{wire-entry.d.ts → wire/index.d.ts} +12 -12
  228. package/dist/wire/index.d.ts.map +1 -0
  229. package/dist/{wire-entry.js → wire/index.js} +13 -17
  230. package/dist/wire/index.js.map +1 -0
  231. package/dist/{wire-record.d.ts → wire/record.d.ts} +10 -22
  232. package/dist/wire/record.d.ts.map +1 -0
  233. package/dist/{wire-record.js → wire/record.js} +12 -24
  234. package/dist/wire/record.js.map +1 -0
  235. package/dist/{wire-request.d.ts → wire/request.d.ts} +20 -37
  236. package/dist/wire/request.d.ts.map +1 -0
  237. package/dist/{wire-request.js → wire/request.js} +79 -54
  238. package/dist/wire/request.js.map +1 -0
  239. package/package.json +7 -7
  240. package/dist/adapter-entry.d.ts.map +0 -1
  241. package/dist/adapter-entry.js.map +0 -1
  242. package/dist/attachment-download.d.ts.map +0 -1
  243. package/dist/attachment-download.js.map +0 -1
  244. package/dist/auth.d.ts.map +0 -1
  245. package/dist/auth.js.map +0 -1
  246. package/dist/changes.d.ts.map +0 -1
  247. package/dist/changes.js.map +0 -1
  248. package/dist/combine.d.ts.map +0 -1
  249. package/dist/combine.js.map +0 -1
  250. package/dist/did-entry.d.ts.map +0 -1
  251. package/dist/did-entry.js.map +0 -1
  252. package/dist/did.d.ts.map +0 -1
  253. package/dist/did.js.map +0 -1
  254. package/dist/identity-bindings.d.ts.map +0 -1
  255. package/dist/identity-bindings.js.map +0 -1
  256. package/dist/limits.d.ts.map +0 -1
  257. package/dist/limits.js.map +0 -1
  258. package/dist/record-id.d.ts +0 -70
  259. package/dist/record-id.d.ts.map +0 -1
  260. package/dist/record-id.js +0 -127
  261. package/dist/record-id.js.map +0 -1
  262. package/dist/scoped-stack.d.ts +0 -532
  263. package/dist/scoped-stack.d.ts.map +0 -1
  264. package/dist/scoped-stack.js +0 -1219
  265. package/dist/scoped-stack.js.map +0 -1
  266. package/dist/sort.d.ts.map +0 -1
  267. package/dist/sort.js.map +0 -1
  268. package/dist/stack-reads.d.ts.map +0 -1
  269. package/dist/stack-reads.js.map +0 -1
  270. package/dist/stack.d.ts +0 -971
  271. package/dist/stack.d.ts.map +0 -1
  272. package/dist/stack.js +0 -2012
  273. package/dist/stack.js.map +0 -1
  274. package/dist/types.d.ts +0 -1250
  275. package/dist/types.d.ts.map +0 -1
  276. package/dist/types.js +0 -49
  277. package/dist/types.js.map +0 -1
  278. package/dist/wire-body.d.ts.map +0 -1
  279. package/dist/wire-body.js.map +0 -1
  280. package/dist/wire-entry.d.ts.map +0 -1
  281. package/dist/wire-entry.js.map +0 -1
  282. package/dist/wire-record.d.ts.map +0 -1
  283. package/dist/wire-record.js.map +0 -1
  284. package/dist/wire-request.d.ts.map +0 -1
  285. package/dist/wire-request.js.map +0 -1
  286. /package/dist/{did.d.ts → did/did.d.ts} +0 -0
  287. /package/dist/{identity-bindings.d.ts → stack/identity-bindings.d.ts} +0 -0
package/dist/index.d.ts CHANGED
@@ -17,21 +17,27 @@
17
17
  * adapter-api, record-adapter-sqlite, record-adapter-do-sqlite,
18
18
  * blob-adapter-disk and blob-adapter-s3, all under @haverstack/.
19
19
  */
20
- export { Stack } from './stack.js';
21
- export { ScopedStack } from './scoped-stack.js';
22
- export type { StackClient, CreateRecordOptions, BackdatableCreateRecordOptions, StackOptions, DefineTypeOptions, GetRecordOptions, DeleteRecordOptions, DeleteResult, DeleteAndReturnResult, CollectAttachmentGarbageOptions, CollectAttachmentGarbageResult, } from './stack.js';
23
- export { typeHandle } from './type-handle.js';
24
- export type { TypeHandle, ContentOf, PatchOf, TypedRecord, TypedQuery, TypedChange, TypedChangeSet, TypedSubscribeOptions, ReadonlyFieldDef, ReadonlyTypeSchema, } from './type-handle.js';
20
+ export { Stack } from './stack/stack.js';
21
+ export { ScopedStack } from './scoped-stack/scoped-stack.js';
22
+ export type { StackClient, CreateRecordOptions, BackdatableCreateRecordOptions, StackOptions, DefineTypeOptions, GetRecordOptions, DeleteRecordOptions, DeleteResult, DeleteAndReturnResult, CollectAttachmentGarbageOptions, CollectAttachmentGarbageResult, MigrateAllOptions, } from './stack/client.js';
23
+ export type { AppManifest, InstallPlan, ForeignRequest, TypeChange } from './install.js';
24
+ export { isPlanEmpty } from './install.js';
25
+ export { typeHandle, migration } from './type-handle.js';
26
+ export { rename, map, add, drop, derive } from './migration-steps.js';
27
+ export type { MigrationStep, RenameStep, MapStep, AddStep, DropStep, DeriveStep, } from './migration-steps.js';
28
+ export type { TypeHandle, Migration, ContentOf, StoredContentOf, UnlistedValue, ReadonlyFieldDef, ReadonlyTypeSchema, } from './type-handle.js';
29
+ export { MisfitError } from './collection.js';
30
+ export type { Collection, CollectionRecord, CollectionPage, CollectionQuery, CollectionChange, CollectionChangeSet, CollectionSubscribeOptions, ContentPatch, ContentPathOf, Misfit, SortableFieldOf, StoredContent, } from './collection.js';
25
31
  export { StackError, StackValidationError, StackMigrationError, StackPermissionError, StackNotFoundError, StackConflictError, StackVersionConflictError, StackBadRequestError, StackSchemaDriftError, StackPayloadTooLargeError, StackTimeoutError, } from './errors.js';
26
32
  export { UseAfterCloseError, InvalidAdapterError, RelayScopeError } from './errors.js';
27
33
  export type { StackErrorCode } from './errors.js';
28
- export type { RecordId, TypeId, BaseId, FileId, EntityId, AppId, AttachmentContent, StackRecord, RecordChangeSet, RecordVersion, RecordJournalEntry, JournalQuery, VersionsQuery, Actor, ActorOptions, ChangeKind, ChangeOp, ChangeActor, RecordChange, ChangeFilter, SubscribeOptions, Unsubscribe, StackType, TypeSchema, FieldDef, ScalarFieldDef, ArrayFieldDef, ObjectFieldDef, ScalarFieldKind, Association, TagAssociation, AttachmentAssociation, RelationshipAssociation, PermissionAssociation, Grantee, GroupRole, AnyoneAssociation, AuthorityAssociation, DataAssociation, AssociationChange, AssociationEdit, RelationshipTarget, RecordTarget, EntityTarget, ExternalTarget, StackQuery, RecordFilter, RelatedToFilter, AttachmentFilter, RelationshipTargetPattern, QuerySort, NativeSortField, QueryResult, DateRange, Migration, MigrationFn, StackCapabilities, ContentFilterReach, MissingCapability, IfVersionOptions, EntityContent, AppContent, GroupContent, GrantAction, GrantContent, GrantGrantee, TypeGrant, PutAttachmentOptions, ConfigContent, } from './types.js';
34
+ export type { RecordId, TypeId, BaseId, FileId, EntityId, AppId, AttachmentContent, StackRecord, RecordChangeSet, RecordVersion, RecordJournalEntry, JournalQuery, VersionsQuery, Actor, ActorOptions, ChangeKind, ChangeOp, ChangeActor, RecordChange, ChangeFilter, SubscribeOptions, Unsubscribe, StackType, TypeSchema, FieldDef, ScalarFieldDef, EnumFieldDef, ArrayFieldDef, ObjectFieldDef, ScalarFieldKind, Association, TagAssociation, AttachmentAssociation, RelationshipAssociation, PermissionAssociation, Grantee, GroupRole, AnyoneAssociation, AuthorityAssociation, DataAssociation, AssociationChange, AssociationEdit, RelationshipTarget, RecordTarget, EntityTarget, ExternalTarget, StackQuery, RecordFilter, RelatedToFilter, AttachmentFilter, RelationshipTargetPattern, QuerySort, ContentArm, ContentSortKey, NativeSortField, QueryResult, DateRange, StackCapabilities, ContentFilterReach, MissingCapability, IfVersionOptions, EntityContent, AppContent, GroupContent, GrantAction, GrantContent, GrantGrantee, InstallContent, InstallRequest, TypeGrant, PutAttachmentOptions, ConfigContent, } from './types/index.js';
29
35
  export type { GrantQuery } from './grants.js';
30
- export { SYSTEM_TYPES, NATIVE_SORT_FIELDS } from './types.js';
36
+ export { SYSTEM_TYPES, NATIVE_SORT_FIELDS } from './types/index.js';
31
37
  export { generateId } from './id.js';
32
38
  export { hashSchema, isCompatible } from './schema.js';
33
39
  export type { SchemaDriftViolation } from './schema.js';
34
40
  export type { ValidationError } from './validate.js';
35
41
  export { applyMergePatch } from './merge.js';
36
- export { assertOneSurface } from './record-changes.js';
42
+ export { assertOneSurface, isAuthorityAssociation } from './associations/identity.js';
37
43
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,YAAY,EACV,WAAW,EACX,mBAAmB,EACnB,8BAA8B,EAC9B,YAAY,EACZ,iBAAiB,EACjB,gBAAgB,EAChB,mBAAmB,EACnB,YAAY,EACZ,qBAAqB,EACrB,+BAA+B,EAC/B,8BAA8B,GAC/B,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,YAAY,EACV,UAAU,EACV,SAAS,EACT,OAAO,EACP,WAAW,EACX,UAAU,EACV,WAAW,EACX,cAAc,EACd,qBAAqB,EACrB,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EACL,UAAU,EACV,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,EACpB,kBAAkB,EAClB,kBAAkB,EAClB,yBAAyB,EACzB,oBAAoB,EACpB,qBAAqB,EACrB,yBAAyB,EACzB,iBAAiB,GAClB,MAAM,aAAa,CAAC;AAGrB,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACvF,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAGlD,YAAY,EACV,QAAQ,EACR,MAAM,EACN,MAAM,EACN,MAAM,EACN,QAAQ,EACR,KAAK,EACL,iBAAiB,EACjB,WAAW,EACX,eAAe,EACf,aAAa,EACb,kBAAkB,EAClB,YAAY,EACZ,aAAa,EACb,KAAK,EACL,YAAY,EACZ,UAAU,EACV,QAAQ,EACR,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,gBAAgB,EAChB,WAAW,EACX,SAAS,EACT,UAAU,EACV,QAAQ,EACR,cAAc,EACd,aAAa,EACb,cAAc,EACd,eAAe,EACf,WAAW,EACX,cAAc,EACd,qBAAqB,EACrB,uBAAuB,EACvB,qBAAqB,EACrB,OAAO,EACP,SAAS,EACT,iBAAiB,EACjB,oBAAoB,EACpB,eAAe,EACf,iBAAiB,EACjB,eAAe,EACf,kBAAkB,EAClB,YAAY,EACZ,YAAY,EACZ,cAAc,EACd,UAAU,EACV,YAAY,EACZ,eAAe,EACf,gBAAgB,EAChB,yBAAyB,EACzB,SAAS,EACT,eAAe,EACf,WAAW,EACX,SAAS,EACT,SAAS,EACT,WAAW,EACX,iBAAiB,EACjB,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,aAAa,EACb,UAAU,EACV,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,SAAS,EACT,oBAAoB,EACpB,aAAa,GACd,MAAM,YAAY,CAAC;AAEpB,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAM9D,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACvD,YAAY,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACxD,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAC7D,YAAY,EACV,WAAW,EACX,mBAAmB,EACnB,8BAA8B,EAC9B,YAAY,EACZ,iBAAiB,EACjB,gBAAgB,EAChB,mBAAmB,EACnB,YAAY,EACZ,qBAAqB,EACrB,+BAA+B,EAC/B,8BAA8B,EAC9B,iBAAiB,GAClB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AACzF,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAG3C,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AACtE,YAAY,EACV,aAAa,EACb,UAAU,EACV,OAAO,EACP,OAAO,EACP,QAAQ,EACR,UAAU,GACX,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EACV,UAAU,EACV,SAAS,EACT,SAAS,EACT,eAAe,EACf,aAAa,EACb,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,YAAY,EACV,UAAU,EACV,gBAAgB,EAChB,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,mBAAmB,EACnB,0BAA0B,EAC1B,YAAY,EACZ,aAAa,EACb,MAAM,EACN,eAAe,EACf,aAAa,GACd,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EACL,UAAU,EACV,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,EACpB,kBAAkB,EAClB,kBAAkB,EAClB,yBAAyB,EACzB,oBAAoB,EACpB,qBAAqB,EACrB,yBAAyB,EACzB,iBAAiB,GAClB,MAAM,aAAa,CAAC;AAGrB,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACvF,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAGlD,YAAY,EACV,QAAQ,EACR,MAAM,EACN,MAAM,EACN,MAAM,EACN,QAAQ,EACR,KAAK,EACL,iBAAiB,EACjB,WAAW,EACX,eAAe,EACf,aAAa,EACb,kBAAkB,EAClB,YAAY,EACZ,aAAa,EACb,KAAK,EACL,YAAY,EACZ,UAAU,EACV,QAAQ,EACR,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,gBAAgB,EAChB,WAAW,EACX,SAAS,EACT,UAAU,EACV,QAAQ,EACR,cAAc,EACd,YAAY,EACZ,aAAa,EACb,cAAc,EACd,eAAe,EACf,WAAW,EACX,cAAc,EACd,qBAAqB,EACrB,uBAAuB,EACvB,qBAAqB,EACrB,OAAO,EACP,SAAS,EACT,iBAAiB,EACjB,oBAAoB,EACpB,eAAe,EACf,iBAAiB,EACjB,eAAe,EACf,kBAAkB,EAClB,YAAY,EACZ,YAAY,EACZ,cAAc,EACd,UAAU,EACV,YAAY,EACZ,eAAe,EACf,gBAAgB,EAChB,yBAAyB,EACzB,SAAS,EACT,UAAU,EACV,cAAc,EACd,eAAe,EACf,WAAW,EACX,SAAS,EACT,iBAAiB,EACjB,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,aAAa,EACb,UAAU,EACV,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,cAAc,EACd,cAAc,EACd,SAAS,EACT,oBAAoB,EACpB,aAAa,GACd,MAAM,kBAAkB,CAAC;AAE1B,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAMpE,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACvD,YAAY,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACxD,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC"}
package/dist/index.js CHANGED
@@ -18,21 +18,25 @@
18
18
  * blob-adapter-disk and blob-adapter-s3, all under @haverstack/.
19
19
  */
20
20
  // Core class and client interface
21
- export { Stack } from './stack.js';
22
- export { ScopedStack } from './scoped-stack.js';
21
+ export { Stack } from './stack/stack.js';
22
+ export { ScopedStack } from './scoped-stack/scoped-stack.js';
23
+ export { isPlanEmpty } from './install.js';
23
24
  // Type handles
24
- export { typeHandle } from './type-handle.js';
25
+ export { typeHandle, migration } from './type-handle.js';
26
+ export { rename, map, add, drop, derive } from './migration-steps.js';
27
+ // Collections
28
+ export { MisfitError } from './collection.js';
25
29
  // The error taxonomy
26
30
  export { StackError, StackValidationError, StackMigrationError, StackPermissionError, StackNotFoundError, StackConflictError, StackVersionConflictError, StackBadRequestError, StackSchemaDriftError, StackPayloadTooLargeError, StackTimeoutError, } from './errors.js';
27
31
  // Local errors outside the taxonomy — no wire representation, and no
28
32
  // `Stack` prefix. See docs/spec/wire-format.md § The taxonomy root.
29
33
  export { UseAfterCloseError, InvalidAdapterError, RelayScopeError } from './errors.js';
30
- export { SYSTEM_TYPES, NATIVE_SORT_FIELDS } from './types.js';
34
+ export { SYSTEM_TYPES, NATIVE_SORT_FIELDS } from './types/index.js';
31
35
  // Utilities
32
36
  // No in-repo caller: client-minted IDs are the default per spec, and an app
33
37
  // needing the ID before the write round-trips has to mint one itself.
34
38
  export { generateId } from './id.js';
35
39
  export { hashSchema, isCompatible } from './schema.js';
36
40
  export { applyMergePatch } from './merge.js';
37
- export { assertOneSurface } from './record-changes.js';
41
+ export { assertOneSurface, isAuthorityAssociation } from './associations/identity.js';
38
42
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,kCAAkC;AAClC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAehD,eAAe;AACf,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAc9C,qBAAqB;AACrB,OAAO,EACL,UAAU,EACV,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,EACpB,kBAAkB,EAClB,kBAAkB,EAClB,yBAAyB,EACzB,oBAAoB,EACpB,qBAAqB,EACrB,yBAAyB,EACzB,iBAAiB,GAClB,MAAM,aAAa,CAAC;AACrB,qEAAqE;AACrE,oEAAoE;AACpE,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AA8EvF,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAE9D,YAAY;AAEZ,4EAA4E;AAC5E,sEAAsE;AACtE,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGvD,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,kCAAkC;AAClC,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAgB7D,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C,eAAe;AACf,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAmBtE,cAAc;AACd,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAgB9C,qBAAqB;AACrB,OAAO,EACL,UAAU,EACV,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,EACpB,kBAAkB,EAClB,kBAAkB,EAClB,yBAAyB,EACzB,oBAAoB,EACpB,qBAAqB,EACrB,yBAAyB,EACzB,iBAAiB,GAClB,MAAM,aAAa,CAAC;AACrB,qEAAqE;AACrE,oEAAoE;AACpE,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAiFvF,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAEpE,YAAY;AAEZ,4EAA4E;AAC5E,sEAAsE;AACtE,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGvD,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC"}
@@ -0,0 +1,141 @@
1
+ /**
2
+ * App installs
3
+ * -------------------------------------------------------
4
+ * An app the owner does not run ships a manifest — the types it defines
5
+ * and the type-level grants it asks for — and the owner applies it with
6
+ * `Stack.planInstall()` then `Stack.installApp()`. What the stack keeps is
7
+ * not the manifest but the owner's approval of it: an `_install` Record,
8
+ * one per `appId`, linked by association to the `_app` cards it was
9
+ * installed for and the `_grant` Records it produced. Its version history
10
+ * is the upgrade log, and soft-deleting it is uninstalling.
11
+ *
12
+ * An install claims the families it defines, one install per family. That
13
+ * claim is what lets a contained app commit migrations within its own
14
+ * families without the owner running its code — see
15
+ * ScopedStack.commitMigration().
16
+ *
17
+ * This module holds the parts that read an install as data: the write-time
18
+ * shape rules, the family claim, and the plan diff. The verbs that write
19
+ * are in stack/install-app.ts. See docs/spec/apps.md.
20
+ */
21
+ import type { AppId, AuthorityAssociation, BaseId, EntityId, GrantContent, InstallContent, InstallRequest, RecordId, RelationshipAssociation, StackRecord, TypeId } from './types/index.js';
22
+ import type { DefineTypeOptions } from './stack/client.js';
23
+ import type { ValidationError } from './validate.js';
24
+ /** What an app ships: the types it defines and the grants it asks for. */
25
+ export type AppManifest = {
26
+ appId: AppId;
27
+ name: string;
28
+ version?: string;
29
+ types: DefineTypeOptions[];
30
+ requests: InstallRequest[];
31
+ };
32
+ /** A request on a family this install does not define, and who owns that family. */
33
+ export type ForeignRequest = InstallRequest & {
34
+ /**
35
+ * The app whose namespace the family is in, whether or not it is
36
+ * installed; `'commons'` or `'system'` for families no app owns; null
37
+ * for a family with no namespace.
38
+ */
39
+ owner: AppId | 'commons' | 'system' | null;
40
+ };
41
+ /**
42
+ * A manifest type whose definition would write: one not yet defined, or
43
+ * defined with a different schema or name. Commons types included, since
44
+ * defining one claims nothing but still fixes its shape for every app.
45
+ */
46
+ export type TypeChange = {
47
+ id: TypeId;
48
+ change: 'new' | 'schema' | 'name';
49
+ };
50
+ /**
51
+ * What applying a manifest would change, for the owner to approve.
52
+ * `installApp()` applies a plan only while it is still what planning the
53
+ * same manifest would produce. See docs/spec/apps.md § Plan, then apply.
54
+ */
55
+ export type InstallPlan = {
56
+ manifest: AppManifest;
57
+ /** The key being installed. */
58
+ did: EntityId;
59
+ /** The install as it stood when planned — null for a first install. */
60
+ existing: (StackRecord & {
61
+ content: InstallContent;
62
+ }) | null;
63
+ /** Families this install would claim that it does not claim yet. */
64
+ newFamilies: BaseId[];
65
+ /** Type versions not yet in the install's `defines`. */
66
+ newVersions: TypeId[];
67
+ requestsAdded: InstallRequest[];
68
+ requestsRemoved: InstallRequest[];
69
+ /** Requests on families the manifest does not define — the ones an approval most needs to show. */
70
+ foreignRequests: ForeignRequest[];
71
+ /** Every manifest type `installApp()` would define or redefine. */
72
+ typeChanges: TypeChange[];
73
+ /**
74
+ * Whether `did` would gain access: not yet linked to this install, or
75
+ * linked through an `_app` card that is soft-deleted, which installApp()
76
+ * undeletes. See docs/spec/apps.md § Plan, then apply.
77
+ */
78
+ newKey: boolean;
79
+ /**
80
+ * The keys already linked to the install. Each holds `requests`, so a
81
+ * plan that changes them changes every one — and a new key joins them
82
+ * as the same app. See docs/spec/apps.md § Plan, then apply.
83
+ */
84
+ linkedKeys: EntityId[];
85
+ };
86
+ /** Relationship label from an install to an `_app` card it was installed for. */
87
+ export declare const INSTALL_APP_LABEL = "install.app";
88
+ /** Relationship label from an install to a `_grant` it produced. */
89
+ export declare const INSTALL_GRANT_LABEL = "install.grant";
90
+ export declare const installAppLink: (recordId: RecordId) => RelationshipAssociation;
91
+ export declare const installGrantLink: (recordId: RecordId) => RelationshipAssociation;
92
+ /** Record-level `read` on an install for one of its keys. */
93
+ export declare const installReader: (entityId: EntityId) => AuthorityAssociation;
94
+ /** Record ids an install links to under `label`. */
95
+ export declare function linkedIds(record: StackRecord, label: string): RecordId[];
96
+ /** The part of a family before its `/` — `com.example.notes` for `com.example.notes/note`. */
97
+ export declare const namespaceOf: (baseId: BaseId) => string | null;
98
+ /**
99
+ * How a family stands toward the app `appId`: its own (the family's
100
+ * namespace is the `appId`), a commons or system family nobody owns, or
101
+ * another app's. Only an app's own families can be claimed, so which app
102
+ * owns a family never depends on which was installed first.
103
+ * See docs/spec/apps.md § Who owns a family.
104
+ */
105
+ export declare function familyStanding(baseId: BaseId, appId: AppId): 'own' | 'commons' | 'system' | 'foreign';
106
+ /**
107
+ * The families an install claims, read as data: entries that are not
108
+ * well-formed TypeIds claim nothing.
109
+ */
110
+ export declare function claimedFamilies(content: unknown): Set<BaseId>;
111
+ /**
112
+ * An `_install`'s `defines` and `requests`, asked of its content on every
113
+ * write. A schema can say both are lists; only this can say what their
114
+ * entries must name. See docs/spec/apps.md § The `_install` record.
115
+ */
116
+ export declare function validateInstall(typeId: TypeId, content: unknown): ValidationError[];
117
+ /** The manifest's types in its own namespace — the versions an install of it defines. */
118
+ export declare function ownTypeIds(manifest: AppManifest): TypeId[];
119
+ /**
120
+ * A deep-frozen copy of `manifest`, so the plan that holds it applies what
121
+ * was reviewed even if the caller's object changes afterwards.
122
+ */
123
+ export declare function snapshotManifest(manifest: AppManifest): AppManifest;
124
+ /** Whether two requests ask for the same family and exactly the same actions. */
125
+ export declare function sameRequest(a: InstallRequest, b: InstallRequest): boolean;
126
+ /** Whether a stored grant is exactly `request`, made out to `did`. */
127
+ export declare function grantIsRequest(grant: GrantContent, request: InstallRequest, did: EntityId): boolean;
128
+ /**
129
+ * Whether applying `plan` would change nothing: the install is live, this
130
+ * key is linked to it, the manifest adds and removes nothing, and its
131
+ * `name` and `version` are the ones the install holds. A server
132
+ * answers such a request as already installed rather than queuing it.
133
+ * See docs/spec/wire-format.md § Installs.
134
+ */
135
+ export declare function isPlanEmpty(plan: InstallPlan): boolean;
136
+ /**
137
+ * The parts of a plan that depend on the stack's state — what
138
+ * `installApp()` compares to refuse a stale one.
139
+ */
140
+ export declare function planFingerprint(plan: InstallPlan): string;
141
+ //# sourceMappingURL=install.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../src/install.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,219 @@
1
+ /**
2
+ * App installs
3
+ * -------------------------------------------------------
4
+ * An app the owner does not run ships a manifest — the types it defines
5
+ * and the type-level grants it asks for — and the owner applies it with
6
+ * `Stack.planInstall()` then `Stack.installApp()`. What the stack keeps is
7
+ * not the manifest but the owner's approval of it: an `_install` Record,
8
+ * one per `appId`, linked by association to the `_app` cards it was
9
+ * installed for and the `_grant` Records it produced. Its version history
10
+ * is the upgrade log, and soft-deleting it is uninstalling.
11
+ *
12
+ * An install claims the families it defines, one install per family. That
13
+ * claim is what lets a contained app commit migrations within its own
14
+ * families without the owner running its code — see
15
+ * ScopedStack.commitMigration().
16
+ *
17
+ * This module holds the parts that read an install as data: the write-time
18
+ * shape rules, the family claim, and the plan diff. The verbs that write
19
+ * are in stack/install-app.ts. See docs/spec/apps.md.
20
+ */
21
+ import { baseIdOf, familyIdProblem, parseTypeId } from './schema.js';
22
+ import { GRANT_ACTION_SET, UNGRANTABLE_SYSTEM_TYPES, sameActions } from './grants.js';
23
+ import { SYSTEM_TYPES } from './types/index.js';
24
+ /** Relationship label from an install to an `_app` card it was installed for. */
25
+ export const INSTALL_APP_LABEL = 'install.app';
26
+ /** Relationship label from an install to a `_grant` it produced. */
27
+ export const INSTALL_GRANT_LABEL = 'install.grant';
28
+ export const installAppLink = (recordId) => ({
29
+ kind: 'relationship',
30
+ label: INSTALL_APP_LABEL,
31
+ target: { kind: 'record', recordId },
32
+ });
33
+ export const installGrantLink = (recordId) => ({
34
+ kind: 'relationship',
35
+ label: INSTALL_GRANT_LABEL,
36
+ target: { kind: 'record', recordId },
37
+ });
38
+ /** Record-level `read` on an install for one of its keys. */
39
+ export const installReader = (entityId) => ({
40
+ kind: 'permission',
41
+ label: 'read',
42
+ grantee: { kind: 'entity', entityId },
43
+ });
44
+ /** Record ids an install links to under `label`. */
45
+ export function linkedIds(record, label) {
46
+ const ids = [];
47
+ for (const a of record.associations ?? []) {
48
+ if (a.kind === 'relationship' && a.label === label && a.target.kind === 'record') {
49
+ ids.push(a.target.recordId);
50
+ }
51
+ }
52
+ return ids;
53
+ }
54
+ const SYSTEM_FAMILIES = new Set(Object.values(SYSTEM_TYPES));
55
+ const isSystemFamily = (baseId) => SYSTEM_FAMILIES.has(baseId);
56
+ /** The Schema Commons namespace: families no app owns. See docs/commons/README.md. */
57
+ const COMMONS_NAMESPACE = 'org.haverstack';
58
+ /** The part of a family before its `/` — `com.example.notes` for `com.example.notes/note`. */
59
+ export const namespaceOf = (baseId) => {
60
+ const slash = baseId.indexOf('/');
61
+ return slash > 0 ? baseId.slice(0, slash) : null;
62
+ };
63
+ /**
64
+ * How a family stands toward the app `appId`: its own (the family's
65
+ * namespace is the `appId`), a commons or system family nobody owns, or
66
+ * another app's. Only an app's own families can be claimed, so which app
67
+ * owns a family never depends on which was installed first.
68
+ * See docs/spec/apps.md § Who owns a family.
69
+ */
70
+ export function familyStanding(baseId, appId) {
71
+ if (isSystemFamily(baseId))
72
+ return 'system';
73
+ const namespace = namespaceOf(baseId);
74
+ if (namespace === COMMONS_NAMESPACE)
75
+ return 'commons';
76
+ return namespace === appId ? 'own' : 'foreign';
77
+ }
78
+ /**
79
+ * The families an install claims, read as data: entries that are not
80
+ * well-formed TypeIds claim nothing.
81
+ */
82
+ export function claimedFamilies(content) {
83
+ const defines = content?.defines;
84
+ const families = new Set();
85
+ if (!Array.isArray(defines))
86
+ return families;
87
+ for (const id of defines) {
88
+ if (typeof id !== 'string')
89
+ continue;
90
+ const parsed = parseTypeId(id);
91
+ if (parsed)
92
+ families.add(parsed.baseId);
93
+ }
94
+ return families;
95
+ }
96
+ /**
97
+ * An `_install`'s `defines` and `requests`, asked of its content on every
98
+ * write. A schema can say both are lists; only this can say what their
99
+ * entries must name. See docs/spec/apps.md § The `_install` record.
100
+ */
101
+ export function validateInstall(typeId, content) {
102
+ if (baseIdOf(typeId) !== SYSTEM_TYPES.INSTALL)
103
+ return [];
104
+ const c = content;
105
+ const errors = [];
106
+ if (Array.isArray(c?.defines)) {
107
+ c.defines.forEach((id, i) => {
108
+ const parsed = typeof id === 'string' ? parseTypeId(id) : null;
109
+ if (!parsed) {
110
+ errors.push({ path: `defines[${i}]`, message: 'Expected a versioned TypeId' });
111
+ }
112
+ else if (typeof c?.appId === 'string' && familyStanding(parsed.baseId, c.appId) !== 'own') {
113
+ errors.push({
114
+ path: `defines[${i}]`,
115
+ message: `"${parsed.baseId}" is outside the namespace "${c.appId}"; an install claims only its own families`,
116
+ });
117
+ }
118
+ });
119
+ }
120
+ if (Array.isArray(c?.requests)) {
121
+ c.requests.forEach((r, i) => {
122
+ const req = r;
123
+ const problem = familyIdProblem(req?.baseId, `requests[${i}].baseId`);
124
+ if (problem) {
125
+ errors.push({ path: `requests[${i}].baseId`, message: problem });
126
+ }
127
+ else if (UNGRANTABLE_SYSTEM_TYPES.has(req.baseId)) {
128
+ errors.push({
129
+ path: `requests[${i}].baseId`,
130
+ message: `"${String(req.baseId)}" cannot be granted, so no install can request it`,
131
+ });
132
+ }
133
+ if (Array.isArray(req?.actions)) {
134
+ req.actions.forEach((a, j) => {
135
+ if (!GRANT_ACTION_SET.has(a)) {
136
+ errors.push({
137
+ path: `requests[${i}].actions[${j}]`,
138
+ message: `Unknown grant action "${String(a)}"`,
139
+ });
140
+ }
141
+ });
142
+ }
143
+ });
144
+ }
145
+ return errors;
146
+ }
147
+ /** The manifest's types in its own namespace — the versions an install of it defines. */
148
+ export function ownTypeIds(manifest) {
149
+ const ids = manifest.types
150
+ .map((t) => t.id)
151
+ .filter((id) => familyStanding(baseIdOf(id), manifest.appId) === 'own');
152
+ return [...new Set(ids)];
153
+ }
154
+ /**
155
+ * A deep-frozen copy of `manifest`, so the plan that holds it applies what
156
+ * was reviewed even if the caller's object changes afterwards.
157
+ */
158
+ export function snapshotManifest(manifest) {
159
+ return deepFreeze(structuredClone(manifest));
160
+ }
161
+ function deepFreeze(value) {
162
+ if (typeof value === 'object' && value !== null && !Object.isFrozen(value)) {
163
+ Object.freeze(value);
164
+ for (const v of Object.values(value))
165
+ deepFreeze(v);
166
+ }
167
+ return value;
168
+ }
169
+ /** Whether two requests ask for the same family and exactly the same actions. */
170
+ export function sameRequest(a, b) {
171
+ return a.baseId === b.baseId && sameActions(a.actions, b.actions);
172
+ }
173
+ /** Whether a stored grant is exactly `request`, made out to `did`. */
174
+ export function grantIsRequest(grant, request, did) {
175
+ if (grant.grantee?.kind !== 'entity' || grant.grantee.entityId !== did)
176
+ return false;
177
+ if (!Array.isArray(grant.actions))
178
+ return false;
179
+ return sameRequest({ baseId: grant.baseId, actions: grant.actions }, request);
180
+ }
181
+ /**
182
+ * Whether applying `plan` would change nothing: the install is live, this
183
+ * key is linked to it, the manifest adds and removes nothing, and its
184
+ * `name` and `version` are the ones the install holds. A server
185
+ * answers such a request as already installed rather than queuing it.
186
+ * See docs/spec/wire-format.md § Installs.
187
+ */
188
+ export function isPlanEmpty(plan) {
189
+ return (plan.existing !== null &&
190
+ !plan.existing.deletedAt &&
191
+ !plan.newKey &&
192
+ plan.manifest.name === plan.existing.content.name &&
193
+ (plan.manifest.version ?? null) === (plan.existing.content.version ?? null) &&
194
+ plan.newFamilies.length === 0 &&
195
+ plan.newVersions.length === 0 &&
196
+ plan.typeChanges.length === 0 &&
197
+ plan.requestsAdded.length === 0 &&
198
+ plan.requestsRemoved.length === 0);
199
+ }
200
+ /**
201
+ * The parts of a plan that depend on the stack's state — what
202
+ * `installApp()` compares to refuse a stale one.
203
+ */
204
+ export function planFingerprint(plan) {
205
+ return JSON.stringify([
206
+ plan.existing?.id ?? null,
207
+ plan.existing?.version ?? null,
208
+ plan.existing?.deletedAt ? true : false,
209
+ plan.newFamilies,
210
+ plan.newVersions,
211
+ plan.requestsAdded,
212
+ plan.requestsRemoved,
213
+ plan.foreignRequests,
214
+ plan.typeChanges,
215
+ plan.newKey,
216
+ plan.linkedKeys,
217
+ ]);
218
+ }
219
+ //# sourceMappingURL=install.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install.js","sourceRoot":"","sources":["../src/install.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"merge.d.ts","sourceRoot":"","sources":["../src/merge.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC,GACpC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CA0BzB"}
1
+ {"version":3,"file":"merge.d.ts","sourceRoot":"","sources":["../src/merge.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC,GACpC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAoBzB"}
package/dist/merge.js CHANGED
@@ -14,17 +14,11 @@ export function applyMergePatch(content, patch) {
14
14
  delete merged[key];
15
15
  }
16
16
  else {
17
- // defineProperty, not `merged[key] = value`: assignment goes through
18
- // [[Set]], so a patch key of `__proto__` would invoke the prototype
19
- // setter and reassign the object's prototype instead of setting a
20
- // field — silently losing the write. defineProperty creates an own
21
- // data property for any key, which is also what JSON.parse does when
22
- // the same key is read back, so both write paths agree. The spread
23
- // above is already safe (it copies data properties directly).
24
- //
25
- // Stack.create()/Stack.mutate() reject the reserved keys outright (see
26
- // validateReservedKeys); this is the backstop for adapters that call
27
- // this directly, and for the day someone deepens the merge.
17
+ // defineProperty, not assignment: [[Set]] on `__proto__` would
18
+ // reassign the prototype and lose the write, while an own data
19
+ // property is what JSON.parse makes of the same key, so both write
20
+ // paths agree. A backstop for adapters calling this directly; Stack
21
+ // refuses the reserved keys outright (validateReservedKeys).
28
22
  Object.defineProperty(merged, key, {
29
23
  value,
30
24
  writable: true,
package/dist/merge.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"merge.js","sourceRoot":"","sources":["../src/merge.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,UAAU,eAAe,CAC7B,OAAgC,EAChC,KAAqC;IAErC,MAAM,MAAM,GAA4B,EAAE,GAAG,OAAO,EAAE,CAAC;IACvD,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACjD,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YACnB,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;QACrB,CAAC;aAAM,CAAC;YACN,qEAAqE;YACrE,oEAAoE;YACpE,kEAAkE;YAClE,mEAAmE;YACnE,qEAAqE;YACrE,mEAAmE;YACnE,8DAA8D;YAC9D,EAAE;YACF,uEAAuE;YACvE,qEAAqE;YACrE,4DAA4D;YAC5D,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,GAAG,EAAE;gBACjC,KAAK;gBACL,QAAQ,EAAE,IAAI;gBACd,UAAU,EAAE,IAAI;gBAChB,YAAY,EAAE,IAAI;aACnB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
1
+ {"version":3,"file":"merge.js","sourceRoot":"","sources":["../src/merge.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,UAAU,eAAe,CAC7B,OAAgC,EAChC,KAAqC;IAErC,MAAM,MAAM,GAA4B,EAAE,GAAG,OAAO,EAAE,CAAC;IACvD,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACjD,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YACnB,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;QACrB,CAAC;aAAM,CAAC;YACN,+DAA+D;YAC/D,+DAA+D;YAC/D,mEAAmE;YACnE,oEAAoE;YACpE,6DAA6D;YAC7D,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,GAAG,EAAE;gBACjC,KAAK;gBACL,QAAQ,EAAE,IAAI;gBACd,UAAU,EAAE,IAAI;gBAChB,YAAY,EAAE,IAAI;aACnB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,102 @@
1
+ /**
2
+ * Migration steps
3
+ * -------------------------------------------------------
4
+ * A migration is a list of declared steps — rename, map, add, drop and
5
+ * derive — rather than a function, so that core can read what became of
6
+ * each field. Two things are built from one list: the in-memory `migrate`
7
+ * that `Stack.open()`, a collection's reads and `migrateAll()` run, and the
8
+ * field origins a collection translates a content filter or sort through.
9
+ *
10
+ * `fieldOrigins()` also checks the list against both schemas, so a step
11
+ * the target Type would refuse fails when `migration()` runs rather than
12
+ * on the first record `migrateAll()` writes. See docs/spec/data-model.md
13
+ * § Migration steps.
14
+ */
15
+ import type { ReadonlyTypeSchema } from './type-handle.js';
16
+ export type RenameStep = {
17
+ readonly op: 'rename';
18
+ readonly from: string;
19
+ readonly to: string;
20
+ };
21
+ export type MapStep = {
22
+ readonly op: 'map';
23
+ readonly field: string;
24
+ readonly values: Readonly<Record<string, string>>;
25
+ };
26
+ export type AddStep = {
27
+ readonly op: 'add';
28
+ readonly field: string;
29
+ readonly value: unknown;
30
+ };
31
+ export type DropStep = {
32
+ readonly op: 'drop';
33
+ readonly field: string;
34
+ };
35
+ /**
36
+ * `derive` is a method so a step typed on one handle's content fits a list
37
+ * of untyped ones, as `Migration.migrate` does.
38
+ */
39
+ export type DeriveStep<F = Record<string, unknown>> = {
40
+ readonly op: 'derive';
41
+ readonly field: string;
42
+ derive(content: F): unknown;
43
+ };
44
+ /** One step of a migration, typed on the content stored at its `from`. */
45
+ export type MigrationStep<F = Record<string, unknown>> = RenameStep | MapStep | AddStep | DropStep | DeriveStep<F>;
46
+ /** Move a field's value to a new name. */
47
+ export declare const rename: (from: string, to: string) => RenameStep;
48
+ /**
49
+ * Replace each value `values` lists with its mapping, keeping any other,
50
+ * element-wise through an array. A stored enum may hold a value no handle
51
+ * lists, and it is carried through rather than lost.
52
+ */
53
+ export declare const map: (field: string, values: Readonly<Record<string, string>>) => MapStep;
54
+ /** Set a field to a constant. */
55
+ export declare const add: (field: string, value: unknown) => AddStep;
56
+ /** Remove a field. */
57
+ export declare const drop: (field: string) => DropStep;
58
+ /**
59
+ * Set a field to what `fn` computes from the record as stored at the
60
+ * migration's `from`; `undefined` leaves it absent. The one opaque step: a
61
+ * field it produces does not translate across versions.
62
+ */
63
+ export declare const derive: <F>(field: string, fn: (content: F) => unknown) => DeriveStep<F>;
64
+ /** The content `steps` produce from `content`, which is left untouched. */
65
+ export declare const applySteps: (steps: readonly MigrationStep[], content: Record<string, unknown>) => Record<string, unknown>;
66
+ /**
67
+ * What one of the target's top-level fields is, in terms of the source's:
68
+ * a source field, its string values possibly remapped; a constant, where
69
+ * `undefined` is no value; or derived, which nothing can see through.
70
+ */
71
+ export type FieldOrigin = {
72
+ readonly kind: 'field';
73
+ readonly field: string;
74
+ readonly values?: Readonly<Record<string, string>>;
75
+ } | {
76
+ readonly kind: 'constant';
77
+ readonly value: unknown;
78
+ } | {
79
+ readonly kind: 'derived';
80
+ };
81
+ /**
82
+ * Every top-level field the target declares, by its origin, and every name
83
+ * the steps removed, as no value.
84
+ */
85
+ export type FieldOrigins = ReadonlyMap<string, FieldOrigin>;
86
+ /**
87
+ * The origins across two migrations end to end: `lower` takes A to B and
88
+ * `upper` takes B to C, so the result says what each of C's fields is in
89
+ * terms of A's.
90
+ */
91
+ export declare const composeOrigins: (lower: FieldOrigins, upper: FieldOrigins) => FieldOrigins;
92
+ /**
93
+ * What each of `to`'s top-level fields is in terms of `from`'s, after
94
+ * `steps`. Returns the problem that makes the list unusable as a string
95
+ * instead: a step naming a field that is not there, a field `to` would
96
+ * refuse, or one it requires that nothing produces. See
97
+ * docs/spec/data-model.md § Migration steps.
98
+ */
99
+ export declare const fieldOrigins: (steps: readonly MigrationStep<never>[], from: ReadonlyTypeSchema, to: ReadonlyTypeSchema) => FieldOrigins | string;
100
+ export declare const recordOrigins: (migration: object, origins: FieldOrigins) => void;
101
+ export declare const originsOf: (migration: object) => FieldOrigins | undefined;
102
+ //# sourceMappingURL=migration-steps.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migration-steps.d.ts","sourceRoot":"","sources":["../src/migration-steps.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAO3D,MAAM,MAAM,UAAU,GAAG;IAAE,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC;AAC/F,MAAM,MAAM,OAAO,GAAG;IACpB,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IACnB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CACnD,CAAC;AACF,MAAM,MAAM,OAAO,GAAG;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAAC;AAC9F,MAAM,MAAM,QAAQ,GAAG;IAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AACvE;;;GAGG;AACH,MAAM,MAAM,UAAU,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI;IACpD,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,OAAO,EAAE,CAAC,GAAG,OAAO,CAAC;CAC7B,CAAC;AAEF,0EAA0E;AAC1E,MAAM,MAAM,aAAa,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IACjD,UAAU,GACV,OAAO,GACP,OAAO,GACP,QAAQ,GACR,UAAU,CAAC,CAAC,CAAC,CAAC;AAElB,0CAA0C;AAC1C,eAAO,MAAM,MAAM,GAAI,MAAM,MAAM,EAAE,IAAI,MAAM,KAAG,UACP,CAAC;AAE5C;;;;GAIG;AACH,eAAO,MAAM,GAAG,GAAI,OAAO,MAAM,EAAE,QAAQ,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,KAAG,OACH,CAAC;AAE5E,iCAAiC;AACjC,eAAO,MAAM,GAAG,GAAI,OAAO,MAAM,EAAE,OAAO,OAAO,KAAG,OACR,CAAC;AAE7C,sBAAsB;AACtB,eAAO,MAAM,IAAI,GAAI,OAAO,MAAM,KAAG,QAAgD,CAAC;AAEtF;;;;GAIG;AACH,eAAO,MAAM,MAAM,GAAI,CAAC,EAAE,OAAO,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,OAAO,KAAG,UAAU,CAAC,CAAC,CAC/B,CAAC;AAsBrD,2EAA2E;AAC3E,eAAO,MAAM,UAAU,GACrB,OAAO,SAAS,aAAa,EAAE,EAC/B,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC/B,MAAM,CAAC,MAAM,EAAE,OAAO,CA0BxB,CAAC;AAMF;;;;GAIG;AACH,MAAM,MAAM,WAAW,GACnB;IACE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CACpD,GACD;IAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;CAAE,GACtD;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;CAAE,CAAC;AAEjC;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;AAiB5D;;;;GAIG;AACH,eAAO,MAAM,cAAc,GAAI,OAAO,YAAY,EAAE,OAAO,YAAY,KAAG,YAsBzE,CAAC;AAwEF;;;;;;GAMG;AACH,eAAO,MAAM,YAAY,GACvB,OAAO,SAAS,aAAa,CAAC,KAAK,CAAC,EAAE,EACtC,MAAM,kBAAkB,EACxB,IAAI,kBAAkB,KACrB,YAAY,GAAG,MAqFjB,CAAC;AAaF,eAAO,MAAM,aAAa,GAAI,WAAW,MAAM,EAAE,SAAS,YAAY,KAAG,IAExE,CAAC;AAEF,eAAO,MAAM,SAAS,GAAI,WAAW,MAAM,KAAG,YAAY,GAAG,SAAmC,CAAC"}