@shaxpir/duiduidui-models 1.0.1 → 1.1.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/dist/models/{content/ArrayView.d.ts → ArrayView.d.ts} +1 -1
- package/dist/models/{content/ArrayView.js → ArrayView.js} +14 -14
- package/dist/models/BayesianScore.d.ts +9 -0
- package/dist/models/BayesianScore.js +27 -0
- package/dist/models/{markup/ChangeModel.d.ts → ChangeModel.d.ts} +2 -3
- package/dist/models/{markup/ChangeModel.js → ChangeModel.js} +20 -10
- package/dist/models/{content/Content.d.ts → Content.d.ts} +9 -10
- package/dist/models/{content/Content.js → Content.js} +2 -6
- package/dist/models/{content/ContentKind.d.ts → ContentKind.d.ts} +3 -0
- package/dist/models/{content/ContentKind.js → ContentKind.js} +5 -1
- package/dist/models/{content/Device.d.ts → Device.d.ts} +15 -7
- package/dist/models/{content/Device.js → Device.js} +14 -18
- package/dist/models/Hanzi.d.ts +15 -0
- package/dist/models/{content/Manifest.d.ts → Manifest.d.ts} +7 -3
- package/dist/models/{content/Manifest.js → Manifest.js} +12 -8
- package/dist/models/{content/Media.d.ts → Media.d.ts} +2 -3
- package/dist/models/{content/Media.js → Media.js} +4 -5
- package/dist/models/{content/Metric.d.ts → Metric.d.ts} +2 -3
- package/dist/models/{content/Metric.js → Metric.js} +18 -20
- package/dist/models/{content/Model.d.ts → Model.d.ts} +3 -5
- package/dist/models/{content/Model.js → Model.js} +5 -6
- package/dist/models/{markup/Operation.d.ts → Operation.d.ts} +2 -5
- package/dist/models/{markup/Operation.js → Operation.js} +30 -25
- package/dist/models/Phrase.d.ts +39 -0
- package/dist/models/{content/Profile.d.ts → Profile.d.ts} +1 -2
- package/dist/models/{content/Profile.js → Profile.js} +7 -9
- package/dist/models/Progress.d.ts +26 -0
- package/dist/models/Progress.js +39 -0
- package/dist/models/Review.d.ts +14 -0
- package/dist/models/{content/Session.d.ts → Session.d.ts} +7 -15
- package/dist/models/Session.js +103 -0
- package/dist/models/Term.d.ts +36 -0
- package/dist/models/Term.js +82 -0
- package/dist/models/User.d.ts +32 -0
- package/dist/models/User.js +65 -0
- package/dist/models/Workspace.d.ts +37 -0
- package/dist/models/Workspace.js +94 -0
- package/dist/models/index.d.ts +22 -2
- package/dist/models/index.js +22 -2
- package/dist/repo/PermissiveJson1.d.ts +16 -16
- package/dist/repo/PermissiveJson1.js +17 -7
- package/dist/repo/ShareSync.d.ts +6 -6
- package/dist/repo/ShareSync.js +26 -19
- package/dist/repo/index.d.ts +1 -0
- package/dist/repo/index.js +1 -0
- package/dist/util/index.d.ts +0 -6
- package/dist/util/index.js +0 -6
- package/lib/models/{content/ArrayView.ts → ArrayView.ts} +2 -2
- package/lib/models/BayesianScore.ts +32 -0
- package/lib/models/{markup/ChangeModel.ts → ChangeModel.ts} +3 -4
- package/lib/models/{content/Content.ts → Content.ts} +15 -18
- package/lib/models/{content/ContentKind.ts → ContentKind.ts} +6 -1
- package/lib/models/{content/Device.ts → Device.ts} +26 -22
- package/lib/models/Hanzi.ts +16 -0
- package/lib/models/{content/Manifest.ts → Manifest.ts} +15 -6
- package/lib/models/{content/Media.ts → Media.ts} +3 -4
- package/lib/models/Metric.ts +233 -0
- package/lib/models/{content/Model.ts → Model.ts} +4 -6
- package/lib/models/{markup/Operation.ts → Operation.ts} +6 -16
- package/lib/models/{content/Permissions.ts → Permissions.ts} +0 -2
- package/lib/models/Phrase.ts +53 -0
- package/lib/models/{content/Profile.ts → Profile.ts} +4 -6
- package/lib/models/Progress.ts +66 -0
- package/lib/models/Review.ts +18 -0
- package/lib/models/Session.ts +140 -0
- package/lib/models/Term.ts +139 -0
- package/lib/models/User.ts +97 -0
- package/lib/models/Workspace.ts +129 -0
- package/lib/models/index.ts +22 -2
- package/lib/repo/ShareSync.ts +9 -13
- package/lib/repo/index.ts +1 -0
- package/lib/util/index.ts +0 -6
- package/package.json +4 -15
- package/dist/models/OutboundMessage.d.ts +0 -18
- package/dist/models/OutboundMessage.js +0 -25
- package/dist/models/content/Activity.d.ts +0 -10
- package/dist/models/content/Billing.d.ts +0 -144
- package/dist/models/content/Billing.js +0 -418
- package/dist/models/content/Book.d.ts +0 -77
- package/dist/models/content/Book.js +0 -407
- package/dist/models/content/Category.d.ts +0 -16
- package/dist/models/content/Category.js +0 -20
- package/dist/models/content/Checkpointable.d.ts +0 -21
- package/dist/models/content/Checkpointable.js +0 -156
- package/dist/models/content/Comment.d.ts +0 -19
- package/dist/models/content/Comment.js +0 -53
- package/dist/models/content/ConceptArt.d.ts +0 -31
- package/dist/models/content/ConceptArt.js +0 -84
- package/dist/models/content/Context.d.ts +0 -28
- package/dist/models/content/Context.js +0 -162
- package/dist/models/content/DevEnv.d.ts +0 -5
- package/dist/models/content/DevEnv.js +0 -9
- package/dist/models/content/Dictionary.d.ts +0 -31
- package/dist/models/content/Dictionary.js +0 -5
- package/dist/models/content/DictionaryEntry.d.ts +0 -20
- package/dist/models/content/DictionaryEntry.js +0 -2
- package/dist/models/content/ElasticModel.d.ts +0 -149
- package/dist/models/content/ElasticModel.js +0 -179
- package/dist/models/content/Environment.d.ts +0 -61
- package/dist/models/content/Environment.js +0 -124
- package/dist/models/content/ExportOptions.d.ts +0 -64
- package/dist/models/content/ExportOptions.js +0 -213
- package/dist/models/content/Folder.d.ts +0 -16
- package/dist/models/content/Folder.js +0 -33
- package/dist/models/content/Fragment.d.ts +0 -54
- package/dist/models/content/Fragment.js +0 -181
- package/dist/models/content/Hanzi.d.ts +0 -21
- package/dist/models/content/HighlightRule.d.ts +0 -9
- package/dist/models/content/HighlightRule.js +0 -2
- package/dist/models/content/Migration.d.ts +0 -68
- package/dist/models/content/Migration.js +0 -155
- package/dist/models/content/Phrase.d.ts +0 -8
- package/dist/models/content/Placeholder.d.ts +0 -8
- package/dist/models/content/Placeholder.js +0 -36
- package/dist/models/content/RichText.d.ts +0 -58
- package/dist/models/content/RichText.js +0 -79
- package/dist/models/content/Session.js +0 -173
- package/dist/models/content/Speech.d.ts +0 -67
- package/dist/models/content/Speech.js +0 -97
- package/dist/models/content/Stub.d.ts +0 -24
- package/dist/models/content/Stub.js +0 -179
- package/dist/models/content/Time.d.ts +0 -56
- package/dist/models/content/Time.js +0 -295
- package/dist/models/content/User.d.ts +0 -36
- package/dist/models/content/User.js +0 -95
- package/dist/models/content/Workspace.d.ts +0 -71
- package/dist/models/content/Workspace.js +0 -237
- package/dist/models/content/index.d.ts +0 -17
- package/dist/models/content/index.js +0 -34
- package/dist/models/legacy/LegacyBodyFormat.d.ts +0 -9
- package/dist/models/legacy/LegacyBodyFormat.js +0 -2
- package/dist/models/legacy/LegacyComment.d.ts +0 -12
- package/dist/models/legacy/LegacyComment.js +0 -2
- package/dist/models/legacy/LegacyContent.d.ts +0 -53
- package/dist/models/legacy/LegacyContent.js +0 -55
- package/dist/models/legacy/LegacyConversion.d.ts +0 -55
- package/dist/models/legacy/LegacyConversion.js +0 -401
- package/dist/models/legacy/LegacyFragment.d.ts +0 -21
- package/dist/models/legacy/LegacyFragment.js +0 -2
- package/dist/models/legacy/LegacyLocator.d.ts +0 -8
- package/dist/models/legacy/LegacyLocator.js +0 -31
- package/dist/models/legacy/LegacyOutboundMessage.d.ts +0 -16
- package/dist/models/legacy/LegacyOutboundMessage.js +0 -13
- package/dist/models/legacy/LegacyPicture.d.ts +0 -14
- package/dist/models/legacy/LegacyPicture.js +0 -2
- package/dist/models/legacy/LegacyProfile.d.ts +0 -9
- package/dist/models/legacy/LegacyProfile.js +0 -2
- package/dist/models/legacy/LegacySession.d.ts +0 -41
- package/dist/models/legacy/LegacySession.js +0 -35
- package/dist/models/legacy/LegacyStory.d.ts +0 -23
- package/dist/models/legacy/LegacyStory.js +0 -2
- package/dist/models/legacy/LegacyStub.d.ts +0 -15
- package/dist/models/legacy/LegacyStub.js +0 -2
- package/dist/models/legacy/LegacyTransaction.d.ts +0 -14
- package/dist/models/legacy/LegacyTransaction.js +0 -49
- package/dist/models/legacy/LegacyUser.d.ts +0 -28
- package/dist/models/legacy/LegacyUser.js +0 -32
- package/dist/models/legacy/LegacyWorkspace.d.ts +0 -23
- package/dist/models/legacy/LegacyWorkspace.js +0 -6
- package/dist/models/legacy/index.d.ts +0 -15
- package/dist/models/legacy/index.js +0 -32
- package/dist/models/markup/BodyFormat.d.ts +0 -14
- package/dist/models/markup/BodyFormat.js +0 -190
- package/dist/models/markup/DeltaOps.d.ts +0 -5
- package/dist/models/markup/DeltaOps.js +0 -74
- package/dist/models/markup/HtmlMarkup.d.ts +0 -4
- package/dist/models/markup/HtmlMarkup.js +0 -21
- package/dist/models/markup/index.d.ts +0 -4
- package/dist/models/markup/index.js +0 -21
- package/dist/util/Async.d.ts +0 -8
- package/dist/util/Async.js +0 -18
- package/dist/util/Base62.d.ts +0 -6
- package/dist/util/Base62.js +0 -47
- package/dist/util/BinarySearch.d.ts +0 -7
- package/dist/util/BinarySearch.js +0 -46
- package/dist/util/CachingHasher.d.ts +0 -8
- package/dist/util/CachingHasher.js +0 -41
- package/dist/util/Color.d.ts +0 -32
- package/dist/util/Color.js +0 -204
- package/dist/util/Dispatch.d.ts +0 -15
- package/dist/util/Dispatch.js +0 -79
- package/dist/util/EditDistance.d.ts +0 -13
- package/dist/util/EditDistance.js +0 -184
- package/dist/util/NumberFormat.d.ts +0 -14
- package/dist/util/NumberFormat.js +0 -224
- package/dist/util/Struct.d.ts +0 -4
- package/dist/util/Struct.js +0 -15
- package/dist/util/Template.d.ts +0 -16
- package/dist/util/Template.js +0 -128
- package/dist/util/Text.d.ts +0 -45
- package/dist/util/Text.js +0 -243
- package/dist/util/Tuples.d.ts +0 -9
- package/dist/util/Tuples.js +0 -135
- package/dist/util/Validate.d.ts +0 -4
- package/dist/util/Validate.js +0 -11
- package/dist/util/Vocabulary.d.ts +0 -3
- package/dist/util/Vocabulary.js +0 -35
- package/lib/models/content/Billing.ts +0 -558
- package/lib/models/content/DevEnv.ts +0 -5
- package/lib/models/content/DictionaryEntry.ts +0 -22
- package/lib/models/content/Hanzi.ts +0 -25
- package/lib/models/content/Phrase.ts +0 -10
- package/lib/models/content/Time.ts +0 -328
- package/lib/models/content/User.ts +0 -130
- package/lib/models/content/index.ts +0 -19
- package/lib/models/markup/DeltaOps.ts +0 -71
- package/lib/models/markup/index.ts +0 -6
- package/lib/util/Base62.ts +0 -47
- package/lib/util/CachingHasher.ts +0 -38
- package/lib/util/Dispatch.ts +0 -92
- package/lib/util/NumberFormat.ts +0 -194
- package/lib/util/Struct.ts +0 -14
- package/lib/util/Tuples.ts +0 -131
- /package/dist/models/{content/GeoLocation.d.ts → GeoLocation.d.ts} +0 -0
- /package/dist/models/{content/GeoLocation.js → GeoLocation.js} +0 -0
- /package/dist/models/{content/Hanzi.js → Hanzi.js} +0 -0
- /package/dist/models/{content/Permissions.d.ts → Permissions.d.ts} +0 -0
- /package/dist/models/{content/Permissions.js → Permissions.js} +0 -0
- /package/dist/models/{content/Phrase.js → Phrase.js} +0 -0
- /package/dist/models/{content/Activity.js → Review.js} +0 -0
- /package/dist/{models/markup → repo}/TextEditOps.d.ts +0 -0
- /package/dist/{models/markup → repo}/TextEditOps.js +0 -0
- /package/lib/models/{content/GeoLocation.ts → GeoLocation.ts} +0 -0
- /package/lib/{models/markup → repo}/TextEditOps.ts +0 -0
|
@@ -1,558 +0,0 @@
|
|
|
1
|
-
import { Doc } from '@shaxpir/sharedb/lib/client';
|
|
2
|
-
import { ShareSync, ShareSyncFactory } from '../../repo/ShareSync';
|
|
3
|
-
import { Struct } from '../../util/Struct';
|
|
4
|
-
import { CachingHasher } from '../../util/CachingHasher';
|
|
5
|
-
import { NumberFormat } from "../../util/NumberFormat";
|
|
6
|
-
import { BatchOperation } from '../markup/Operation';
|
|
7
|
-
import { ArrayView } from './ArrayView';
|
|
8
|
-
import { Content, ContentBody, ContentId, ContentMeta } from "./Content";
|
|
9
|
-
import { ContentKind } from './ContentKind';
|
|
10
|
-
import { CompactDateTime, MultiClock, MultiTime, Time } from './Time';
|
|
11
|
-
|
|
12
|
-
export interface CreditCardHarvest {
|
|
13
|
-
name:string;
|
|
14
|
-
number:string;
|
|
15
|
-
cvc:string;
|
|
16
|
-
exp_month:string;
|
|
17
|
-
exp_year:string;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export interface CreditCard {
|
|
21
|
-
name:string;
|
|
22
|
-
brand:string;
|
|
23
|
-
last4:string;
|
|
24
|
-
exp_month:string;
|
|
25
|
-
exp_year:string;
|
|
26
|
-
country:string;
|
|
27
|
-
funding:string;
|
|
28
|
-
wallet?:string;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export interface TransactionPayload {
|
|
32
|
-
at_utc_time?:CompactDateTime;
|
|
33
|
-
topic:TransactionTopic;
|
|
34
|
-
details?:any;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export enum TransactionTopic {
|
|
38
|
-
|
|
39
|
-
START_7_DAY_TRIAL = "START_7_DAY_TRIAL",
|
|
40
|
-
|
|
41
|
-
APPLY_COUPON = "APPLY_COUPON",
|
|
42
|
-
|
|
43
|
-
PAYMENT_SUCCESS = "PAYMENT_SUCCESS",
|
|
44
|
-
PAYMENT_FAIL = "PAYMENT_FAIL",
|
|
45
|
-
|
|
46
|
-
CANCEL_SUBSCRIPTION = "CANCEL_SUBSCRIPTION",
|
|
47
|
-
RESTART_SUBSCRIPTION = "RESTART_SUBSCRIPTION"
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export enum Interval {
|
|
51
|
-
MONTHLY = "MONTHLY",
|
|
52
|
-
ANNUAL = "ANNUAL",
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
export enum ProductLevel {
|
|
56
|
-
FREE = "FREE",
|
|
57
|
-
BASIC = "BASIC",
|
|
58
|
-
PRO = "PRO",
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
export interface BillingProduct {
|
|
62
|
-
id:string;
|
|
63
|
-
name:string;
|
|
64
|
-
level:ProductLevel;
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
export interface BillingPrice {
|
|
68
|
-
id:string;
|
|
69
|
-
name:string;
|
|
70
|
-
amount:number;
|
|
71
|
-
interval:Interval;
|
|
72
|
-
product_id:string;
|
|
73
|
-
trial_days:number;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
export interface BillingPlan {
|
|
77
|
-
id:string;
|
|
78
|
-
name:string;
|
|
79
|
-
amount:number;
|
|
80
|
-
level:ProductLevel;
|
|
81
|
-
interval:Interval;
|
|
82
|
-
trial_days:number;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
export interface ProductCatalogConfig {
|
|
86
|
-
products:BillingProduct[];
|
|
87
|
-
prices:BillingPrice[];
|
|
88
|
-
plans:BillingPlan[];
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
export class ProductCatalog {
|
|
92
|
-
|
|
93
|
-
private productsById:Map<string,BillingProduct>;
|
|
94
|
-
private pricesById:Map<string,BillingPrice>;
|
|
95
|
-
private plansById:Map<string,BillingPlan>;
|
|
96
|
-
|
|
97
|
-
constructor(config:ProductCatalogConfig) {
|
|
98
|
-
this.productsById = new Map<string,BillingProduct>();
|
|
99
|
-
this.pricesById = new Map<string,BillingPrice>();
|
|
100
|
-
this.plansById = new Map<string,BillingPlan>();
|
|
101
|
-
for (const product of config.products) {
|
|
102
|
-
this.productsById.set(product.id, product);
|
|
103
|
-
}
|
|
104
|
-
for (const price of config.prices) {
|
|
105
|
-
this.pricesById.set(price.id, price);
|
|
106
|
-
}
|
|
107
|
-
for (const plan of config.plans) {
|
|
108
|
-
this.plansById.set(plan.id, plan);
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
public getProductById(id:string):BillingProduct {
|
|
113
|
-
return this.productsById.get(id);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
public getPriceById(id:string):BillingPrice {
|
|
117
|
-
return this.pricesById.get(id);
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
public getPlanById(id:string):BillingPlan {
|
|
121
|
-
return this.plansById.get(id);
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
public getProductsByPredicate(
|
|
125
|
-
predicate:(product:BillingProduct) => boolean
|
|
126
|
-
):BillingProduct[] {
|
|
127
|
-
const products:BillingProduct[] = [];
|
|
128
|
-
for (const product of this.productsById.values()) {
|
|
129
|
-
if (predicate(product)) {
|
|
130
|
-
products.push(product);
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
return products;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
public getPricesByPredicate(
|
|
137
|
-
predicate:(price:BillingPrice) => boolean
|
|
138
|
-
):BillingPrice[] {
|
|
139
|
-
const prices:BillingPrice[] = [];
|
|
140
|
-
for (const price of this.pricesById.values()) {
|
|
141
|
-
if (predicate(price)) {
|
|
142
|
-
prices.push(price);
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
return prices;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
public getPlansByPredicate(
|
|
149
|
-
predicate:(plan:BillingPlan) => boolean
|
|
150
|
-
):BillingPlan[] {
|
|
151
|
-
const plans:BillingPlan[] = [];
|
|
152
|
-
for (const plan of this.plansById.values()) {
|
|
153
|
-
if (predicate(plan)) {
|
|
154
|
-
plans.push(plan);
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
return plans;
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
// TODO: cleanup "PRE_TRIAL" status, and update all users who have this status
|
|
162
|
-
export enum PaymentStatus {
|
|
163
|
-
PRE_TRIAL = "PRE_TRIAL",
|
|
164
|
-
IN_TRIAL = "IN_TRIAL",
|
|
165
|
-
PAID = "PAID",
|
|
166
|
-
UNPAID = "UNPAID",
|
|
167
|
-
CANCELLED = "CANCELLED",
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
export interface BillingBody extends ContentBody {
|
|
171
|
-
meta:ContentMeta;
|
|
172
|
-
payload:BillingPayload;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
export interface BillingPayload {
|
|
176
|
-
payment_status:PaymentStatus;
|
|
177
|
-
paid_until:CompactDateTime;
|
|
178
|
-
stripe_customer_id:string;
|
|
179
|
-
stripe_payment_method_id?:string;
|
|
180
|
-
stripe_payment_method_type?:string;
|
|
181
|
-
transactions:TransactionPayload[];
|
|
182
|
-
credit_card?:CreditCard;
|
|
183
|
-
product_id?:string;
|
|
184
|
-
price_id?:string;
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
export class Billing extends Content {
|
|
188
|
-
|
|
189
|
-
private _transactionsView:ArrayView<TransactionPayload>;
|
|
190
|
-
|
|
191
|
-
constructor(doc:Doc, shouldAcquire:boolean, shareSync:ShareSync) {
|
|
192
|
-
super(doc, shouldAcquire, shareSync);
|
|
193
|
-
this._transactionsView = new ArrayView<TransactionPayload>(this, [ 'payload', 'transactions' ]);
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
public get payload():BillingPayload {
|
|
197
|
-
this.checkDisposed("Billing.payload");
|
|
198
|
-
return this.doc.data.payload as BillingPayload;
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
public static makeBillingId(userId:ContentId):ContentId {
|
|
202
|
-
return CachingHasher.makeMd5ContentId(userId + "-" + ContentKind.BILLING);
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
public static create(
|
|
206
|
-
userId:ContentId,
|
|
207
|
-
payload:BillingPayload,
|
|
208
|
-
createdAt?:MultiTime
|
|
209
|
-
):Billing {
|
|
210
|
-
// Billing creation always happens in UTC time
|
|
211
|
-
const now = MultiClock.utcNow();
|
|
212
|
-
// If the createdAt time is not provided, use the current time
|
|
213
|
-
createdAt ??= now;
|
|
214
|
-
const billingId = Billing.makeBillingId(userId);
|
|
215
|
-
return ShareSyncFactory.get().createContent(
|
|
216
|
-
{
|
|
217
|
-
meta : {
|
|
218
|
-
ref : billingId,
|
|
219
|
-
is_head : true,
|
|
220
|
-
kind : ContentKind.BILLING,
|
|
221
|
-
id : billingId,
|
|
222
|
-
owner : userId,
|
|
223
|
-
created_at : createdAt,
|
|
224
|
-
updated_at : now,
|
|
225
|
-
},
|
|
226
|
-
payload : payload
|
|
227
|
-
}
|
|
228
|
-
) as Billing;
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
public isSubscribedToPricedProduct():boolean {
|
|
232
|
-
this.checkDisposed("Billing.isSubscribedToPricedProduct");
|
|
233
|
-
return this.priceId != null && this.productId != null;
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
public get priceId():string {
|
|
237
|
-
this.checkDisposed("Billing.priceId");
|
|
238
|
-
return this.payload.price_id || null;
|
|
239
|
-
}
|
|
240
|
-
public setPriceId(value:string) {
|
|
241
|
-
this.checkDisposed("Billing.setPriceId");
|
|
242
|
-
if (this.payload.price_id !== value) {
|
|
243
|
-
const batch = new BatchOperation(this);
|
|
244
|
-
batch.setPathValue([ 'payload', 'price_id' ] , value);
|
|
245
|
-
batch.commit();
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
public get productId():string {
|
|
250
|
-
this.checkDisposed("Billing.productId");
|
|
251
|
-
return this.payload.product_id || null;
|
|
252
|
-
}
|
|
253
|
-
public setProductId(value:string) {
|
|
254
|
-
this.checkDisposed("Billing.setProductId");
|
|
255
|
-
if (this.payload.product_id !== value) {
|
|
256
|
-
const batch = new BatchOperation(this);
|
|
257
|
-
batch.setPathValue([ 'payload', 'product_id' ] , value);
|
|
258
|
-
batch.commit();
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
public get paidUntil():CompactDateTime {
|
|
263
|
-
this.checkDisposed("Billing.paidUntil");
|
|
264
|
-
return this.payload.paid_until;
|
|
265
|
-
}
|
|
266
|
-
public setPaidUntil(value:CompactDateTime) {
|
|
267
|
-
this.checkDisposed("Billing.setPaidUntil");
|
|
268
|
-
if (this.paidUntil !== value) {
|
|
269
|
-
const batch = new BatchOperation(this);
|
|
270
|
-
batch.setPathValue([ 'payload', 'paid_until' ] , value);
|
|
271
|
-
batch.commit();
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
public get paymentStatus():PaymentStatus {
|
|
276
|
-
this.checkDisposed("Billing.paymentStatus");
|
|
277
|
-
return this.payload.payment_status;
|
|
278
|
-
}
|
|
279
|
-
public setPaymentStatus(value:PaymentStatus) {
|
|
280
|
-
this.checkDisposed("Billing.setPaymentStatus");
|
|
281
|
-
if (this.paymentStatus !== value) {
|
|
282
|
-
const batch = new BatchOperation(this);
|
|
283
|
-
batch.setPathValue([ 'payload', 'payment_status' ] , value);
|
|
284
|
-
batch.commit();
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
public get stripeCustomerId():string {
|
|
289
|
-
this.checkDisposed("Billing.stripeCustomerId");
|
|
290
|
-
return this.payload.stripe_customer_id;
|
|
291
|
-
}
|
|
292
|
-
public setStripeCustomerId(value:string) {
|
|
293
|
-
this.checkDisposed("Billing.setStripeCustomerId");
|
|
294
|
-
if (this.stripeCustomerId !== value) {
|
|
295
|
-
const batch = new BatchOperation(this);
|
|
296
|
-
batch.setPathValue([ 'payload', 'stripe_customer_id' ] , value);
|
|
297
|
-
batch.commit();
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
public get stripePaymentMethodId():string {
|
|
302
|
-
this.checkDisposed("Billing.stripePaymentMethodId");
|
|
303
|
-
return this.payload.stripe_payment_method_id;
|
|
304
|
-
}
|
|
305
|
-
public setStripePaymentMethodId(value:string) {
|
|
306
|
-
this.checkDisposed("Billing.setStripePaymentMethodId");
|
|
307
|
-
if (this.stripeCustomerId !== value) {
|
|
308
|
-
const batch = new BatchOperation(this);
|
|
309
|
-
batch.setPathValue([ 'payload', 'stripe_payment_method_id' ] , value);
|
|
310
|
-
batch.commit();
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
public get stripePaymentMethodType():string {
|
|
315
|
-
this.checkDisposed("Billing.stripePaymentMethodType");
|
|
316
|
-
return this.payload.stripe_payment_method_id;
|
|
317
|
-
}
|
|
318
|
-
public setStripePaymentMethodType(value:string) {
|
|
319
|
-
this.checkDisposed("Billing.setStripePaymentMethodType");
|
|
320
|
-
if (this.stripeCustomerId !== value) {
|
|
321
|
-
const batch = new BatchOperation(this);
|
|
322
|
-
batch.setPathValue([ 'payload', 'stripe_payment_method_type' ] , value);
|
|
323
|
-
batch.commit();
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
public get creditCard():CreditCard {
|
|
328
|
-
this.checkDisposed("Billing.creditCard");
|
|
329
|
-
return this.payload.credit_card;
|
|
330
|
-
}
|
|
331
|
-
public setCreditCard(value:CreditCard) {
|
|
332
|
-
this.checkDisposed("Billing.setCreditCard");
|
|
333
|
-
if (this.creditCard != value) {
|
|
334
|
-
const batch = new BatchOperation(this);
|
|
335
|
-
batch.setPathValue([ 'payload', 'credit_card' ] , value);
|
|
336
|
-
batch.commit();
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
public get transactions():ArrayView<TransactionPayload> {
|
|
341
|
-
this.checkDisposed("Billing.transactions");
|
|
342
|
-
return this._transactionsView;
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
// Somehow, the transactions array on many users is not in the correct order. Some users have
|
|
346
|
-
// transactions in reverse order, and some have transactions in random order. Eventually, we
|
|
347
|
-
// will correct the stored data, but for now, we will clone the transactions array and sort it
|
|
348
|
-
// by the transaction time, so that we can correctly iterate through the transactions.
|
|
349
|
-
public get sortedTransactions():TransactionPayload[] {
|
|
350
|
-
this.checkDisposed("Billing.sortedTransactions");
|
|
351
|
-
return Struct.clone(this._transactionsView.values).sort(
|
|
352
|
-
(a:TransactionPayload, b:TransactionPayload) => {
|
|
353
|
-
return Time.compareDateTime(a.at_utc_time, b.at_utc_time);
|
|
354
|
-
}
|
|
355
|
-
);
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
public getLastTransaction():TransactionPayload {
|
|
359
|
-
this.checkDisposed("Billing.getLastTransaction");
|
|
360
|
-
if (this._transactionsView.length > 0) {
|
|
361
|
-
const transactions = this.sortedTransactions;
|
|
362
|
-
return transactions[transactions.length - 1];
|
|
363
|
-
} else {
|
|
364
|
-
return null;
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
public getLastPaymentTransaction():TransactionPayload {
|
|
369
|
-
this.checkDisposed("Billing.getLastPaymentTransaction");
|
|
370
|
-
// Starts iterating from the most-recent transaction, so this function will
|
|
371
|
-
// return only the most-recent matching transaction.
|
|
372
|
-
const transactions = this.sortedTransactions;
|
|
373
|
-
for (let i = transactions.length - 1; i >= 0; i--) {
|
|
374
|
-
const transaction:TransactionPayload = transactions[i];
|
|
375
|
-
const topic:TransactionTopic = transaction.topic;
|
|
376
|
-
if (topic === TransactionTopic.PAYMENT_FAIL || topic === TransactionTopic.PAYMENT_SUCCESS) {
|
|
377
|
-
return transaction;
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
|
-
return null;
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
public getActiveUserCoupon():any {
|
|
384
|
-
this.checkDisposed("Billing.getActiveUserCoupon");
|
|
385
|
-
const nowInSeconds:number = (new Date()).getTime() / 1000;
|
|
386
|
-
// Coupons with a duration of "once" or "forever" have a null "end" value. We treat "once" coupons
|
|
387
|
-
// as being still-in-effect until a payment on the next invoice is attempted (either a pass or fail
|
|
388
|
-
// tells us that the billing period has completed).
|
|
389
|
-
const transactions = this.sortedTransactions;
|
|
390
|
-
for (let i = transactions.length - 1; i >= 0; i--) {
|
|
391
|
-
const transaction = transactions[i];
|
|
392
|
-
const topic:TransactionTopic = transaction.topic;
|
|
393
|
-
if (topic === TransactionTopic.CANCEL_SUBSCRIPTION) {
|
|
394
|
-
return null;
|
|
395
|
-
}
|
|
396
|
-
if (topic === TransactionTopic.APPLY_COUPON) {
|
|
397
|
-
const discount:any = transaction.details;
|
|
398
|
-
const coupon:any = discount.coupon;
|
|
399
|
-
if (coupon.duration === "forever" || (nowInSeconds >= discount.start && nowInSeconds <= discount.end)) {
|
|
400
|
-
return coupon;
|
|
401
|
-
} else {
|
|
402
|
-
return null;
|
|
403
|
-
}
|
|
404
|
-
}
|
|
405
|
-
}
|
|
406
|
-
return null;
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
public daysPastDue():number {
|
|
410
|
-
this.checkDisposed("Billing.daysPastDue");
|
|
411
|
-
const daysSincePaidUntil:number = Time.timeSince(this.paidUntil, 'days');
|
|
412
|
-
return daysSincePaidUntil < 0 ? 0 : daysSincePaidUntil;
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
public didLastPaymentFail():boolean {
|
|
416
|
-
this.checkDisposed("Billing.didLastPaymentFail");
|
|
417
|
-
const t:TransactionPayload = this.getLastPaymentTransaction();
|
|
418
|
-
return t != null && t.topic === TransactionTopic.PAYMENT_FAIL;
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
public didLastPaymentSucceed():boolean {
|
|
422
|
-
this.checkDisposed("Billing.didLastPaymentSucceed");
|
|
423
|
-
const t:TransactionPayload = this.getLastPaymentTransaction();
|
|
424
|
-
return t != null && t.topic === TransactionTopic.PAYMENT_SUCCESS;
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
public findTransactionByTopic(topic:TransactionTopic):TransactionPayload {
|
|
428
|
-
this.checkDisposed("Billing.findTransactionByTopic");
|
|
429
|
-
const transactions = this.sortedTransactions;
|
|
430
|
-
// Starts iterating from the most-recent transaction, so this function will
|
|
431
|
-
// return only the most-recent matching transaction.
|
|
432
|
-
for (let i = transactions.length - 1; i >= 0; i--) {
|
|
433
|
-
const transaction:TransactionPayload = transactions[i];
|
|
434
|
-
if (transaction.topic === topic) {
|
|
435
|
-
return transaction;
|
|
436
|
-
}
|
|
437
|
-
}
|
|
438
|
-
return null;
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
public cancel():void {
|
|
442
|
-
this.checkDisposed("Billing.cancel");
|
|
443
|
-
|
|
444
|
-
const now:MultiTime = MultiClock.utcNow();
|
|
445
|
-
const transaction:TransactionPayload = {
|
|
446
|
-
at_utc_time: now.utc_time,
|
|
447
|
-
topic: TransactionTopic.CANCEL_SUBSCRIPTION
|
|
448
|
-
};
|
|
449
|
-
|
|
450
|
-
const batch = new BatchOperation(this, now);
|
|
451
|
-
|
|
452
|
-
// Add a transaction to the billing model for this cancellation
|
|
453
|
-
batch.pushIntoArray([ 'payload', 'transactions' ], transaction);
|
|
454
|
-
batch.setPathValue([ 'payload', 'plan' ], null);
|
|
455
|
-
batch.setPathValue([ 'payload', 'price_id' ], null);
|
|
456
|
-
batch.setPathValue([ 'payload', 'product_id' ], null);
|
|
457
|
-
batch.setPathValue([ 'payload', 'paid_until' ], null);
|
|
458
|
-
batch.setPathValue([ 'payload', 'payment_status' ], PaymentStatus.CANCELLED);
|
|
459
|
-
|
|
460
|
-
batch.commit();
|
|
461
|
-
}
|
|
462
|
-
|
|
463
|
-
public restartPlan(
|
|
464
|
-
plan:string,
|
|
465
|
-
paidUntilEpochSeconds:number
|
|
466
|
-
):void {
|
|
467
|
-
this.checkDisposed("Billing.restartPlan");
|
|
468
|
-
|
|
469
|
-
const now:MultiTime = MultiClock.utcNow();
|
|
470
|
-
const transaction:TransactionPayload = {
|
|
471
|
-
at_utc_time: now.utc_time,
|
|
472
|
-
topic: TransactionTopic.RESTART_SUBSCRIPTION
|
|
473
|
-
};
|
|
474
|
-
|
|
475
|
-
const batch = new BatchOperation(this, now);
|
|
476
|
-
|
|
477
|
-
// Add a transaction to the billing model for this cancellation
|
|
478
|
-
batch.pushIntoArray([ 'payload', 'transactions' ], transaction);
|
|
479
|
-
batch.setPathValue([ 'payload', 'plan' ], plan);
|
|
480
|
-
batch.setPathValue([ 'payload', 'product_id' ], null);
|
|
481
|
-
batch.setPathValue([ 'payload', 'price_id' ], null);
|
|
482
|
-
batch.setPathValue([ 'payload', 'paid_until' ], Time.utcFromEpochSeconds(paidUntilEpochSeconds));
|
|
483
|
-
batch.setPathValue([ 'payload', 'payment_status' ], PaymentStatus.PAID);
|
|
484
|
-
|
|
485
|
-
batch.commit();
|
|
486
|
-
}
|
|
487
|
-
|
|
488
|
-
public restartPricedProduct(
|
|
489
|
-
productId:string,
|
|
490
|
-
priceId:string,
|
|
491
|
-
paidUntilEpochSeconds:number
|
|
492
|
-
):void {
|
|
493
|
-
this.checkDisposed("Billing.restartPricedProduct");
|
|
494
|
-
|
|
495
|
-
const now:MultiTime = MultiClock.utcNow();
|
|
496
|
-
const transaction:TransactionPayload = {
|
|
497
|
-
at_utc_time: now.utc_time,
|
|
498
|
-
topic: TransactionTopic.RESTART_SUBSCRIPTION
|
|
499
|
-
};
|
|
500
|
-
|
|
501
|
-
const batch = new BatchOperation(this, now);
|
|
502
|
-
|
|
503
|
-
// Add a transaction to the billing model for this cancellation
|
|
504
|
-
batch.pushIntoArray([ 'payload', 'transactions' ], transaction);
|
|
505
|
-
batch.setPathValue([ 'payload', 'plan' ], null);
|
|
506
|
-
batch.setPathValue([ 'payload', 'product_id' ], productId);
|
|
507
|
-
batch.setPathValue([ 'payload', 'price_id' ], priceId);
|
|
508
|
-
batch.setPathValue([ 'payload', 'paid_until' ], Time.utcFromEpochSeconds(paidUntilEpochSeconds));
|
|
509
|
-
batch.setPathValue([ 'payload', 'payment_status' ], PaymentStatus.PAID);
|
|
510
|
-
|
|
511
|
-
batch.commit();
|
|
512
|
-
}
|
|
513
|
-
|
|
514
|
-
public static async findByStripeCustomerId(stripeCustomerId:string):Promise<Billing[]> {
|
|
515
|
-
const shareSync = ShareSyncFactory.get();
|
|
516
|
-
return shareSync.findAndAcquire(
|
|
517
|
-
ContentKind.BILLING, { "payload.stripe_customer_id" : stripeCustomerId }
|
|
518
|
-
) as Promise<Billing[]>;
|
|
519
|
-
}
|
|
520
|
-
|
|
521
|
-
public static describeCoupon(coupon:any):string {
|
|
522
|
-
|
|
523
|
-
let description:string = "";
|
|
524
|
-
if (coupon.hasOwnProperty("percent_off") && coupon.percent_off !== null) {
|
|
525
|
-
description = coupon.percent_off + "% OFF";
|
|
526
|
-
} else if (coupon.hasOwnProperty("amount_off") && coupon.amount_off !== null) {
|
|
527
|
-
description = NumberFormat.dollarsFromCents(coupon.amount_off) + " OFF";
|
|
528
|
-
}
|
|
529
|
-
|
|
530
|
-
if (coupon.duration === "forever") {
|
|
531
|
-
description += ", FOREVER";
|
|
532
|
-
} else if (coupon.duration === "once") {
|
|
533
|
-
description += " YOUR NEXT INVOICE";
|
|
534
|
-
} else if (coupon.duration === "repeating") {
|
|
535
|
-
description += " FOR " + coupon.duration_in_months + " MONTHS";
|
|
536
|
-
}
|
|
537
|
-
|
|
538
|
-
return description;
|
|
539
|
-
}
|
|
540
|
-
|
|
541
|
-
public static normalizeCreditCardBrand(brand:string):string {
|
|
542
|
-
const lowerCaseNoSpaces:string = brand.toLowerCase().replace(/\s/g, '');
|
|
543
|
-
if (lowerCaseNoSpaces.startsWith("visa")) {
|
|
544
|
-
return "VISA";
|
|
545
|
-
} else if (lowerCaseNoSpaces.startsWith("mastercard")) {
|
|
546
|
-
return "MC";
|
|
547
|
-
} else if (lowerCaseNoSpaces.startsWith("americanexpress")) {
|
|
548
|
-
return "AMEX";
|
|
549
|
-
} else if (lowerCaseNoSpaces.startsWith("diners")) {
|
|
550
|
-
return "DINERS";
|
|
551
|
-
} else if (lowerCaseNoSpaces.startsWith("jcb")) {
|
|
552
|
-
return "JCB";
|
|
553
|
-
} else if (lowerCaseNoSpaces.startsWith("discover")) {
|
|
554
|
-
return "DISC";
|
|
555
|
-
}
|
|
556
|
-
return brand;
|
|
557
|
-
}
|
|
558
|
-
}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
export interface DictionaryEntry {
|
|
2
|
-
text:string;
|
|
3
|
-
rank:number;
|
|
4
|
-
learn_rank:number;
|
|
5
|
-
is_starred?:boolean;
|
|
6
|
-
tags:string[];
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export interface Pronouncable {
|
|
10
|
-
pinyin:string; // hanzi, phrase
|
|
11
|
-
pinyin_tokenized?:string; // phrase
|
|
12
|
-
pinyin_normalized:string; // hanzi, phrase
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export interface Definable {
|
|
16
|
-
definition:string; // hanzi, phrase
|
|
17
|
-
definition_analysis:string; // hanzi, phrase
|
|
18
|
-
translation?:string; // hanzi
|
|
19
|
-
transliteration?:string; // phrase
|
|
20
|
-
function?:string; // hanzi
|
|
21
|
-
usage?:string; // phrase
|
|
22
|
-
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { ContentBody, ContentMeta } from "./Content";
|
|
2
|
-
import { Definable, DictionaryEntry, Pronouncable } from "./DictionaryEntry";
|
|
3
|
-
|
|
4
|
-
export interface HanziComponent {
|
|
5
|
-
component:string;
|
|
6
|
-
meaning:string;
|
|
7
|
-
pinyin:string;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export interface HanziSense extends Definable, Pronouncable {
|
|
11
|
-
phrases:string[];
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export interface HanziPayload extends DictionaryEntry {
|
|
15
|
-
components:HanziComponent[];
|
|
16
|
-
component_analysis:string;
|
|
17
|
-
radical:string;
|
|
18
|
-
radical_analysis:string;
|
|
19
|
-
senses:HanziSense[];
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export interface HanziBody extends ContentBody {
|
|
23
|
-
meta:ContentMeta;
|
|
24
|
-
payload:HanziPayload;
|
|
25
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { ContentBody, ContentMeta } from "./Content";
|
|
2
|
-
import { Definable, DictionaryEntry, Pronouncable } from "./DictionaryEntry";
|
|
3
|
-
|
|
4
|
-
export interface PhrasePayload extends DictionaryEntry, Pronouncable, Definable {
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
export interface PhraseBody extends ContentBody {
|
|
8
|
-
meta:ContentMeta;
|
|
9
|
-
payload:PhrasePayload;
|
|
10
|
-
}
|