@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.
- package/README.md +1 -0
- package/decs.d.ts +87 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +20 -0
- package/dist/models/OutboundMessage.d.ts +18 -0
- package/dist/models/OutboundMessage.js +25 -0
- package/dist/models/content/Activity.d.ts +10 -0
- package/dist/models/content/Activity.js +2 -0
- package/dist/models/content/ArrayView.d.ts +26 -0
- package/dist/models/content/ArrayView.js +174 -0
- package/dist/models/content/Billing.d.ts +144 -0
- package/dist/models/content/Billing.js +418 -0
- package/dist/models/content/Book.d.ts +77 -0
- package/dist/models/content/Book.js +407 -0
- package/dist/models/content/Category.d.ts +16 -0
- package/dist/models/content/Category.js +20 -0
- package/dist/models/content/Checkpointable.d.ts +21 -0
- package/dist/models/content/Checkpointable.js +156 -0
- package/dist/models/content/Comment.d.ts +19 -0
- package/dist/models/content/Comment.js +53 -0
- package/dist/models/content/ConceptArt.d.ts +31 -0
- package/dist/models/content/ConceptArt.js +84 -0
- package/dist/models/content/Content.d.ts +52 -0
- package/dist/models/content/Content.js +61 -0
- package/dist/models/content/ContentKind.d.ts +10 -0
- package/dist/models/content/ContentKind.js +16 -0
- package/dist/models/content/Context.d.ts +28 -0
- package/dist/models/content/Context.js +162 -0
- package/dist/models/content/DevEnv.d.ts +5 -0
- package/dist/models/content/DevEnv.js +9 -0
- package/dist/models/content/Device.d.ts +24 -0
- package/dist/models/content/Device.js +62 -0
- package/dist/models/content/Dictionary.d.ts +31 -0
- package/dist/models/content/Dictionary.js +5 -0
- package/dist/models/content/DictionaryEntry.d.ts +20 -0
- package/dist/models/content/DictionaryEntry.js +2 -0
- package/dist/models/content/ElasticModel.d.ts +149 -0
- package/dist/models/content/ElasticModel.js +179 -0
- package/dist/models/content/Environment.d.ts +61 -0
- package/dist/models/content/Environment.js +124 -0
- package/dist/models/content/ExportOptions.d.ts +64 -0
- package/dist/models/content/ExportOptions.js +213 -0
- package/dist/models/content/Folder.d.ts +16 -0
- package/dist/models/content/Folder.js +33 -0
- package/dist/models/content/Fragment.d.ts +54 -0
- package/dist/models/content/Fragment.js +181 -0
- package/dist/models/content/GeoLocation.d.ts +4 -0
- package/dist/models/content/GeoLocation.js +2 -0
- package/dist/models/content/Hanzi.d.ts +21 -0
- package/dist/models/content/Hanzi.js +2 -0
- package/dist/models/content/HighlightRule.d.ts +9 -0
- package/dist/models/content/HighlightRule.js +2 -0
- package/dist/models/content/Manifest.d.ts +42 -0
- package/dist/models/content/Manifest.js +114 -0
- package/dist/models/content/Media.d.ts +32 -0
- package/dist/models/content/Media.js +98 -0
- package/dist/models/content/Metric.d.ts +46 -0
- package/dist/models/content/Metric.js +183 -0
- package/dist/models/content/Migration.d.ts +68 -0
- package/dist/models/content/Migration.js +155 -0
- package/dist/models/content/Model.d.ts +45 -0
- package/dist/models/content/Model.js +280 -0
- package/dist/models/content/Permissions.d.ts +7 -0
- package/dist/models/content/Permissions.js +20 -0
- package/dist/models/content/Phrase.d.ts +8 -0
- package/dist/models/content/Phrase.js +2 -0
- package/dist/models/content/Placeholder.d.ts +8 -0
- package/dist/models/content/Placeholder.js +36 -0
- package/dist/models/content/Profile.d.ts +30 -0
- package/dist/models/content/Profile.js +95 -0
- package/dist/models/content/RichText.d.ts +58 -0
- package/dist/models/content/RichText.js +79 -0
- package/dist/models/content/Session.d.ts +39 -0
- package/dist/models/content/Session.js +173 -0
- package/dist/models/content/Speech.d.ts +67 -0
- package/dist/models/content/Speech.js +97 -0
- package/dist/models/content/Stub.d.ts +24 -0
- package/dist/models/content/Stub.js +179 -0
- package/dist/models/content/Time.d.ts +56 -0
- package/dist/models/content/Time.js +295 -0
- package/dist/models/content/User.d.ts +36 -0
- package/dist/models/content/User.js +95 -0
- package/dist/models/content/Workspace.d.ts +71 -0
- package/dist/models/content/Workspace.js +237 -0
- package/dist/models/content/index.d.ts +36 -0
- package/dist/models/content/index.js +53 -0
- package/dist/models/index.d.ts +4 -0
- package/dist/models/index.js +21 -0
- package/dist/models/legacy/LegacyBodyFormat.d.ts +9 -0
- package/dist/models/legacy/LegacyBodyFormat.js +2 -0
- package/dist/models/legacy/LegacyComment.d.ts +12 -0
- package/dist/models/legacy/LegacyComment.js +2 -0
- package/dist/models/legacy/LegacyContent.d.ts +53 -0
- package/dist/models/legacy/LegacyContent.js +55 -0
- package/dist/models/legacy/LegacyConversion.d.ts +55 -0
- package/dist/models/legacy/LegacyConversion.js +401 -0
- package/dist/models/legacy/LegacyFragment.d.ts +21 -0
- package/dist/models/legacy/LegacyFragment.js +2 -0
- package/dist/models/legacy/LegacyLocator.d.ts +8 -0
- package/dist/models/legacy/LegacyLocator.js +31 -0
- package/dist/models/legacy/LegacyOutboundMessage.d.ts +16 -0
- package/dist/models/legacy/LegacyOutboundMessage.js +13 -0
- package/dist/models/legacy/LegacyPicture.d.ts +14 -0
- package/dist/models/legacy/LegacyPicture.js +2 -0
- package/dist/models/legacy/LegacyProfile.d.ts +9 -0
- package/dist/models/legacy/LegacyProfile.js +2 -0
- package/dist/models/legacy/LegacySession.d.ts +41 -0
- package/dist/models/legacy/LegacySession.js +35 -0
- package/dist/models/legacy/LegacyStory.d.ts +23 -0
- package/dist/models/legacy/LegacyStory.js +2 -0
- package/dist/models/legacy/LegacyStub.d.ts +15 -0
- package/dist/models/legacy/LegacyStub.js +2 -0
- package/dist/models/legacy/LegacyTransaction.d.ts +14 -0
- package/dist/models/legacy/LegacyTransaction.js +49 -0
- package/dist/models/legacy/LegacyUser.d.ts +28 -0
- package/dist/models/legacy/LegacyUser.js +32 -0
- package/dist/models/legacy/LegacyWorkspace.d.ts +23 -0
- package/dist/models/legacy/LegacyWorkspace.js +6 -0
- package/dist/models/legacy/index.d.ts +15 -0
- package/dist/models/legacy/index.js +32 -0
- package/dist/models/markup/BodyFormat.d.ts +14 -0
- package/dist/models/markup/BodyFormat.js +190 -0
- package/dist/models/markup/ChangeModel.d.ts +22 -0
- package/dist/models/markup/ChangeModel.js +107 -0
- package/dist/models/markup/DeltaOps.d.ts +5 -0
- package/dist/models/markup/DeltaOps.js +74 -0
- package/dist/models/markup/HtmlMarkup.d.ts +4 -0
- package/dist/models/markup/HtmlMarkup.js +21 -0
- package/dist/models/markup/Operation.d.ts +32 -0
- package/dist/models/markup/Operation.js +194 -0
- package/dist/models/markup/TextEditOps.d.ts +9 -0
- package/dist/models/markup/TextEditOps.js +50 -0
- package/dist/models/markup/index.d.ts +6 -0
- package/dist/models/markup/index.js +23 -0
- package/dist/repo/ConnectionListener.d.ts +9 -0
- package/dist/repo/ConnectionListener.js +21 -0
- package/dist/repo/PermissiveJson1.d.ts +58 -0
- package/dist/repo/PermissiveJson1.js +39 -0
- package/dist/repo/ShareSync.d.ts +60 -0
- package/dist/repo/ShareSync.js +348 -0
- package/dist/repo/index.d.ts +3 -0
- package/dist/repo/index.js +20 -0
- package/dist/util/Async.d.ts +8 -0
- package/dist/util/Async.js +18 -0
- package/dist/util/Base62.d.ts +6 -0
- package/dist/util/Base62.js +47 -0
- package/dist/util/BinarySearch.d.ts +7 -0
- package/dist/util/BinarySearch.js +46 -0
- package/dist/util/CachingHasher.d.ts +8 -0
- package/dist/util/CachingHasher.js +41 -0
- package/dist/util/Color.d.ts +32 -0
- package/dist/util/Color.js +204 -0
- package/dist/util/Dispatch.d.ts +15 -0
- package/dist/util/Dispatch.js +79 -0
- package/dist/util/EditDistance.d.ts +13 -0
- package/dist/util/EditDistance.js +184 -0
- package/dist/util/Encryption.d.ts +5 -0
- package/dist/util/Encryption.js +2 -0
- package/dist/util/Logging.d.ts +108 -0
- package/dist/util/Logging.js +412 -0
- package/dist/util/NumberFormat.d.ts +14 -0
- package/dist/util/NumberFormat.js +224 -0
- package/dist/util/Struct.d.ts +4 -0
- package/dist/util/Struct.js +15 -0
- package/dist/util/Template.d.ts +16 -0
- package/dist/util/Template.js +128 -0
- package/dist/util/Text.d.ts +45 -0
- package/dist/util/Text.js +243 -0
- package/dist/util/Tuples.d.ts +9 -0
- package/dist/util/Tuples.js +135 -0
- package/dist/util/Validate.d.ts +4 -0
- package/dist/util/Validate.js +11 -0
- package/dist/util/Vocabulary.d.ts +3 -0
- package/dist/util/Vocabulary.js +35 -0
- package/dist/util/index.d.ts +16 -0
- package/dist/util/index.js +33 -0
- package/lib/models/content/ArrayView.ts +203 -0
- package/lib/models/content/Billing.ts +558 -0
- package/lib/models/content/Content.ts +110 -0
- package/lib/models/content/ContentKind.ts +14 -0
- package/lib/models/content/DevEnv.ts +5 -0
- package/lib/models/content/Device.ts +86 -0
- package/lib/models/content/DictionaryEntry.ts +22 -0
- package/lib/models/content/GeoLocation.ts +4 -0
- package/lib/models/content/Hanzi.ts +25 -0
- package/lib/models/content/Manifest.ts +162 -0
- package/lib/models/content/Media.ts +126 -0
- package/lib/models/content/Model.ts +327 -0
- package/lib/models/content/Permissions.ts +21 -0
- package/lib/models/content/Phrase.ts +10 -0
- package/lib/models/content/Profile.ts +119 -0
- package/lib/models/content/Time.ts +328 -0
- package/lib/models/content/User.ts +130 -0
- package/lib/models/markup/ChangeModel.ts +95 -0
- package/lib/models/markup/DeltaOps.ts +71 -0
- package/lib/models/markup/Operation.ts +215 -0
- package/lib/models/markup/TextEditOps.ts +50 -0
- package/lib/repo/ConnectionListener.ts +25 -0
- package/lib/repo/PermissiveJson1.ts +14 -0
- package/lib/repo/ShareSync.ts +390 -0
- package/lib/util/Base62.ts +47 -0
- package/lib/util/CachingHasher.ts +38 -0
- package/lib/util/Dispatch.ts +92 -0
- package/lib/util/Encryption.ts +5 -0
- package/lib/util/Logging.ts +568 -0
- package/lib/util/NumberFormat.ts +194 -0
- package/lib/util/Struct.ts +14 -0
- package/lib/util/Tuples.ts +131 -0
- package/package.json +41 -0
- package/tsconfig.json +25 -0
- package/tslint.json +46 -0
|
@@ -0,0 +1,401 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.LegacyConversion = void 0;
|
|
7
|
+
const dayjs_1 = __importDefault(require("dayjs"));
|
|
8
|
+
const utc_1 = __importDefault(require("dayjs/plugin/utc"));
|
|
9
|
+
dayjs_1.default.extend(utc_1.default);
|
|
10
|
+
const Struct_1 = require("../../util/Struct");
|
|
11
|
+
const content_1 = require("../content");
|
|
12
|
+
const ConceptArt_1 = require("../content/ConceptArt");
|
|
13
|
+
const Content_1 = require("../content/Content");
|
|
14
|
+
const ContentKind_1 = require("../content/ContentKind");
|
|
15
|
+
const Environment_1 = require("../content/Environment");
|
|
16
|
+
const Profile_1 = require("../content/Profile");
|
|
17
|
+
const RichText_1 = require("../content/RichText");
|
|
18
|
+
const Session_1 = require("../content/Session");
|
|
19
|
+
const Time_1 = require("../content/Time");
|
|
20
|
+
const Workspace_1 = require("../content/Workspace");
|
|
21
|
+
const BodyFormat_1 = require("../markup/BodyFormat");
|
|
22
|
+
const LegacyContent_1 = require("./LegacyContent");
|
|
23
|
+
const LegacyLocator_1 = require("./LegacyLocator");
|
|
24
|
+
class LegacyConversion {
|
|
25
|
+
constructor(userId) {
|
|
26
|
+
this.userId = userId;
|
|
27
|
+
}
|
|
28
|
+
static convertDateTime(timestamp) {
|
|
29
|
+
return dayjs_1.default.utc(timestamp, Time_1.Time.DATETIME_FORMAT_LEGACY).format(Time_1.Time.DATETIME_FORMAT_COMPACT);
|
|
30
|
+
}
|
|
31
|
+
static convertOutboundMessage(message) {
|
|
32
|
+
let converted = Struct_1.Struct.clone(message);
|
|
33
|
+
converted.at_utc_time = LegacyConversion.convertDateTime(converted.at_utc_time);
|
|
34
|
+
return converted;
|
|
35
|
+
}
|
|
36
|
+
convertKind(legacyKind) {
|
|
37
|
+
if (legacyKind === LegacyContent_1.LegacyContentKind.STORY) {
|
|
38
|
+
return ContentKind_1.ContentKind.BOOK;
|
|
39
|
+
}
|
|
40
|
+
else if (legacyKind === LegacyContent_1.LegacyContentKind.PICTURE) {
|
|
41
|
+
return ContentKind_1.ContentKind.CONCEPT_ART;
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
return legacyKind;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
convertId(record) {
|
|
48
|
+
let id = record.id;
|
|
49
|
+
if (record.kind === LegacyContent_1.LegacyContentKind.SESSION) {
|
|
50
|
+
id = Session_1.Session.makeSessionId(this.userId);
|
|
51
|
+
}
|
|
52
|
+
else if (record.kind === LegacyContent_1.LegacyContentKind.WORKSPACE) {
|
|
53
|
+
id = Workspace_1.Workspace.makeWorkspaceId(this.userId);
|
|
54
|
+
}
|
|
55
|
+
else if (record.kind === LegacyContent_1.LegacyContentKind.PROFILE) {
|
|
56
|
+
id = Profile_1.Profile.makeProfileId(this.userId);
|
|
57
|
+
}
|
|
58
|
+
return id;
|
|
59
|
+
}
|
|
60
|
+
convertMeta(legacyRecord, createdAt, isHead) {
|
|
61
|
+
let convertedId = this.convertId(legacyRecord);
|
|
62
|
+
let kind = this.convertKind(legacyRecord.kind);
|
|
63
|
+
let updatedAt = this.convertMetaAt(legacyRecord);
|
|
64
|
+
let ref = isHead ? convertedId : Content_1.Content.makeContentRef(convertedId, createdAt.utc_time);
|
|
65
|
+
let meta = {
|
|
66
|
+
ref: ref,
|
|
67
|
+
is_head: isHead,
|
|
68
|
+
kind: kind,
|
|
69
|
+
id: convertedId,
|
|
70
|
+
created_at: createdAt,
|
|
71
|
+
updated_at: updatedAt,
|
|
72
|
+
owner: this.userId
|
|
73
|
+
};
|
|
74
|
+
if (isHead) {
|
|
75
|
+
meta.checkpoints = [];
|
|
76
|
+
}
|
|
77
|
+
return meta;
|
|
78
|
+
}
|
|
79
|
+
convertMetaAt(legacyRecord) {
|
|
80
|
+
let extraMillis = 0;
|
|
81
|
+
if (legacyRecord.kind == LegacyContent_1.LegacyContentKind.SESSION) {
|
|
82
|
+
// Handle some corrupt legacy data where there are multiple sessions with identical
|
|
83
|
+
// start timestamps by adding the sequence-number of the session to the start time
|
|
84
|
+
// in milliseconds. This should give us unique session IDs.
|
|
85
|
+
extraMillis = legacyRecord.seq;
|
|
86
|
+
}
|
|
87
|
+
return this.convertMultiTime(legacyRecord.at, extraMillis);
|
|
88
|
+
}
|
|
89
|
+
convertMultiTime(at, extraMillis) {
|
|
90
|
+
let atUtcTime = LegacyConversion.convertDateTime(at.utc_time);
|
|
91
|
+
let atLocalTime = LegacyConversion.convertDateTime(at.local_time);
|
|
92
|
+
if (extraMillis != 0) {
|
|
93
|
+
// Handle some corrupt legacy data where there are multiple sessions with identical
|
|
94
|
+
// start timestamps by adding the sequence-number of the session to the start time
|
|
95
|
+
// in milliseconds. This should give us unique session IDs.
|
|
96
|
+
atUtcTime = Time_1.Time.plus(atUtcTime, extraMillis, 'milliseconds');
|
|
97
|
+
atLocalTime = Time_1.Time.plus(atLocalTime, extraMillis, 'milliseconds');
|
|
98
|
+
}
|
|
99
|
+
return {
|
|
100
|
+
utc_time: atUtcTime,
|
|
101
|
+
local_time: atLocalTime
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
convertLegacyPayload(legacyRecord) {
|
|
105
|
+
return Struct_1.Struct.clone(legacyRecord.payload);
|
|
106
|
+
}
|
|
107
|
+
convertRichTextPayload(legacyBodyFormat) {
|
|
108
|
+
let converted = this.convertLegacyPayload(legacyBodyFormat);
|
|
109
|
+
converted.richtext_flavor = RichText_1.RichTextFlavor.quill;
|
|
110
|
+
converted.richtext_body = { ops: BodyFormat_1.BodyFormatModel.toDeltaOps(legacyBodyFormat.payload) };
|
|
111
|
+
delete converted.body;
|
|
112
|
+
delete converted.format;
|
|
113
|
+
return converted;
|
|
114
|
+
}
|
|
115
|
+
convertUser(legacyUser) {
|
|
116
|
+
let userId = legacyUser.id;
|
|
117
|
+
return {
|
|
118
|
+
email: legacyUser.payload.email,
|
|
119
|
+
force_password_reset: legacyUser.payload.force_password_reset,
|
|
120
|
+
pass_md5_salt_md5: legacyUser.payload.pass_md5_salt_md5,
|
|
121
|
+
salt: legacyUser.payload.salt,
|
|
122
|
+
profile_id: Profile_1.Profile.makeProfileId(userId),
|
|
123
|
+
session_id: Session_1.Session.makeSessionId(userId),
|
|
124
|
+
workspace_id: Workspace_1.Workspace.makeWorkspaceId(userId)
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
convertBilling(legacyUser, convertedTransactions) {
|
|
128
|
+
return {
|
|
129
|
+
plan: legacyUser.payload.plan,
|
|
130
|
+
paid_until: LegacyConversion.convertDateTime(legacyUser.payload.paid_until),
|
|
131
|
+
payment_status: legacyUser.payload.payment_status,
|
|
132
|
+
stripe_customer_id: legacyUser.payload.stripe_customer_id,
|
|
133
|
+
credit_card: legacyUser.payload.credit_card,
|
|
134
|
+
transactions: convertedTransactions
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
convertProfile(legacyProfile, createdAt, legacyAvatar) {
|
|
138
|
+
let payload = this.convertLegacyPayload(legacyProfile);
|
|
139
|
+
payload.username = null;
|
|
140
|
+
payload.avatar_media_ref = legacyProfile.payload.avatar;
|
|
141
|
+
payload.avatar_cropping = null;
|
|
142
|
+
if (legacyAvatar && legacyAvatar.payload.cropping) {
|
|
143
|
+
payload.avatar_cropping = Struct_1.Struct.clone(legacyAvatar.payload.cropping);
|
|
144
|
+
}
|
|
145
|
+
delete payload.avatar;
|
|
146
|
+
return {
|
|
147
|
+
meta: this.convertMeta(legacyProfile, createdAt, true),
|
|
148
|
+
payload: payload
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
convertWorkspace(legacyWorkspace, createdAt, newSessionTimetsamps, contentHeadStubsById) {
|
|
152
|
+
if (legacyWorkspace.payload.hasOwnProperty("stories")) {
|
|
153
|
+
legacyWorkspace.payload.books = Struct_1.Struct.clone(legacyWorkspace.payload.stories);
|
|
154
|
+
delete legacyWorkspace.stories;
|
|
155
|
+
}
|
|
156
|
+
let payload = this.convertLegacyPayload(legacyWorkspace);
|
|
157
|
+
payload.books = this.convertStubArray(contentHeadStubsById, legacyWorkspace.payload.books);
|
|
158
|
+
payload.shorts = this.convertStubArray(contentHeadStubsById, legacyWorkspace.payload.shorts);
|
|
159
|
+
payload.articles = this.convertStubArray(contentHeadStubsById, legacyWorkspace.payload.articles);
|
|
160
|
+
payload.poems = this.convertStubArray(contentHeadStubsById, legacyWorkspace.payload.poems);
|
|
161
|
+
payload.ideas = this.convertStubArray(contentHeadStubsById, legacyWorkspace.payload.ideas);
|
|
162
|
+
payload.trash = this.convertStubArray(contentHeadStubsById, legacyWorkspace.payload.trash);
|
|
163
|
+
payload.devices = [];
|
|
164
|
+
payload.sessions = Time_1.Time.sortByUtcTime(Struct_1.Struct.clone(newSessionTimetsamps));
|
|
165
|
+
// UX and HighlightRules have been moved to Device models.
|
|
166
|
+
delete payload.ux;
|
|
167
|
+
delete payload.highlight;
|
|
168
|
+
// Primary device settings will be updated directly, during migration.
|
|
169
|
+
delete payload.primary_device;
|
|
170
|
+
delete payload.primary_device_last_update;
|
|
171
|
+
return {
|
|
172
|
+
meta: this.convertMeta(legacyWorkspace, createdAt, true),
|
|
173
|
+
payload: payload
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
convertSession(legacySession, checkpointTable) {
|
|
177
|
+
let payload = this.convertLegacyPayload(legacySession);
|
|
178
|
+
payload.activity = this.convertActivityArray(legacySession.payload.activity, checkpointTable);
|
|
179
|
+
payload.start = this.convertMultiTime(legacySession.payload.start, legacySession.seq);
|
|
180
|
+
payload.end = this.convertMultiTime(legacySession.at, legacySession.seq);
|
|
181
|
+
let meta = this.convertMeta(legacySession, payload.start, false);
|
|
182
|
+
// Move session duration from 'minutes_of.total' to 'duration_minutes', and rewrite null values as zeros.
|
|
183
|
+
payload.duration_minutes = legacySession.payload.minutes_of.total;
|
|
184
|
+
if (payload.duration_minutes == null) {
|
|
185
|
+
payload.duration_minutes = 0;
|
|
186
|
+
}
|
|
187
|
+
delete payload.minutes_of;
|
|
188
|
+
// Move device ID from 'environment.device_id' to 'device_id'
|
|
189
|
+
payload.device_id = legacySession.payload.environment.device_id;
|
|
190
|
+
delete payload.environment.device_id;
|
|
191
|
+
// Fixup missing operating-system version names for Mac OS
|
|
192
|
+
payload.environment.versions.os_version = Environment_1.EnvironmentModel.getOsVersion(payload.environment.versions.os_type, payload.environment.versions.os_release);
|
|
193
|
+
// Fixup missing 'shaxpir_bundle' version property
|
|
194
|
+
payload.environment.versions.shaxpir_bundle = payload.environment.versions.shaxpir;
|
|
195
|
+
payload.environment.versions.is_bundle_update = false;
|
|
196
|
+
return {
|
|
197
|
+
meta: meta,
|
|
198
|
+
payload: payload
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
convertTransactionPayload(legacyTransaction) {
|
|
202
|
+
let converted = Struct_1.Struct.clone(legacyTransaction.payload);
|
|
203
|
+
converted.at_utc_time = LegacyConversion.convertDateTime(legacyTransaction.at.utc_time);
|
|
204
|
+
if (converted.hasOwnProperty("details") && Object.keys(converted.details).length === 0) {
|
|
205
|
+
delete converted.details;
|
|
206
|
+
}
|
|
207
|
+
if (converted.details && converted.details.period) {
|
|
208
|
+
converted.details.period.start = LegacyConversion.convertDateTime(converted.details.period.start);
|
|
209
|
+
converted.details.period.end = LegacyConversion.convertDateTime(converted.details.period.end);
|
|
210
|
+
}
|
|
211
|
+
return converted;
|
|
212
|
+
}
|
|
213
|
+
convertBook(legacyStory, createdAt, contentHeadStubsById) {
|
|
214
|
+
let payload = this.convertLegacyPayload(legacyStory);
|
|
215
|
+
// Some very old book objects might be missing these properties
|
|
216
|
+
if (legacyStory.payload.hasOwnProperty("cover_art_id")) {
|
|
217
|
+
payload.cover_media_ref = legacyStory.payload.cover_art_id;
|
|
218
|
+
delete payload.cover_art_id;
|
|
219
|
+
}
|
|
220
|
+
else {
|
|
221
|
+
payload.cover_media_ref = null;
|
|
222
|
+
}
|
|
223
|
+
if (payload.hasOwnProperty("synopsis_id")) {
|
|
224
|
+
payload.synopsis_ref = payload.synopsis_id;
|
|
225
|
+
delete payload.synopsis_id;
|
|
226
|
+
}
|
|
227
|
+
else {
|
|
228
|
+
payload.synopsis_ref = null; // TODO: we need to create a fragment!
|
|
229
|
+
}
|
|
230
|
+
payload.manuscript = this.convertStubArray(contentHeadStubsById, legacyStory.payload.manuscript);
|
|
231
|
+
payload.notebook = this.convertStubArray(contentHeadStubsById, legacyStory.payload.notebook);
|
|
232
|
+
payload.trash = this.convertStubArray(contentHeadStubsById, legacyStory.payload.trash);
|
|
233
|
+
if (!payload.hasOwnProperty("export_options")) {
|
|
234
|
+
payload.export_options = content_1.ExportOptionsModel.build(payload);
|
|
235
|
+
}
|
|
236
|
+
return {
|
|
237
|
+
meta: this.convertMeta(legacyStory, createdAt, true),
|
|
238
|
+
payload: payload
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
convertCheckpoints(legacyCheckpoints) {
|
|
242
|
+
// Create the checkpoint bodies
|
|
243
|
+
let checkpoints = [];
|
|
244
|
+
for (let i = 0; i < legacyCheckpoints.length; i++) {
|
|
245
|
+
let legacyCheckpoint = legacyCheckpoints[i];
|
|
246
|
+
// Checkpoints have the same timestamp for createdAt and updatedAt
|
|
247
|
+
let createdAt = this.convertMetaAt(legacyCheckpoint);
|
|
248
|
+
let kind = this.convertKind(legacyCheckpoint.kind);
|
|
249
|
+
let converted;
|
|
250
|
+
if (kind === ContentKind_1.ContentKind.FRAGMENT) {
|
|
251
|
+
converted = this.convertFragment(legacyCheckpoint, createdAt, false);
|
|
252
|
+
}
|
|
253
|
+
else if (kind === ContentKind_1.ContentKind.COMMENT) {
|
|
254
|
+
converted = this.convertComment(legacyCheckpoint, createdAt, false);
|
|
255
|
+
}
|
|
256
|
+
else if (kind === ContentKind_1.ContentKind.CONCEPT_ART) {
|
|
257
|
+
converted = this.convertPictureToConceptArt(legacyCheckpoint, createdAt, false);
|
|
258
|
+
}
|
|
259
|
+
checkpoints.push(converted);
|
|
260
|
+
}
|
|
261
|
+
return checkpoints;
|
|
262
|
+
}
|
|
263
|
+
convertFragment(legacyFragment, createdAt, isHead) {
|
|
264
|
+
let payload = this.convertRichTextPayload(legacyFragment);
|
|
265
|
+
payload.book_ids = this.convertArrayOfLocators(legacyFragment.payload.stories);
|
|
266
|
+
payload.gallery = this.convertArrayOfLocators(legacyFragment.payload.pictures);
|
|
267
|
+
delete payload.stories;
|
|
268
|
+
delete payload.pictures;
|
|
269
|
+
delete payload.comments;
|
|
270
|
+
// The IDs in the LegacyFragment were "picture" IDs, and "Picture" objects contained the data now split between
|
|
271
|
+
// Media and ConceptArt objects. So now we need to generate "ConceptArt" IDs to go into this list. Media IDs are
|
|
272
|
+
// the same as the Picture IDs from whence they sprung, but ConceptArt IDs are derived from Media IDs.
|
|
273
|
+
for (let i = 0; i < payload.gallery.length; i++) {
|
|
274
|
+
const mediaId = payload.gallery[i];
|
|
275
|
+
payload.gallery[i] = ConceptArt_1.ConceptArt.makeConceptArtIdForMedia(mediaId);
|
|
276
|
+
}
|
|
277
|
+
// Connections have been updated to use refs instead of locators
|
|
278
|
+
let connections = [];
|
|
279
|
+
for (let i = 0; i < legacyFragment.payload.connections.length; i++) {
|
|
280
|
+
let section = legacyFragment.payload.connections[i];
|
|
281
|
+
connections.push({
|
|
282
|
+
label: section.label,
|
|
283
|
+
refs: this.convertArrayOfLocators(section.locators)
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
payload.connections = connections;
|
|
287
|
+
payload.robot_lock = null;
|
|
288
|
+
return {
|
|
289
|
+
meta: this.convertMeta(legacyFragment, createdAt, isHead),
|
|
290
|
+
payload: payload
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
convertPictureToMedia(legacyPicture, createdAt) {
|
|
294
|
+
// Convert the payload
|
|
295
|
+
let mediaPayload = Struct_1.Struct.clone(legacyPicture.payload);
|
|
296
|
+
delete mediaPayload.name;
|
|
297
|
+
delete mediaPayload.body;
|
|
298
|
+
delete mediaPayload.format;
|
|
299
|
+
delete mediaPayload.word_count;
|
|
300
|
+
delete mediaPayload.cropping;
|
|
301
|
+
delete mediaPayload.references;
|
|
302
|
+
// Convert the meta
|
|
303
|
+
let meta = this.convertMeta(legacyPicture, createdAt, true);
|
|
304
|
+
meta.kind = ContentKind_1.ContentKind.MEDIA;
|
|
305
|
+
return {
|
|
306
|
+
meta: meta,
|
|
307
|
+
payload: mediaPayload
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
convertPictureToConceptArt(legacyPicture, createdAt, isHead) {
|
|
311
|
+
let payload = this.convertRichTextPayload(legacyPicture);
|
|
312
|
+
payload.media_ref = legacyPicture.id;
|
|
313
|
+
delete payload.extension;
|
|
314
|
+
delete payload.bytes;
|
|
315
|
+
delete payload.width;
|
|
316
|
+
delete payload.height;
|
|
317
|
+
// All LegacyPicture objects have a one-to-one relationship with a pair of modern ConceptArt and Media objects.
|
|
318
|
+
// But that won't necessarily always be the case in the future. Let's use a hash to create a new unique ID, but
|
|
319
|
+
// one that doesn't necessarily invoke its prevenance at a glance. So in the future, we'll be able to generate
|
|
320
|
+
// arbitrary ConceptArt objects without necessarily a one-to-one relationship with a corresponding Media object.
|
|
321
|
+
let meta = this.convertMeta(legacyPicture, createdAt, isHead);
|
|
322
|
+
meta.kind = ContentKind_1.ContentKind.CONCEPT_ART;
|
|
323
|
+
meta.id = ConceptArt_1.ConceptArt.makeConceptArtIdForMedia(meta.id);
|
|
324
|
+
meta.ref = isHead ? meta.id : Content_1.Content.makeContentRef(meta.id, meta.updated_at.utc_time);
|
|
325
|
+
return {
|
|
326
|
+
meta: meta,
|
|
327
|
+
payload: payload
|
|
328
|
+
};
|
|
329
|
+
}
|
|
330
|
+
convertComment(legacyComment, createdAt, isHead) {
|
|
331
|
+
let meta = this.convertMeta(legacyComment, createdAt, isHead);
|
|
332
|
+
let payload = this.convertRichTextPayload(legacyComment);
|
|
333
|
+
payload.anchor = legacyComment.payload.anchor;
|
|
334
|
+
return {
|
|
335
|
+
meta: meta,
|
|
336
|
+
payload: payload
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
convertArrayOfLocators(locators) {
|
|
340
|
+
let contentIds = new Array();
|
|
341
|
+
for (let i = 0; i < locators.length; i++) {
|
|
342
|
+
contentIds[i] = LegacyLocator_1.LegacyLocatorModel.headOf(locators[i]);
|
|
343
|
+
}
|
|
344
|
+
return contentIds;
|
|
345
|
+
}
|
|
346
|
+
convertActivityArray(activity, checkpointTable) {
|
|
347
|
+
let newActivity = [];
|
|
348
|
+
// The new Activity array only cares about fragments, comments, and pictures.
|
|
349
|
+
for (let i = 0, len = activity.length; i < len; i++) {
|
|
350
|
+
let activityEntry = activity[i];
|
|
351
|
+
if (activityEntry.kind === LegacyContent_1.LegacyContentKind.FRAGMENT ||
|
|
352
|
+
activityEntry.kind === LegacyContent_1.LegacyContentKind.COMMENT ||
|
|
353
|
+
activityEntry.kind === LegacyContent_1.LegacyContentKind.PICTURE) {
|
|
354
|
+
let convertedBefore = null;
|
|
355
|
+
if (activityEntry.versions.before != null) {
|
|
356
|
+
convertedBefore = checkpointTable.get(activityEntry.versions.before);
|
|
357
|
+
}
|
|
358
|
+
let convertedAfter = checkpointTable.get(activityEntry.versions.after);
|
|
359
|
+
newActivity.push({
|
|
360
|
+
kind: this.convertKind(activityEntry.kind),
|
|
361
|
+
id: activityEntry.id,
|
|
362
|
+
before: convertedBefore,
|
|
363
|
+
after: convertedAfter,
|
|
364
|
+
word_count: activityEntry.word_count
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
return newActivity;
|
|
369
|
+
}
|
|
370
|
+
convertStubArray(contentHeadStubsById, stubs) {
|
|
371
|
+
let newStubArray = [];
|
|
372
|
+
for (let i = 0, len = stubs.length; i < len; i++) {
|
|
373
|
+
let stub = stubs[i];
|
|
374
|
+
if (typeof (stub) === "string") {
|
|
375
|
+
// If this stub is just a raw string (a rare legacy possibility), replace it with a real stub object.
|
|
376
|
+
let contentId = LegacyLocator_1.LegacyLocatorModel.headOf(stub);
|
|
377
|
+
if (contentHeadStubsById.has(contentId)) {
|
|
378
|
+
newStubArray.push(Struct_1.Struct.clone(contentHeadStubsById.get(contentId)));
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
else if (stub.kind === LegacyContent_1.LegacyContentKind.FOLDER) {
|
|
382
|
+
// If this is a folder stub, just keep it. It doesn't need any changes.
|
|
383
|
+
newStubArray.push(stub);
|
|
384
|
+
}
|
|
385
|
+
else if (stub) {
|
|
386
|
+
// If this is a normal stub, replace it with the canonical version (with name & category included) from the lookup table.
|
|
387
|
+
let contentStub = stub;
|
|
388
|
+
let contentId = LegacyLocator_1.LegacyLocatorModel.headOf(contentStub.locator);
|
|
389
|
+
if (contentHeadStubsById.has(contentId)) {
|
|
390
|
+
let s = Struct_1.Struct.clone(contentHeadStubsById.get(contentId));
|
|
391
|
+
newStubArray.push(s);
|
|
392
|
+
if (contentStub.hasOwnProperty("parent") && contentStub.parent != null) {
|
|
393
|
+
s.parent = LegacyLocator_1.LegacyLocatorModel.headOf(contentStub.parent);
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
return newStubArray;
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
exports.LegacyConversion = LegacyConversion;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Category } from "../content/Category";
|
|
2
|
+
import { LegacyBodyFormat, LegacyBodyFormatPayload } from "./LegacyBodyFormat";
|
|
3
|
+
import { LegacyHeadLocator, LegacyLocator } from "./LegacyLocator";
|
|
4
|
+
export interface LegacyConnection {
|
|
5
|
+
label: string;
|
|
6
|
+
locators: LegacyHeadLocator[];
|
|
7
|
+
}
|
|
8
|
+
export interface LegacyFragmentPayload extends LegacyBodyFormatPayload {
|
|
9
|
+
name: string;
|
|
10
|
+
category: Category;
|
|
11
|
+
stories?: LegacyLocator[];
|
|
12
|
+
books?: LegacyLocator[];
|
|
13
|
+
comments: LegacyLocator[];
|
|
14
|
+
pictures?: LegacyLocator[];
|
|
15
|
+
gallery?: LegacyLocator[];
|
|
16
|
+
connections: LegacyConnection[];
|
|
17
|
+
word_count: number;
|
|
18
|
+
}
|
|
19
|
+
export interface LegacyFragment extends LegacyBodyFormat {
|
|
20
|
+
payload: LegacyFragmentPayload;
|
|
21
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type LegacyHeadLocator = string;
|
|
2
|
+
export type LegacyLocator = string;
|
|
3
|
+
export declare class LegacyLocatorModel {
|
|
4
|
+
static isHead(locator: LegacyLocator): boolean;
|
|
5
|
+
static headOf(locator: LegacyLocator): LegacyHeadLocator;
|
|
6
|
+
static seqOf(locator: LegacyLocator): number;
|
|
7
|
+
static create(id: LegacyHeadLocator, seq?: number): LegacyLocator;
|
|
8
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.LegacyLocatorModel = void 0;
|
|
4
|
+
class LegacyLocatorModel {
|
|
5
|
+
static isHead(locator) {
|
|
6
|
+
let parts = locator.split('-');
|
|
7
|
+
return parts.length === 1;
|
|
8
|
+
}
|
|
9
|
+
static headOf(locator) {
|
|
10
|
+
let parts = locator.split('-');
|
|
11
|
+
return parts[0];
|
|
12
|
+
}
|
|
13
|
+
static seqOf(locator) {
|
|
14
|
+
let parts = locator.split('-');
|
|
15
|
+
if (parts.length > 1) {
|
|
16
|
+
return Number(parts[1]);
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
static create(id, seq) {
|
|
23
|
+
if (typeof (seq) === "number") {
|
|
24
|
+
return id + "-" + seq;
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
return id;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
exports.LegacyLocatorModel = LegacyLocatorModel;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { OutboundChannel, OutboundMessage } from "../OutboundMessage";
|
|
2
|
+
import { LegacyDateTime } from "./LegacyContent";
|
|
3
|
+
export interface LegacyOutboundMessage {
|
|
4
|
+
id: string;
|
|
5
|
+
at_utc_time: LegacyDateTime;
|
|
6
|
+
user_id: string;
|
|
7
|
+
campaign: string;
|
|
8
|
+
channel: OutboundChannel;
|
|
9
|
+
template: string;
|
|
10
|
+
recipient: string;
|
|
11
|
+
dryrun: boolean;
|
|
12
|
+
params: any;
|
|
13
|
+
}
|
|
14
|
+
export declare class LegacyOutboundMessageModel {
|
|
15
|
+
static toLegacy(message: OutboundMessage): LegacyOutboundMessage;
|
|
16
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.LegacyOutboundMessageModel = void 0;
|
|
4
|
+
const Struct_1 = require("../../util/Struct");
|
|
5
|
+
const LegacyContent_1 = require("./LegacyContent");
|
|
6
|
+
class LegacyOutboundMessageModel {
|
|
7
|
+
static toLegacy(message) {
|
|
8
|
+
let legacy = Struct_1.Struct.clone(message);
|
|
9
|
+
legacy.at_utc_time = LegacyContent_1.LegacyClock.fromCompact(message.at_utc_time);
|
|
10
|
+
return legacy;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
exports.LegacyOutboundMessageModel = LegacyOutboundMessageModel;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { MediaCropping, MediaDimensions } from "../content/Media";
|
|
2
|
+
import { LegacyBodyFormat, LegacyBodyFormatPayload } from "./LegacyBodyFormat";
|
|
3
|
+
import { LegacyLocator } from "./LegacyLocator";
|
|
4
|
+
export interface LegacyPicturePayload extends LegacyBodyFormatPayload, MediaDimensions {
|
|
5
|
+
name: string;
|
|
6
|
+
extension: string;
|
|
7
|
+
references: LegacyLocator[];
|
|
8
|
+
bytes: number;
|
|
9
|
+
cropping: MediaCropping;
|
|
10
|
+
word_count: number;
|
|
11
|
+
}
|
|
12
|
+
export interface LegacyPicture extends LegacyBodyFormat {
|
|
13
|
+
payload: LegacyPicturePayload;
|
|
14
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { LegacyContent } from "./LegacyContent";
|
|
2
|
+
import { LegacyHeadLocator } from "./LegacyLocator";
|
|
3
|
+
export interface LegacyProfilePayload {
|
|
4
|
+
full_name: string;
|
|
5
|
+
avatar: LegacyHeadLocator;
|
|
6
|
+
}
|
|
7
|
+
export interface LegacyProfile extends LegacyContent {
|
|
8
|
+
payload: LegacyProfilePayload;
|
|
9
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { ContentId, GeoLocation, Screens, StorageDevice, Versions } from "../content";
|
|
2
|
+
import { LegacyContent, LegacyContentKind, LegacyMultiTime } from "./LegacyContent";
|
|
3
|
+
import { LegacyHeadLocator, LegacyLocator } from "./LegacyLocator";
|
|
4
|
+
export interface LegacyActivityVersions {
|
|
5
|
+
before: LegacyLocator | null;
|
|
6
|
+
after: LegacyLocator;
|
|
7
|
+
}
|
|
8
|
+
export interface LegacyActivity {
|
|
9
|
+
kind: LegacyContentKind;
|
|
10
|
+
id: LegacyHeadLocator;
|
|
11
|
+
versions: LegacyActivityVersions;
|
|
12
|
+
word_count?: number;
|
|
13
|
+
total_word_count?: number;
|
|
14
|
+
}
|
|
15
|
+
export interface MinutesOf {
|
|
16
|
+
total: number;
|
|
17
|
+
}
|
|
18
|
+
export interface LegacySessionPayload {
|
|
19
|
+
start: LegacyMultiTime;
|
|
20
|
+
tz_offset: number;
|
|
21
|
+
minutes_of: MinutesOf;
|
|
22
|
+
environment: LegacyEnvironment;
|
|
23
|
+
word_count: number;
|
|
24
|
+
activity: LegacyActivity[];
|
|
25
|
+
}
|
|
26
|
+
export interface LegacyEnvironment {
|
|
27
|
+
device_id: ContentId;
|
|
28
|
+
versions: Versions;
|
|
29
|
+
memory: number;
|
|
30
|
+
storage: StorageDevice[];
|
|
31
|
+
screens: Screens;
|
|
32
|
+
language: string;
|
|
33
|
+
location: GeoLocation;
|
|
34
|
+
}
|
|
35
|
+
export interface LegacySession extends LegacyContent {
|
|
36
|
+
payload: LegacySessionPayload;
|
|
37
|
+
}
|
|
38
|
+
export declare class LegacyActivityModel {
|
|
39
|
+
static summarize(content: LegacyContent, prev: LegacyContent): LegacyActivity;
|
|
40
|
+
static addMetricsChangeToSummary(summary: LegacyActivity, content: LegacyContent, prev: LegacyContent, metricsName: "word_count" | "total_word_count"): void;
|
|
41
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.LegacyActivityModel = void 0;
|
|
4
|
+
class LegacyActivityModel {
|
|
5
|
+
static summarize(content, prev) {
|
|
6
|
+
// TODO: the activity stream will eventually contain all sorts of interesting
|
|
7
|
+
// stuff about renaming content items, changing map positions, adding and removing
|
|
8
|
+
// pictures, etc. But for now, let's just keep it limited to word-counting.
|
|
9
|
+
// It only makes sense to summarize the change-activity if these two content items have the same ID
|
|
10
|
+
if (prev != null && prev.id !== content.id) {
|
|
11
|
+
throw new Error("can\x27t summarize activity for content with disjunct ids: " + prev.id + ", " + content.id);
|
|
12
|
+
}
|
|
13
|
+
let summary = {
|
|
14
|
+
"kind": content.kind,
|
|
15
|
+
"id": content.id,
|
|
16
|
+
"versions": {
|
|
17
|
+
"before": prev == null ? null : prev.locator,
|
|
18
|
+
"after": content.locator
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
LegacyActivityModel.addMetricsChangeToSummary(summary, content, prev, "word_count");
|
|
22
|
+
LegacyActivityModel.addMetricsChangeToSummary(summary, content, prev, "total_word_count");
|
|
23
|
+
return summary;
|
|
24
|
+
}
|
|
25
|
+
static addMetricsChangeToSummary(summary, content, prev, metricsName) {
|
|
26
|
+
if (content.payload.hasOwnProperty(metricsName)) {
|
|
27
|
+
let wordCountChange = content.payload[metricsName];
|
|
28
|
+
if (prev !== null && prev.payload.hasOwnProperty(metricsName)) {
|
|
29
|
+
wordCountChange -= prev.payload[metricsName];
|
|
30
|
+
}
|
|
31
|
+
summary[metricsName] = wordCountChange;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
exports.LegacyActivityModel = LegacyActivityModel;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { ExportOptions } from "../content/ExportOptions";
|
|
2
|
+
import { LegacyContent } from "./LegacyContent";
|
|
3
|
+
import { LegacyHeadLocator, LegacyLocator } from "./LegacyLocator";
|
|
4
|
+
import { LegacyStub } from "./LegacyStub";
|
|
5
|
+
export interface LegacyStoryPayload {
|
|
6
|
+
name: string;
|
|
7
|
+
subtitle: string;
|
|
8
|
+
synopsis_id: LegacyHeadLocator | null;
|
|
9
|
+
cover_art_id: LegacyHeadLocator | null;
|
|
10
|
+
author: string;
|
|
11
|
+
contributors: LegacyLocator[];
|
|
12
|
+
copyright: string;
|
|
13
|
+
publisher: string;
|
|
14
|
+
isbn: string;
|
|
15
|
+
manuscript: LegacyStub[];
|
|
16
|
+
notebook: LegacyStub[];
|
|
17
|
+
export_options: ExportOptions;
|
|
18
|
+
trash: Array<LegacyStub | LegacyHeadLocator>;
|
|
19
|
+
total_word_count: number;
|
|
20
|
+
}
|
|
21
|
+
export interface LegacyStory extends LegacyContent {
|
|
22
|
+
payload: LegacyStoryPayload;
|
|
23
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { LegacyContentKind } from "./LegacyContent";
|
|
2
|
+
import { LegacyHeadLocator, LegacyLocator } from "./LegacyLocator";
|
|
3
|
+
export interface LegacyStub {
|
|
4
|
+
kind: LegacyContentKind;
|
|
5
|
+
label: string;
|
|
6
|
+
parent?: LegacyHeadLocator;
|
|
7
|
+
children?: LegacyStub[];
|
|
8
|
+
}
|
|
9
|
+
export interface LegacyFolderStub extends LegacyStub {
|
|
10
|
+
id: LegacyHeadLocator;
|
|
11
|
+
}
|
|
12
|
+
export interface LegacyContentStub extends LegacyStub {
|
|
13
|
+
category?: string;
|
|
14
|
+
locator: LegacyLocator;
|
|
15
|
+
}
|