@shaxpir/duiduidui-models 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (211) hide show
  1. package/README.md +1 -0
  2. package/decs.d.ts +87 -0
  3. package/dist/index.d.ts +3 -0
  4. package/dist/index.js +20 -0
  5. package/dist/models/OutboundMessage.d.ts +18 -0
  6. package/dist/models/OutboundMessage.js +25 -0
  7. package/dist/models/content/Activity.d.ts +10 -0
  8. package/dist/models/content/Activity.js +2 -0
  9. package/dist/models/content/ArrayView.d.ts +26 -0
  10. package/dist/models/content/ArrayView.js +174 -0
  11. package/dist/models/content/Billing.d.ts +144 -0
  12. package/dist/models/content/Billing.js +418 -0
  13. package/dist/models/content/Book.d.ts +77 -0
  14. package/dist/models/content/Book.js +407 -0
  15. package/dist/models/content/Category.d.ts +16 -0
  16. package/dist/models/content/Category.js +20 -0
  17. package/dist/models/content/Checkpointable.d.ts +21 -0
  18. package/dist/models/content/Checkpointable.js +156 -0
  19. package/dist/models/content/Comment.d.ts +19 -0
  20. package/dist/models/content/Comment.js +53 -0
  21. package/dist/models/content/ConceptArt.d.ts +31 -0
  22. package/dist/models/content/ConceptArt.js +84 -0
  23. package/dist/models/content/Content.d.ts +52 -0
  24. package/dist/models/content/Content.js +61 -0
  25. package/dist/models/content/ContentKind.d.ts +10 -0
  26. package/dist/models/content/ContentKind.js +16 -0
  27. package/dist/models/content/Context.d.ts +28 -0
  28. package/dist/models/content/Context.js +162 -0
  29. package/dist/models/content/DevEnv.d.ts +5 -0
  30. package/dist/models/content/DevEnv.js +9 -0
  31. package/dist/models/content/Device.d.ts +24 -0
  32. package/dist/models/content/Device.js +62 -0
  33. package/dist/models/content/Dictionary.d.ts +31 -0
  34. package/dist/models/content/Dictionary.js +5 -0
  35. package/dist/models/content/DictionaryEntry.d.ts +20 -0
  36. package/dist/models/content/DictionaryEntry.js +2 -0
  37. package/dist/models/content/ElasticModel.d.ts +149 -0
  38. package/dist/models/content/ElasticModel.js +179 -0
  39. package/dist/models/content/Environment.d.ts +61 -0
  40. package/dist/models/content/Environment.js +124 -0
  41. package/dist/models/content/ExportOptions.d.ts +64 -0
  42. package/dist/models/content/ExportOptions.js +213 -0
  43. package/dist/models/content/Folder.d.ts +16 -0
  44. package/dist/models/content/Folder.js +33 -0
  45. package/dist/models/content/Fragment.d.ts +54 -0
  46. package/dist/models/content/Fragment.js +181 -0
  47. package/dist/models/content/GeoLocation.d.ts +4 -0
  48. package/dist/models/content/GeoLocation.js +2 -0
  49. package/dist/models/content/Hanzi.d.ts +21 -0
  50. package/dist/models/content/Hanzi.js +2 -0
  51. package/dist/models/content/HighlightRule.d.ts +9 -0
  52. package/dist/models/content/HighlightRule.js +2 -0
  53. package/dist/models/content/Manifest.d.ts +42 -0
  54. package/dist/models/content/Manifest.js +114 -0
  55. package/dist/models/content/Media.d.ts +32 -0
  56. package/dist/models/content/Media.js +98 -0
  57. package/dist/models/content/Metric.d.ts +46 -0
  58. package/dist/models/content/Metric.js +183 -0
  59. package/dist/models/content/Migration.d.ts +68 -0
  60. package/dist/models/content/Migration.js +155 -0
  61. package/dist/models/content/Model.d.ts +45 -0
  62. package/dist/models/content/Model.js +280 -0
  63. package/dist/models/content/Permissions.d.ts +7 -0
  64. package/dist/models/content/Permissions.js +20 -0
  65. package/dist/models/content/Phrase.d.ts +8 -0
  66. package/dist/models/content/Phrase.js +2 -0
  67. package/dist/models/content/Placeholder.d.ts +8 -0
  68. package/dist/models/content/Placeholder.js +36 -0
  69. package/dist/models/content/Profile.d.ts +30 -0
  70. package/dist/models/content/Profile.js +95 -0
  71. package/dist/models/content/RichText.d.ts +58 -0
  72. package/dist/models/content/RichText.js +79 -0
  73. package/dist/models/content/Session.d.ts +39 -0
  74. package/dist/models/content/Session.js +173 -0
  75. package/dist/models/content/Speech.d.ts +67 -0
  76. package/dist/models/content/Speech.js +97 -0
  77. package/dist/models/content/Stub.d.ts +24 -0
  78. package/dist/models/content/Stub.js +179 -0
  79. package/dist/models/content/Time.d.ts +56 -0
  80. package/dist/models/content/Time.js +295 -0
  81. package/dist/models/content/User.d.ts +36 -0
  82. package/dist/models/content/User.js +95 -0
  83. package/dist/models/content/Workspace.d.ts +71 -0
  84. package/dist/models/content/Workspace.js +237 -0
  85. package/dist/models/content/index.d.ts +36 -0
  86. package/dist/models/content/index.js +53 -0
  87. package/dist/models/index.d.ts +4 -0
  88. package/dist/models/index.js +21 -0
  89. package/dist/models/legacy/LegacyBodyFormat.d.ts +9 -0
  90. package/dist/models/legacy/LegacyBodyFormat.js +2 -0
  91. package/dist/models/legacy/LegacyComment.d.ts +12 -0
  92. package/dist/models/legacy/LegacyComment.js +2 -0
  93. package/dist/models/legacy/LegacyContent.d.ts +53 -0
  94. package/dist/models/legacy/LegacyContent.js +55 -0
  95. package/dist/models/legacy/LegacyConversion.d.ts +55 -0
  96. package/dist/models/legacy/LegacyConversion.js +401 -0
  97. package/dist/models/legacy/LegacyFragment.d.ts +21 -0
  98. package/dist/models/legacy/LegacyFragment.js +2 -0
  99. package/dist/models/legacy/LegacyLocator.d.ts +8 -0
  100. package/dist/models/legacy/LegacyLocator.js +31 -0
  101. package/dist/models/legacy/LegacyOutboundMessage.d.ts +16 -0
  102. package/dist/models/legacy/LegacyOutboundMessage.js +13 -0
  103. package/dist/models/legacy/LegacyPicture.d.ts +14 -0
  104. package/dist/models/legacy/LegacyPicture.js +2 -0
  105. package/dist/models/legacy/LegacyProfile.d.ts +9 -0
  106. package/dist/models/legacy/LegacyProfile.js +2 -0
  107. package/dist/models/legacy/LegacySession.d.ts +41 -0
  108. package/dist/models/legacy/LegacySession.js +35 -0
  109. package/dist/models/legacy/LegacyStory.d.ts +23 -0
  110. package/dist/models/legacy/LegacyStory.js +2 -0
  111. package/dist/models/legacy/LegacyStub.d.ts +15 -0
  112. package/dist/models/legacy/LegacyStub.js +2 -0
  113. package/dist/models/legacy/LegacyTransaction.d.ts +14 -0
  114. package/dist/models/legacy/LegacyTransaction.js +49 -0
  115. package/dist/models/legacy/LegacyUser.d.ts +28 -0
  116. package/dist/models/legacy/LegacyUser.js +32 -0
  117. package/dist/models/legacy/LegacyWorkspace.d.ts +23 -0
  118. package/dist/models/legacy/LegacyWorkspace.js +6 -0
  119. package/dist/models/legacy/index.d.ts +15 -0
  120. package/dist/models/legacy/index.js +32 -0
  121. package/dist/models/markup/BodyFormat.d.ts +14 -0
  122. package/dist/models/markup/BodyFormat.js +190 -0
  123. package/dist/models/markup/ChangeModel.d.ts +22 -0
  124. package/dist/models/markup/ChangeModel.js +107 -0
  125. package/dist/models/markup/DeltaOps.d.ts +5 -0
  126. package/dist/models/markup/DeltaOps.js +74 -0
  127. package/dist/models/markup/HtmlMarkup.d.ts +4 -0
  128. package/dist/models/markup/HtmlMarkup.js +21 -0
  129. package/dist/models/markup/Operation.d.ts +32 -0
  130. package/dist/models/markup/Operation.js +194 -0
  131. package/dist/models/markup/TextEditOps.d.ts +9 -0
  132. package/dist/models/markup/TextEditOps.js +50 -0
  133. package/dist/models/markup/index.d.ts +6 -0
  134. package/dist/models/markup/index.js +23 -0
  135. package/dist/repo/ConnectionListener.d.ts +9 -0
  136. package/dist/repo/ConnectionListener.js +21 -0
  137. package/dist/repo/PermissiveJson1.d.ts +58 -0
  138. package/dist/repo/PermissiveJson1.js +39 -0
  139. package/dist/repo/ShareSync.d.ts +60 -0
  140. package/dist/repo/ShareSync.js +348 -0
  141. package/dist/repo/index.d.ts +3 -0
  142. package/dist/repo/index.js +20 -0
  143. package/dist/util/Async.d.ts +8 -0
  144. package/dist/util/Async.js +18 -0
  145. package/dist/util/Base62.d.ts +6 -0
  146. package/dist/util/Base62.js +47 -0
  147. package/dist/util/BinarySearch.d.ts +7 -0
  148. package/dist/util/BinarySearch.js +46 -0
  149. package/dist/util/CachingHasher.d.ts +8 -0
  150. package/dist/util/CachingHasher.js +41 -0
  151. package/dist/util/Color.d.ts +32 -0
  152. package/dist/util/Color.js +204 -0
  153. package/dist/util/Dispatch.d.ts +15 -0
  154. package/dist/util/Dispatch.js +79 -0
  155. package/dist/util/EditDistance.d.ts +13 -0
  156. package/dist/util/EditDistance.js +184 -0
  157. package/dist/util/Encryption.d.ts +5 -0
  158. package/dist/util/Encryption.js +2 -0
  159. package/dist/util/Logging.d.ts +108 -0
  160. package/dist/util/Logging.js +412 -0
  161. package/dist/util/NumberFormat.d.ts +14 -0
  162. package/dist/util/NumberFormat.js +224 -0
  163. package/dist/util/Struct.d.ts +4 -0
  164. package/dist/util/Struct.js +15 -0
  165. package/dist/util/Template.d.ts +16 -0
  166. package/dist/util/Template.js +128 -0
  167. package/dist/util/Text.d.ts +45 -0
  168. package/dist/util/Text.js +243 -0
  169. package/dist/util/Tuples.d.ts +9 -0
  170. package/dist/util/Tuples.js +135 -0
  171. package/dist/util/Validate.d.ts +4 -0
  172. package/dist/util/Validate.js +11 -0
  173. package/dist/util/Vocabulary.d.ts +3 -0
  174. package/dist/util/Vocabulary.js +35 -0
  175. package/dist/util/index.d.ts +16 -0
  176. package/dist/util/index.js +33 -0
  177. package/lib/models/content/ArrayView.ts +203 -0
  178. package/lib/models/content/Billing.ts +558 -0
  179. package/lib/models/content/Content.ts +110 -0
  180. package/lib/models/content/ContentKind.ts +14 -0
  181. package/lib/models/content/DevEnv.ts +5 -0
  182. package/lib/models/content/Device.ts +86 -0
  183. package/lib/models/content/DictionaryEntry.ts +22 -0
  184. package/lib/models/content/GeoLocation.ts +4 -0
  185. package/lib/models/content/Hanzi.ts +25 -0
  186. package/lib/models/content/Manifest.ts +162 -0
  187. package/lib/models/content/Media.ts +126 -0
  188. package/lib/models/content/Model.ts +327 -0
  189. package/lib/models/content/Permissions.ts +21 -0
  190. package/lib/models/content/Phrase.ts +10 -0
  191. package/lib/models/content/Profile.ts +119 -0
  192. package/lib/models/content/Time.ts +328 -0
  193. package/lib/models/content/User.ts +130 -0
  194. package/lib/models/markup/ChangeModel.ts +95 -0
  195. package/lib/models/markup/DeltaOps.ts +71 -0
  196. package/lib/models/markup/Operation.ts +215 -0
  197. package/lib/models/markup/TextEditOps.ts +50 -0
  198. package/lib/repo/ConnectionListener.ts +25 -0
  199. package/lib/repo/PermissiveJson1.ts +14 -0
  200. package/lib/repo/ShareSync.ts +390 -0
  201. package/lib/util/Base62.ts +47 -0
  202. package/lib/util/CachingHasher.ts +38 -0
  203. package/lib/util/Dispatch.ts +92 -0
  204. package/lib/util/Encryption.ts +5 -0
  205. package/lib/util/Logging.ts +568 -0
  206. package/lib/util/NumberFormat.ts +194 -0
  207. package/lib/util/Struct.ts +14 -0
  208. package/lib/util/Tuples.ts +131 -0
  209. package/package.json +41 -0
  210. package/tsconfig.json +25 -0
  211. package/tslint.json +46 -0
@@ -0,0 +1,155 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Migration = exports.MigrationStatus = void 0;
4
+ const ShareSync_1 = require("../../repo/ShareSync");
5
+ const CachingHasher_1 = require("../../util/CachingHasher");
6
+ const markup_1 = require("../markup");
7
+ const Content_1 = require("./Content");
8
+ const ContentKind_1 = require("./ContentKind");
9
+ const Time_1 = require("./Time");
10
+ var MigrationStatus;
11
+ (function (MigrationStatus) {
12
+ MigrationStatus["MIGRATED"] = "MIGRATED";
13
+ MigrationStatus["CANT_MIGRATE"] = "CANT_MIGRATE";
14
+ MigrationStatus["REPAIRED"] = "REPAIRED";
15
+ MigrationStatus["CANT_REPAIR"] = "CANT_REPAIR";
16
+ MigrationStatus["SKIPPED"] = "SKIPPED";
17
+ MigrationStatus["UPDATED"] = "UPDATED";
18
+ })(MigrationStatus || (exports.MigrationStatus = MigrationStatus = {}));
19
+ class Migration extends Content_1.Content {
20
+ constructor(doc, shouldAcquire, shareSync) {
21
+ super(doc, shouldAcquire, shareSync);
22
+ }
23
+ static makeMigrationId(userId) {
24
+ return CachingHasher_1.CachingHasher.makeMd5ContentId(userId + "-" + ContentKind_1.ContentKind.MIGRATION);
25
+ }
26
+ static create(userId, isPrimary, deviceId) {
27
+ const now = Time_1.MultiClock.now();
28
+ const migrationId = Migration.makeMigrationId(userId);
29
+ const migrationRef = Content_1.Content.makeContentRef(migrationId, now.utc_time);
30
+ return ShareSync_1.ShareSyncFactory.get().createContent({
31
+ meta: {
32
+ ref: migrationRef,
33
+ is_head: false,
34
+ kind: ContentKind_1.ContentKind.MIGRATION,
35
+ id: migrationId,
36
+ owner: userId,
37
+ created_at: now,
38
+ updated_at: now
39
+ },
40
+ payload: {
41
+ start: now,
42
+ end: now,
43
+ is_complete: false,
44
+ is_primary: isPrimary,
45
+ device_id: deviceId,
46
+ legacy_snapshot_count: 0,
47
+ migrated_count: 0,
48
+ cant_migrate_count: 0,
49
+ repaired_count: 0,
50
+ cant_repair_count: 0,
51
+ updated_count: 0,
52
+ skipped_count: 0,
53
+ duration_minutes: 0,
54
+ migration_entries: []
55
+ }
56
+ });
57
+ }
58
+ get payload() {
59
+ this.checkDisposed("Migration.payload");
60
+ return this.doc.data.payload;
61
+ }
62
+ get durationMinutes() {
63
+ this.checkDisposed("Migration.durationMinutes");
64
+ return this.payload.duration_minutes;
65
+ }
66
+ get isPrimary() {
67
+ this.checkDisposed("Migration.isPrimary");
68
+ return this.payload.is_primary;
69
+ }
70
+ get isComplete() {
71
+ this.checkDisposed("Migration.isComplete");
72
+ return this.payload.is_complete;
73
+ }
74
+ setIsComplete(value) {
75
+ this.checkDisposed("Migration.setIsComplete");
76
+ if (this.isComplete != value) {
77
+ const batch = new markup_1.BatchOperation(this);
78
+ batch.setPathValue(['payload', 'is_complete'], value);
79
+ this.touch(batch, batch.at);
80
+ batch.commit();
81
+ }
82
+ }
83
+ get legacySnapshotCount() {
84
+ this.checkDisposed("Migration.legacySnapshotCount");
85
+ return this.payload.legacy_snapshot_count;
86
+ }
87
+ setLegacySnapshotCount(value) {
88
+ this.checkDisposed("Migration.setLegacySnapshotCount");
89
+ if (this.legacySnapshotCount != value) {
90
+ const batch = new markup_1.BatchOperation(this);
91
+ batch.setPathValue(['payload', 'legacy_snapshot_count'], value);
92
+ this.touch(batch, batch.at);
93
+ batch.commit();
94
+ }
95
+ }
96
+ get repairedCount() {
97
+ this.checkDisposed("Migration.repairedCount");
98
+ return this.payload.repaired_count;
99
+ }
100
+ get cantRepairCount() {
101
+ this.checkDisposed("Migration.cantRepairCount");
102
+ return this.payload.cant_repair_count;
103
+ }
104
+ get migratedCount() {
105
+ this.checkDisposed("Migration.migratedCount");
106
+ return this.payload.migrated_count;
107
+ }
108
+ get cantMigrateCount() {
109
+ this.checkDisposed("Migration.cantMigrateCount");
110
+ return this.payload.cant_migrate_count;
111
+ }
112
+ get updatedCount() {
113
+ this.checkDisposed("Migration.updatedCount");
114
+ return this.payload.updated_count;
115
+ }
116
+ get skippedCount() {
117
+ this.checkDisposed("Migration.skippedCount");
118
+ return this.payload.skipped_count;
119
+ }
120
+ addMigrationEntry(entry) {
121
+ this.checkDisposed("Migration.addMigrationEntry");
122
+ const batch = new markup_1.BatchOperation(this, entry.at);
123
+ const modelCount = entry.models.length;
124
+ batch.pushIntoArray(['payload', 'migration_entries'], entry);
125
+ this.touch(batch, entry.at);
126
+ switch (entry.status) {
127
+ case MigrationStatus.MIGRATED:
128
+ batch.setPathValue(['payload', 'migrated_count'], this.migratedCount + modelCount);
129
+ break;
130
+ case MigrationStatus.CANT_MIGRATE:
131
+ batch.setPathValue(['payload', 'cant_migrate_count'], this.cantMigrateCount + modelCount);
132
+ break;
133
+ case MigrationStatus.REPAIRED:
134
+ batch.setPathValue(['payload', 'repaired_count'], this.repairedCount + modelCount);
135
+ break;
136
+ case MigrationStatus.CANT_REPAIR:
137
+ batch.setPathValue(['payload', 'cant_repair_count'], this.cantRepairCount + modelCount);
138
+ break;
139
+ case MigrationStatus.UPDATED:
140
+ batch.setPathValue(['payload', 'updated_count'], this.updatedCount + modelCount);
141
+ break;
142
+ case MigrationStatus.SKIPPED:
143
+ batch.setPathValue(['payload', 'skipped_count'], this.skippedCount + modelCount);
144
+ break;
145
+ }
146
+ batch.commit();
147
+ }
148
+ touch(batch, at) {
149
+ const minutes = Time_1.Time.absDiffMinutes(at.utc_time, this.payload.start.utc_time);
150
+ batch.setPathValue(['payload', 'duration_minutes'], minutes);
151
+ batch.setPathValue(['payload', 'end', 'utc_time'], at.utc_time);
152
+ batch.setPathValue(['payload', 'end', 'local_time'], at.local_time);
153
+ }
154
+ }
155
+ exports.Migration = Migration;
@@ -0,0 +1,45 @@
1
+ /// <reference path="../../../decs.d.ts" />
2
+ import { Doc } from '@shaxpir/sharedb/lib/client';
3
+ import { ShareSync } from '../../repo/ShareSync';
4
+ import { DispatchTopic } from '../../util/Dispatch';
5
+ import { ContentId, ContentMeta, ContentRef } from './Content';
6
+ import { ContentKind } from './ContentKind';
7
+ import { ManifestBody } from './Manifest';
8
+ import { PermissionType } from './Permissions';
9
+ import { CompactDateTime } from './Time';
10
+ export declare abstract class Model {
11
+ static CHANGED: DispatchTopic;
12
+ doc: Doc;
13
+ private _isDisposed;
14
+ private _isForbidden;
15
+ private _shouldPerformModelChangeAnalysis;
16
+ private _dataBeforeOpBatch;
17
+ private _clearEventListeners;
18
+ protected shareSync: ShareSync;
19
+ private _subscribingPromise;
20
+ private _acquireCount;
21
+ constructor(doc: Doc, shouldAcquire: boolean, shareSync: ShareSync);
22
+ get kind(): ContentKind;
23
+ get ref(): ContentRef;
24
+ get compoundKey(): string;
25
+ exists(): boolean;
26
+ get isForbidden(): boolean;
27
+ get isSubscribed(): boolean;
28
+ get acquireCount(): number;
29
+ acquire(minVersion?: CompactDateTime): Promise<Model>;
30
+ release(): void;
31
+ dispose(): void;
32
+ disposeAndDestroy(): void;
33
+ disposeAndUnsubscribe(): void;
34
+ fetch(): Promise<Model>;
35
+ subscribe(): Promise<Model>;
36
+ unsubscribe(): Promise<Model>;
37
+ isDisposed(): boolean;
38
+ checkDisposed(source: string): void;
39
+ ensureData(): Promise<Model>;
40
+ ensureRecentData(minVersion: CompactDateTime): Promise<Model>;
41
+ doesUserHavePermission(userId: ContentId, type: PermissionType): boolean;
42
+ static doesUserHaveManifestPermission(data: ManifestBody, userId: ContentId, type: PermissionType): boolean;
43
+ static doesUserHaveContentPermission(kind: ContentKind, meta: ContentMeta, userId: ContentId, type: PermissionType): boolean;
44
+ private log;
45
+ }
@@ -0,0 +1,280 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Model = void 0;
4
+ const Struct_1 = require("../../util/Struct");
5
+ const Dispatch_1 = require("../../util/Dispatch");
6
+ const ChangeModel_1 = require("../markup/ChangeModel");
7
+ const ContentKind_1 = require("./ContentKind");
8
+ const Permissions_1 = require("./Permissions");
9
+ class Model {
10
+ constructor(doc, shouldAcquire, shareSync) {
11
+ this._dataBeforeOpBatch = null;
12
+ this._clearEventListeners = null;
13
+ this._subscribingPromise = null;
14
+ this._acquireCount = 0;
15
+ const model = this;
16
+ model.doc = doc;
17
+ model.shareSync = shareSync;
18
+ model._isDisposed = false;
19
+ model._isForbidden = false;
20
+ // When a model is newly created, or retrieved via a "fetch query", treat that as an implicit
21
+ // call to "acquire", since the SharedDB doc object will eventually need to be disposed.
22
+ if (shouldAcquire) {
23
+ this._acquireCount++;
24
+ }
25
+ const onBeforeOpBatch = function (op, source) {
26
+ if (model._shouldPerformModelChangeAnalysis) {
27
+ model._dataBeforeOpBatch = Struct_1.Struct.clone(model.doc.data);
28
+ }
29
+ };
30
+ const onOpBatch = function (op, source) {
31
+ if (model._shouldPerformModelChangeAnalysis) {
32
+ // Use tuple-arrays to perform a diff...
33
+ const dataAfterOpBatch = Struct_1.Struct.clone(model.doc.data);
34
+ let changeItems = ChangeModel_1.ChangeModel.between(model._dataBeforeOpBatch, dataAfterOpBatch);
35
+ model._dataBeforeOpBatch = null;
36
+ // FROM https://share.github.io/sharedb/api/doc ...
37
+ // The 'source' value will be false for remote ops received from other clients, or will be truthy
38
+ // for ops submitted from this doc instance. For local ops, it will be the value of source supplied
39
+ // to submitOp, or true if no value was supplied
40
+ const isLocalChange = !!source;
41
+ const change = {
42
+ local: isLocalChange,
43
+ model: model,
44
+ items: changeItems,
45
+ op: op
46
+ };
47
+ Dispatch_1.Dispatch.publish(Model.CHANGED, change);
48
+ }
49
+ };
50
+ model.doc.on('before op batch', onBeforeOpBatch);
51
+ model.doc.on('op batch', onOpBatch);
52
+ this._clearEventListeners = function () {
53
+ if (model.doc && model.doc.off) {
54
+ model.doc.off('before op batch', onBeforeOpBatch);
55
+ model.doc.off('op batch', onOpBatch);
56
+ }
57
+ };
58
+ }
59
+ get kind() {
60
+ return this.doc.collection;
61
+ }
62
+ get ref() {
63
+ return this.doc.id;
64
+ }
65
+ get compoundKey() {
66
+ return `${this.doc.collection}/${this.doc.id}`;
67
+ }
68
+ exists() {
69
+ return (!!this.doc.type) && !this.isForbidden;
70
+ }
71
+ get isForbidden() {
72
+ return this._isForbidden;
73
+ }
74
+ get isSubscribed() {
75
+ return this.doc.subscribed;
76
+ }
77
+ get acquireCount() {
78
+ return this._acquireCount;
79
+ }
80
+ async acquire(minVersion) {
81
+ this._acquireCount++;
82
+ if (minVersion) {
83
+ this.log(`ACQUIRE: (${this.compoundKey}) at minVersion '${minVersion}'; acquireCount = ${this.acquireCount}`);
84
+ return this.ensureRecentData(minVersion);
85
+ }
86
+ else {
87
+ this.log(`ACQUIRE: (${this.compoundKey}); acquireCount = ${this.acquireCount}`);
88
+ return this.ensureData();
89
+ }
90
+ }
91
+ release() {
92
+ this._acquireCount--;
93
+ this.log(`RELEASE: (${this.compoundKey}); acquireCount = ${this.acquireCount}`);
94
+ if (this._acquireCount <= 0) {
95
+ this._acquireCount = 0;
96
+ this.dispose();
97
+ }
98
+ }
99
+ dispose() {
100
+ const model = this;
101
+ model._clearEventListeners();
102
+ model.shareSync.dispose(model);
103
+ }
104
+ disposeAndDestroy() {
105
+ this.log(`DISPOSE (AND DESTROY): (${this.compoundKey})`);
106
+ this._isDisposed = true;
107
+ this.doc.destroy();
108
+ }
109
+ disposeAndUnsubscribe() {
110
+ this.log(`DISPOSE (AND UNSUBSCRIBE): (${this.compoundKey})`);
111
+ this._isDisposed = true;
112
+ if (this.isSubscribed) {
113
+ this.unsubscribe();
114
+ }
115
+ }
116
+ async fetch() {
117
+ this.log(`FETCH: (${this.compoundKey})`);
118
+ const model = this;
119
+ return new Promise((resolve, reject) => {
120
+ model.doc.fetch((fetchErr) => {
121
+ if (fetchErr) {
122
+ if (fetchErr.message == 'forbidden') {
123
+ model._isForbidden = true;
124
+ resolve(model);
125
+ }
126
+ else {
127
+ const message = `error fetching model ${model.compoundKey}: ${fetchErr}`;
128
+ console.log(message);
129
+ model.release();
130
+ reject(message);
131
+ }
132
+ }
133
+ else {
134
+ model.shareSync.isDebug() && console.log(`fetched model ${model.compoundKey}`);
135
+ resolve(model);
136
+ }
137
+ });
138
+ });
139
+ }
140
+ async subscribe() {
141
+ this.log(`SUBSCRIBE: (${this.compoundKey})`);
142
+ if (this._subscribingPromise != null) {
143
+ return this._subscribingPromise;
144
+ }
145
+ if (this.isSubscribed) {
146
+ return this;
147
+ }
148
+ const model = this;
149
+ this._subscribingPromise = new Promise((resolve, reject) => {
150
+ this.doc.subscribe((subscribeErr) => {
151
+ model._subscribingPromise = null;
152
+ if (subscribeErr) {
153
+ if (subscribeErr.message == 'forbidden') {
154
+ model._isForbidden = true;
155
+ resolve(model);
156
+ }
157
+ else {
158
+ const message = `error subscribing to Model ${model.compoundKey}: ${subscribeErr}`;
159
+ console.log(message);
160
+ reject(message);
161
+ }
162
+ }
163
+ else {
164
+ model.shareSync.isDebug() && console.log(`subscribed to Model ${model.compoundKey}`);
165
+ resolve(model);
166
+ }
167
+ });
168
+ });
169
+ return this._subscribingPromise;
170
+ }
171
+ async unsubscribe() {
172
+ this.log(`UNSUBSCRIBE: (${this.compoundKey})`);
173
+ if (this._subscribingPromise != null) {
174
+ await this._subscribingPromise;
175
+ }
176
+ if (!this.isSubscribed) {
177
+ return this;
178
+ }
179
+ const model = this;
180
+ return new Promise((resolve, reject) => {
181
+ this.doc.unsubscribe((unsubscribeErr) => {
182
+ if (unsubscribeErr) {
183
+ const message = `error unsubscribing from Model ${model.compoundKey}: ${unsubscribeErr}`;
184
+ console.log(message);
185
+ reject(message);
186
+ }
187
+ else {
188
+ model.shareSync.isDebug() && console.log(`subscribed to Model ${model.compoundKey}`);
189
+ resolve(model);
190
+ }
191
+ });
192
+ });
193
+ }
194
+ isDisposed() {
195
+ return this._isDisposed;
196
+ }
197
+ checkDisposed(source) {
198
+ if (this._isDisposed) {
199
+ console.error(`*** MODEL ALREDY DISPOSED: (${this.compoundKey}); source = ${source}`);
200
+ }
201
+ }
202
+ async ensureData() {
203
+ const model = this;
204
+ return new Promise((resolve, reject) => {
205
+ this.doc.ensureDocHasData((ensureErr) => {
206
+ if (ensureErr) {
207
+ if (ensureErr.message == 'forbidden') {
208
+ model._isForbidden = true;
209
+ resolve(model);
210
+ }
211
+ else {
212
+ const message = `error ensuring doc has data in Model ${model.compoundKey}: ${ensureErr}`;
213
+ console.log(message);
214
+ reject(message);
215
+ }
216
+ }
217
+ else {
218
+ model.shareSync.isDebug() && console.log(`ensured doc has data for Model ${model.compoundKey}`);
219
+ resolve(model);
220
+ }
221
+ });
222
+ });
223
+ }
224
+ async ensureRecentData(minVersion) {
225
+ const model = this;
226
+ return new Promise((resolve, reject) => {
227
+ this.doc.ensureDocHasRecentData(minVersion, (ensureErr) => {
228
+ if (ensureErr) {
229
+ if (ensureErr.message == 'forbidden') {
230
+ model._isForbidden = true;
231
+ resolve(model);
232
+ }
233
+ else {
234
+ const message = `error ensuring doc has recent data in Model ${model.compoundKey} with minVersion ${minVersion}: ${ensureErr}`;
235
+ console.log(message);
236
+ reject(message);
237
+ }
238
+ }
239
+ else {
240
+ model.shareSync.isDebug() && console.log(`ensured doc has recent data for Model ${model.compoundKey} with minVersion ${minVersion}`);
241
+ resolve(model);
242
+ }
243
+ });
244
+ });
245
+ }
246
+ doesUserHavePermission(userId, type) {
247
+ this.checkDisposed("Model.doesUserHavePermission");
248
+ if (this.kind === ContentKind_1.ContentKind.MANIFEST) {
249
+ return Model.doesUserHaveManifestPermission(this.doc.data, userId, type);
250
+ }
251
+ else {
252
+ // Content objects and checkpoints all have a PermissionsMeta
253
+ const meta = this.doc.data.meta;
254
+ return Model.doesUserHaveContentPermission(this.kind, meta, userId, type);
255
+ }
256
+ }
257
+ static doesUserHaveManifestPermission(data, userId, type) {
258
+ return data.meta.owner === userId;
259
+ }
260
+ static doesUserHaveContentPermission(kind, meta, userId, type) {
261
+ // Users are allowed to read any of their own content, but they are not allowed to write their User or Billing objects.
262
+ if (meta.owner === userId) {
263
+ if (type === Permissions_1.PermissionType.READ) {
264
+ return true;
265
+ }
266
+ else if (type === Permissions_1.PermissionType.WRITE) {
267
+ return kind !== ContentKind_1.ContentKind.USER && kind !== ContentKind_1.ContentKind.BILLING;
268
+ }
269
+ }
270
+ // If all else fails, deny permission.
271
+ return false;
272
+ }
273
+ log(message) {
274
+ if (this.shareSync.isDebug()) {
275
+ console.log(message);
276
+ }
277
+ }
278
+ }
279
+ exports.Model = Model;
280
+ Model.CHANGED = "MODEL_CHANGED";
@@ -0,0 +1,7 @@
1
+ export declare enum PermissionType {
2
+ READ = 0,
3
+ WRITE = 1
4
+ }
5
+ export declare class PermissionModel {
6
+ static shouldAllow(grantedPermission: PermissionType, necessaryPermission: PermissionType): boolean;
7
+ }
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PermissionModel = exports.PermissionType = void 0;
4
+ var PermissionType;
5
+ (function (PermissionType) {
6
+ PermissionType[PermissionType["READ"] = 0] = "READ";
7
+ PermissionType[PermissionType["WRITE"] = 1] = "WRITE";
8
+ })(PermissionType || (exports.PermissionType = PermissionType = {}));
9
+ class PermissionModel {
10
+ static shouldAllow(grantedPermission, necessaryPermission) {
11
+ if (grantedPermission == necessaryPermission) {
12
+ return true;
13
+ }
14
+ else if (grantedPermission == PermissionType.WRITE && necessaryPermission == PermissionType.READ) {
15
+ return true;
16
+ }
17
+ return false;
18
+ }
19
+ }
20
+ exports.PermissionModel = PermissionModel;
@@ -0,0 +1,8 @@
1
+ import { ContentBody, ContentMeta } from "./Content";
2
+ import { Definable, DictionaryEntry, Pronouncable } from "./DictionaryEntry";
3
+ export interface PhrasePayload extends DictionaryEntry, Pronouncable, Definable {
4
+ }
5
+ export interface PhraseBody extends ContentBody {
6
+ meta: ContentMeta;
7
+ payload: PhrasePayload;
8
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,8 @@
1
+ import { Content } from './Content';
2
+ import { Stub } from './Stub';
3
+ export declare class Placeholder {
4
+ static readonly PREFIX = "untitled";
5
+ static forCategory(name: string): string;
6
+ static forContent(content: Content): string;
7
+ static forStub(stub: Stub): string;
8
+ }
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Placeholder = void 0;
4
+ const Text_1 = require("../../util/Text");
5
+ const Book_1 = require("./Book");
6
+ const ContentKind_1 = require("./ContentKind");
7
+ const Fragment_1 = require("./Fragment");
8
+ class Placeholder {
9
+ static forCategory(name) {
10
+ let placeholder = "untitled ";
11
+ if (typeof (name) !== "undefined") { // TODO: does anyone call this without an arg?
12
+ placeholder += name.trim();
13
+ }
14
+ return Text_1.Text.capitalizeWords(placeholder.trim());
15
+ }
16
+ static forContent(content) {
17
+ if (content instanceof Book_1.Book) {
18
+ return Placeholder.forCategory(ContentKind_1.ContentKind.BOOK);
19
+ }
20
+ else if (content instanceof Fragment_1.Fragment) {
21
+ return Placeholder.forCategory(content.category);
22
+ }
23
+ return Text_1.Text.capitalizeWords(content.kind);
24
+ }
25
+ static forStub(stub) {
26
+ if (stub.kind === ContentKind_1.ContentKind.BOOK) {
27
+ return Placeholder.forCategory(ContentKind_1.ContentKind.BOOK);
28
+ }
29
+ else if (stub.kind === ContentKind_1.ContentKind.FRAGMENT) {
30
+ return Placeholder.forCategory(stub.category);
31
+ }
32
+ return Text_1.Text.capitalizeWords(stub.kind);
33
+ }
34
+ }
35
+ exports.Placeholder = Placeholder;
36
+ Placeholder.PREFIX = 'untitled';
@@ -0,0 +1,30 @@
1
+ /// <reference path="../../../decs.d.ts" />
2
+ import { Doc } from '@shaxpir/sharedb/lib/client';
3
+ import { ShareSync } from '../../repo/ShareSync';
4
+ import { Content, ContentBody, ContentId, ContentMeta } from "./Content";
5
+ import { MediaCropping } from './Media';
6
+ export interface ProfilePayload {
7
+ username: string;
8
+ full_name: string;
9
+ avatar_media_ref: ContentId;
10
+ avatar_cropping: MediaCropping;
11
+ }
12
+ export interface ProfileBody extends ContentBody {
13
+ meta: ContentMeta;
14
+ payload: ProfilePayload;
15
+ }
16
+ export declare class Profile extends Content {
17
+ static makeProfileId(userId: ContentId): ContentId;
18
+ static create(userId: ContentId): Profile;
19
+ constructor(doc: Doc, shouldAcquire: boolean, shareSync: ShareSync);
20
+ get payload(): ProfilePayload;
21
+ get username(): string;
22
+ setUsername(value: string): void;
23
+ get fullName(): string;
24
+ setFullName(value: string): void;
25
+ get avatarMediaRef(): ContentId;
26
+ setAvatarMediaRef(value: ContentId): void;
27
+ get avatarCropping(): MediaCropping;
28
+ setAvatarCropping(value: MediaCropping): void;
29
+ static findByUsername(username: string): Promise<Profile[]>;
30
+ }