Merge commit '217b9e8835970e0f2c5b9fe2904af77f5caa8695' into OMN-134
This commit is contained in:
@ -1454,7 +1454,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = Entitlements/Omnivore.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 62;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEVELOPMENT_TEAM = QJF2XZ86HB;
|
||||
ENABLE_PREVIEWS = YES;
|
||||
INFOPLIST_FILE = InfoPlists/Omnivore.plist;
|
||||
@ -1463,7 +1463,7 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.4.1;
|
||||
MARKETING_VERSION = 1.4.2;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = app.omnivore.app;
|
||||
PRODUCT_NAME = Omnivore;
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
@ -1483,7 +1483,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = "SafariExtension (iOS).entitlements";
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 62;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEVELOPMENT_TEAM = QJF2XZ86HB;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_FILE = "InfoPlists/SafariExtension-iOS.plist";
|
||||
@ -1495,7 +1495,7 @@
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.4.1;
|
||||
MARKETING_VERSION = 1.4.2;
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
OTHER_LDFLAGS = (
|
||||
@ -1522,7 +1522,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = "SafariExtension (iOS)Release.entitlements";
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 62;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEVELOPMENT_TEAM = QJF2XZ86HB;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_FILE = "InfoPlists/SafariExtension-iOS.plist";
|
||||
@ -1534,7 +1534,7 @@
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.4.1;
|
||||
MARKETING_VERSION = 1.4.2;
|
||||
MTL_FAST_MATH = YES;
|
||||
OTHER_LDFLAGS = (
|
||||
"-framework",
|
||||
@ -1687,7 +1687,7 @@
|
||||
buildSettings = {
|
||||
CODE_SIGN_ENTITLEMENTS = Entitlements/ShareExtension.entitlements;
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
CURRENT_PROJECT_VERSION = 62;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEVELOPMENT_TEAM = QJF2XZ86HB;
|
||||
INFOPLIST_FILE = InfoPlists/ShareExtension.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 14.1;
|
||||
@ -1696,7 +1696,7 @@
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.4.1;
|
||||
MARKETING_VERSION = 1.4.2;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "app.omnivore.app.share-extension";
|
||||
PRODUCT_NAME = ShareExtension;
|
||||
SDKROOT = iphoneos;
|
||||
@ -1741,7 +1741,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = Entitlements/Omnivore.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 62;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEVELOPMENT_TEAM = QJF2XZ86HB;
|
||||
ENABLE_PREVIEWS = YES;
|
||||
INFOPLIST_FILE = InfoPlists/Omnivore.plist;
|
||||
@ -1750,7 +1750,7 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.4.1;
|
||||
MARKETING_VERSION = 1.4.2;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = app.omnivore.app;
|
||||
PRODUCT_NAME = Omnivore;
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
@ -1769,7 +1769,7 @@
|
||||
buildSettings = {
|
||||
CODE_SIGN_ENTITLEMENTS = Entitlements/ShareExtension.entitlements;
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
CURRENT_PROJECT_VERSION = 62;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEVELOPMENT_TEAM = QJF2XZ86HB;
|
||||
INFOPLIST_FILE = InfoPlists/ShareExtension.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 14.1;
|
||||
@ -1778,7 +1778,7 @@
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.4.1;
|
||||
MARKETING_VERSION = 1.4.2;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "app.omnivore.app.share-extension";
|
||||
PRODUCT_NAME = ShareExtension;
|
||||
SDKROOT = iphoneos;
|
||||
|
||||
@ -56,7 +56,9 @@ struct WebReader: UIViewRepresentable {
|
||||
|
||||
webView.configuration.userContentController.add(webView, name: "viewerAction")
|
||||
|
||||
webView.configuration.userContentController.addScriptMessageHandler(context.coordinator, contentWorld: .page, name: "articleAction")
|
||||
webView.configuration.userContentController.addScriptMessageHandler(
|
||||
context.coordinator, contentWorld: .page, name: "articleAction"
|
||||
)
|
||||
|
||||
context.coordinator.linkHandler = openLinkAction
|
||||
context.coordinator.webViewActionHandler = webViewActionHandler
|
||||
|
||||
@ -9,6 +9,14 @@ struct SafariWebLink: Identifiable {
|
||||
let url: URL
|
||||
}
|
||||
|
||||
func encodeHighlightResult(_ highlight: Highlight) -> [String: Any]? {
|
||||
let data = try? JSONEncoder().encode(highlight)
|
||||
if let data = data, let dictionary = try? JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [String: Any] {
|
||||
return dictionary
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
final class WebReaderViewModel: ObservableObject {
|
||||
@Published var isLoading = false
|
||||
@Published var articleContent: ArticleContent?
|
||||
@ -42,13 +50,18 @@ final class WebReaderViewModel: ObservableObject {
|
||||
highlightID: messageBody["id"] as? String ?? "",
|
||||
quote: messageBody["quote"] as? String ?? "",
|
||||
patch: messageBody["patch"] as? String ?? "",
|
||||
articleId: messageBody["articleId"] as? String ?? ""
|
||||
articleId: messageBody["articleId"] as? String ?? "",
|
||||
annotation: messageBody["annotation"] as? String ?? ""
|
||||
)
|
||||
.sink { completion in
|
||||
guard case .failure = completion else { return }
|
||||
replyHandler(["result": false], nil)
|
||||
} receiveValue: { _ in
|
||||
replyHandler(["result": true], nil)
|
||||
replyHandler([], "createHighlight: Error encoding response")
|
||||
} receiveValue: { highlight in
|
||||
if let highlight = encodeHighlightResult(highlight) {
|
||||
replyHandler(["result": highlight], nil)
|
||||
} else {
|
||||
replyHandler([], "createHighlight: Error encoding response")
|
||||
}
|
||||
}
|
||||
.store(in: &subscriptions)
|
||||
}
|
||||
@ -85,9 +98,13 @@ final class WebReaderViewModel: ObservableObject {
|
||||
)
|
||||
.sink { completion in
|
||||
guard case .failure = completion else { return }
|
||||
replyHandler(["result": false], nil)
|
||||
} receiveValue: { _ in
|
||||
replyHandler(["result": true], nil)
|
||||
replyHandler([], "mergeHighlight: Error encoding response")
|
||||
} receiveValue: { highlight in
|
||||
if let highlight = encodeHighlightResult(highlight) {
|
||||
replyHandler(["result": highlight], nil)
|
||||
} else {
|
||||
replyHandler([], "mergeHighlight: Error encoding response")
|
||||
}
|
||||
}
|
||||
.store(in: &subscriptions)
|
||||
}
|
||||
@ -104,9 +121,10 @@ final class WebReaderViewModel: ObservableObject {
|
||||
)
|
||||
.sink { completion in
|
||||
guard case .failure = completion else { return }
|
||||
replyHandler(["result": false], nil)
|
||||
} receiveValue: { _ in
|
||||
replyHandler(["result": true], nil)
|
||||
replyHandler([], "updateHighlight: Error encoding response")
|
||||
} receiveValue: { highlight in
|
||||
// Update highlight JS code just expects the highlight ID back
|
||||
replyHandler(["result": highlight.id], nil)
|
||||
}
|
||||
.store(in: &subscriptions)
|
||||
}
|
||||
|
||||
@ -11,16 +11,16 @@ public extension DataService {
|
||||
patch: String,
|
||||
articleId: String,
|
||||
annotation: String? = nil
|
||||
) -> AnyPublisher<String, BasicError> {
|
||||
) -> AnyPublisher<Highlight, BasicError> {
|
||||
enum MutationResult {
|
||||
case saved(id: String)
|
||||
case saved(highlight: Highlight)
|
||||
case error(errorCode: Enums.CreateHighlightErrorCode)
|
||||
}
|
||||
|
||||
let selection = Selection<MutationResult, Unions.CreateHighlightResult> {
|
||||
try $0.on(
|
||||
createHighlightSuccess: .init {
|
||||
.saved(id: try $0.highlight(selection: Selection.Highlight { try $0.id() }))
|
||||
.saved(highlight: try $0.highlight(selection: highlightSelection))
|
||||
},
|
||||
createHighlightError: .init { .error(errorCode: try $0.errorCodes().first ?? .badData) }
|
||||
)
|
||||
@ -53,8 +53,8 @@ public extension DataService {
|
||||
}
|
||||
|
||||
switch payload.data {
|
||||
case let .saved(id: id):
|
||||
promise(.success(id))
|
||||
case let .saved(highlight: highlight):
|
||||
promise(.success(highlight))
|
||||
case let .error(errorCode: errorCode):
|
||||
promise(.failure(.message(messageText: errorCode.rawValue)))
|
||||
}
|
||||
|
||||
@ -12,16 +12,16 @@ public extension DataService {
|
||||
patch: String,
|
||||
articleId: String,
|
||||
overlapHighlightIdList: [String]
|
||||
) -> AnyPublisher<String, BasicError> {
|
||||
) -> AnyPublisher<Highlight, BasicError> {
|
||||
enum MutationResult {
|
||||
case saved(id: String)
|
||||
case saved(highlight: Highlight)
|
||||
case error(errorCode: Enums.MergeHighlightErrorCode)
|
||||
}
|
||||
|
||||
let selection = Selection<MutationResult, Unions.MergeHighlightResult> {
|
||||
try $0.on(
|
||||
mergeHighlightSuccess: .init {
|
||||
.saved(id: try $0.highlight(selection: Selection.Highlight { try $0.id() }))
|
||||
.saved(highlight: try $0.highlight(selection: highlightSelection))
|
||||
},
|
||||
mergeHighlightError: .init { .error(errorCode: try $0.errorCodes().first ?? .badData) }
|
||||
)
|
||||
@ -57,8 +57,8 @@ public extension DataService {
|
||||
}
|
||||
|
||||
switch payload.data {
|
||||
case let .saved(id: id):
|
||||
promise(.success(id))
|
||||
case let .saved(highlight: highlight):
|
||||
promise(.success(highlight))
|
||||
case let .error(errorCode: errorCode):
|
||||
promise(.failure(.message(messageText: errorCode.rawValue)))
|
||||
}
|
||||
|
||||
@ -8,16 +8,16 @@ public extension DataService {
|
||||
highlightID: String,
|
||||
annotation: String?,
|
||||
sharedAt: Date?
|
||||
) -> AnyPublisher<String, BasicError> {
|
||||
) -> AnyPublisher<Highlight, BasicError> {
|
||||
enum MutationResult {
|
||||
case saved(id: String)
|
||||
case saved(highlight: Highlight)
|
||||
case error(errorCode: Enums.UpdateHighlightErrorCode)
|
||||
}
|
||||
|
||||
let selection = Selection<MutationResult, Unions.UpdateHighlightResult> {
|
||||
try $0.on(
|
||||
updateHighlightSuccess: .init {
|
||||
.saved(id: try $0.highlight(selection: Selection.Highlight { try $0.id() }))
|
||||
.saved(highlight: try $0.highlight(selection: highlightSelection))
|
||||
},
|
||||
updateHighlightError: .init { .error(errorCode: try $0.errorCodes().first ?? .badData) }
|
||||
)
|
||||
@ -47,8 +47,8 @@ public extension DataService {
|
||||
}
|
||||
|
||||
switch payload.data {
|
||||
case let .saved(id: id):
|
||||
promise(.success(id))
|
||||
case let .saved(highlight: highlight):
|
||||
promise(.success(highlight))
|
||||
case let .error(errorCode: errorCode):
|
||||
promise(.failure(.message(messageText: errorCode.rawValue)))
|
||||
}
|
||||
|
||||
@ -11,19 +11,6 @@ public extension DataService {
|
||||
case error(error: String)
|
||||
}
|
||||
|
||||
let highlightSelection = Selection.Highlight {
|
||||
Highlight(
|
||||
id: try $0.id(),
|
||||
shortId: try $0.shortId(),
|
||||
quote: try $0.quote(),
|
||||
prefix: try $0.prefix(),
|
||||
suffix: try $0.suffix(),
|
||||
patch: try $0.patch(),
|
||||
annotation: try $0.annotation(),
|
||||
createdByMe: try $0.createdByMe()
|
||||
)
|
||||
}
|
||||
|
||||
let articleSelection = Selection.Article {
|
||||
ArticleContent(
|
||||
htmlContent: try $0.content(),
|
||||
|
||||
@ -0,0 +1,15 @@
|
||||
import Models
|
||||
import SwiftGraphQL
|
||||
|
||||
let highlightSelection = Selection.Highlight {
|
||||
Highlight(
|
||||
id: try $0.id(),
|
||||
shortId: try $0.shortId(),
|
||||
quote: try $0.quote(),
|
||||
prefix: try $0.prefix(),
|
||||
suffix: try $0.suffix(),
|
||||
patch: try $0.patch(),
|
||||
annotation: try $0.annotation(),
|
||||
createdByMe: try $0.createdByMe()
|
||||
)
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@ -78,6 +78,8 @@ UPDATE_HIGHLIGHT_SQL = f'''
|
||||
def assertData(conn, client):
|
||||
# get all users from postgres
|
||||
try:
|
||||
success = 0
|
||||
failure = 0
|
||||
cursor = conn.cursor(cursor_factory=RealDictCursor)
|
||||
cursor.execute('''SELECT id FROM omnivore.user''')
|
||||
result = cursor.fetchall()
|
||||
@ -90,11 +92,14 @@ def assertData(conn, client):
|
||||
index='pages', body={'query': {'term': {'userId': userId}}})['count']
|
||||
|
||||
if countInPostgres == countInElastic:
|
||||
success += 1
|
||||
print(f'User {userId} OK')
|
||||
else:
|
||||
failure += 1
|
||||
print(
|
||||
f'User {userId} ERROR: postgres: {countInPostgres}, elastic: {countInElastic}')
|
||||
cursor.close()
|
||||
print(f'Asserted data, success: {success}, failure: {failure}')
|
||||
except Exception as err:
|
||||
print('Assert data ERROR:', err)
|
||||
exit(1)
|
||||
|
||||
@ -77,7 +77,7 @@
|
||||
"highlightjs": "^9.16.2",
|
||||
"html-entities": "^2.3.2",
|
||||
"intercom-client": "^3.1.4",
|
||||
"jsdom": "^16.4.0",
|
||||
"jsdom": "^19.0.0",
|
||||
"jsonwebtoken": "^8.5.1",
|
||||
"jwks-rsa": "^2.0.3",
|
||||
"knex": "0.21.12",
|
||||
|
||||
@ -37,9 +37,9 @@ export const createPubSubClient = (): PubsubClient => {
|
||||
Buffer.from(JSON.stringify({ userId, email, name, username }))
|
||||
)
|
||||
},
|
||||
pageSaved: (page: Partial<Page>, userId: string): Promise<void> => {
|
||||
pageUpdated: (page: Partial<Page>, userId: string): Promise<void> => {
|
||||
return publish(
|
||||
'pageSaved',
|
||||
'pageUpdated',
|
||||
Buffer.from(JSON.stringify({ ...page, userId }))
|
||||
)
|
||||
},
|
||||
@ -73,7 +73,7 @@ export interface PubsubClient {
|
||||
username: string
|
||||
) => Promise<void>
|
||||
pageCreated: (page: Page) => Promise<void>
|
||||
pageSaved: (page: Partial<Page>, userId: string) => Promise<void>
|
||||
pageUpdated: (page: Partial<Page>, userId: string) => Promise<void>
|
||||
pageDeleted: (id: string, userId: string) => Promise<void>
|
||||
reportSubmitted(
|
||||
submitterId: string | undefined,
|
||||
|
||||
@ -206,7 +206,7 @@ export const updatePage = async (
|
||||
|
||||
if (body.result !== 'updated') return false
|
||||
|
||||
await ctx.pubsub.pageSaved(page, ctx.uid)
|
||||
await ctx.pubsub.pageUpdated({ ...page, id }, ctx.uid)
|
||||
|
||||
return true
|
||||
} catch (e) {
|
||||
|
||||
@ -1,10 +1,12 @@
|
||||
import {
|
||||
Entity,
|
||||
BaseEntity,
|
||||
Column,
|
||||
ManyToOne,
|
||||
CreateDateColumn,
|
||||
Entity,
|
||||
JoinColumn,
|
||||
ManyToOne,
|
||||
PrimaryGeneratedColumn,
|
||||
UpdateDateColumn,
|
||||
} from 'typeorm'
|
||||
import { User } from './user'
|
||||
|
||||
@ -22,4 +24,10 @@ export class NewsletterEmail extends BaseEntity {
|
||||
|
||||
@Column('varchar', { nullable: true })
|
||||
confirmationCode?: string
|
||||
|
||||
@CreateDateColumn()
|
||||
createdAt!: Date
|
||||
|
||||
@UpdateDateColumn()
|
||||
updatedAt!: Date
|
||||
}
|
||||
|
||||
@ -306,6 +306,9 @@ export const functionResolvers = {
|
||||
}
|
||||
return article.url
|
||||
},
|
||||
async originalArticleUrl(article: { url: string }) {
|
||||
return article.url
|
||||
},
|
||||
async savedByViewer(
|
||||
article: { id: string; savedByViewer?: boolean },
|
||||
__: unknown,
|
||||
|
||||
@ -30,7 +30,10 @@ export const createNewsletterEmail = async (
|
||||
export const getNewsletterEmails = async (
|
||||
userId: string
|
||||
): Promise<NewsletterEmail[]> => {
|
||||
return getRepository(NewsletterEmail).find({ where: { user: userId } })
|
||||
return getRepository(NewsletterEmail).find({
|
||||
where: { user: userId },
|
||||
order: { createdAt: 'DESC' },
|
||||
})
|
||||
}
|
||||
|
||||
export const deleteNewsletterEmail = async (id: string): Promise<boolean> => {
|
||||
|
||||
@ -104,6 +104,7 @@ const articlesQuery = (after = '', order = 'ASCENDING') => {
|
||||
id
|
||||
url
|
||||
linkId
|
||||
originalArticleUrl
|
||||
labels {
|
||||
id
|
||||
name
|
||||
@ -360,6 +361,8 @@ describe('Article API', () => {
|
||||
})
|
||||
|
||||
describe('GetArticles', () => {
|
||||
const url = 'https://blog.omnivore.app/p/getting-started-with-omnivore'
|
||||
|
||||
let query = ''
|
||||
let after = ''
|
||||
let pages: Page[] = []
|
||||
@ -380,7 +383,7 @@ describe('Article API', () => {
|
||||
updatedAt: new Date(),
|
||||
readingProgressPercent: 100,
|
||||
readingProgressAnchorIndex: 0,
|
||||
url: 'https://blog.omnivore.app/p/getting-started-with-omnivore',
|
||||
url: url,
|
||||
savedAt: new Date(),
|
||||
} as Page
|
||||
const pageId = await createPage(page, ctx)
|
||||
@ -406,6 +409,14 @@ describe('Article API', () => {
|
||||
query = articlesQuery(after)
|
||||
})
|
||||
|
||||
it('should return originalArticleUrl', async () => {
|
||||
const res = await graphqlRequest(query, authToken).expect(200)
|
||||
|
||||
expect(res.body.data.articles.edges[0].node.originalArticleUrl).to.eql(
|
||||
url
|
||||
)
|
||||
})
|
||||
|
||||
context('when there are pages with labels', () => {
|
||||
before(() => {
|
||||
// get the last page
|
||||
|
||||
@ -61,16 +61,18 @@ describe('Newsletters API', () => {
|
||||
}
|
||||
`
|
||||
|
||||
it('responds with newsletter emails', async () => {
|
||||
it('responds with newsletter emails sort by created_at desc', async () => {
|
||||
const response = await graphqlRequest(query, authToken).expect(200)
|
||||
expect(response.body.data.newsletterEmails.newsletterEmails).to.eqls(
|
||||
newsletterEmails.map((value) => {
|
||||
return {
|
||||
id: value.id,
|
||||
address: value.address,
|
||||
confirmationCode: value.confirmationCode,
|
||||
}
|
||||
})
|
||||
newsletterEmails
|
||||
.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime())
|
||||
.map((value) => {
|
||||
return {
|
||||
id: value.id,
|
||||
address: value.address,
|
||||
confirmationCode: value.confirmationCode,
|
||||
}
|
||||
})
|
||||
)
|
||||
})
|
||||
|
||||
|
||||
@ -33,7 +33,6 @@ const App = () => {
|
||||
className="disable-webkit-callout"
|
||||
>
|
||||
<ArticleContainer
|
||||
viewerUsername="test"
|
||||
article={window.omnivoreArticle}
|
||||
scrollElementRef={React.createRef()}
|
||||
isAppleAppEmbed={true}
|
||||
|
||||
13
packages/db/migrations/0075.do.add_created_at_to_newsletter_emails.sql
Executable file
13
packages/db/migrations/0075.do.add_created_at_to_newsletter_emails.sql
Executable file
@ -0,0 +1,13 @@
|
||||
-- Type: DO
|
||||
-- Name: add_created_at_to_newsletter_emails
|
||||
-- Description: Add created_at and updated_at fields to newsletter_emails table
|
||||
|
||||
BEGIN;
|
||||
|
||||
ALTER TABLE omnivore.newsletter_emails
|
||||
ADD COLUMN created_at timestamptz NOT NULL default current_timestamp,
|
||||
ADD COLUMN updated_at timestamptz NOT NULL default current_timestamp;
|
||||
|
||||
CREATE TRIGGER newsletter_emails_modtime BEFORE UPDATE ON omnivore.newsletter_emails FOR EACH ROW EXECUTE PROCEDURE update_updated_at_column();
|
||||
|
||||
COMMIT;
|
||||
11
packages/db/migrations/0075.undo.add_created_at_to_newsletter_emails.sql
Executable file
11
packages/db/migrations/0075.undo.add_created_at_to_newsletter_emails.sql
Executable file
@ -0,0 +1,11 @@
|
||||
-- Type: UNDO
|
||||
-- Name: add_created_at_to_newsletter_emails
|
||||
-- Description: Add created_at and updated_at fields to newsletter_emails table
|
||||
|
||||
BEGIN;
|
||||
|
||||
ALTER TABLE omnivore.newsletter_emails
|
||||
DROP COLUMN created_at,
|
||||
DROP COLUMN updated_at;
|
||||
|
||||
COMMIT;
|
||||
@ -10,7 +10,7 @@
|
||||
"axios": "^0.26.0",
|
||||
"chrome-aws-lambda": "^7.0.0",
|
||||
"dotenv": "^8.2.0",
|
||||
"jsdom": "^17.0.0",
|
||||
"jsdom": "^19.0.0",
|
||||
"jsonwebtoken": "^8.5.1",
|
||||
"luxon": "^1.26.0",
|
||||
"puppeteer-core": "^7.1.0",
|
||||
|
||||
@ -27,7 +27,7 @@
|
||||
"chai": "^2.1.*",
|
||||
"htmltidy2": "^0.3.0",
|
||||
"js-beautify": "^1.13.0",
|
||||
"jsdom": "^13.1",
|
||||
"jsdom": "^19.0",
|
||||
"mocha": "^8.2.0",
|
||||
"puppeteer": "^10.1.0",
|
||||
"sinon": "^7.3.2"
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
import { StyledText } from './StyledText'
|
||||
|
||||
type LabelProps = {
|
||||
type LabelChipProps = {
|
||||
text: string
|
||||
color: string // expected to be a RGB hex color string
|
||||
}
|
||||
|
||||
export function Label(props: LabelProps): JSX.Element {
|
||||
export function LabelChip(props: LabelChipProps): JSX.Element {
|
||||
const hexToRgb = (hex: string) => {
|
||||
const bigint = parseInt(hex.substring(1), 16)
|
||||
const r = (bigint >> 16) & 255
|
||||
@ -69,10 +69,10 @@ function LoadedContent(props: LoadedContentProps): JSX.Element {
|
||||
return props.publicArticle.highlights.length - 1
|
||||
}, [props.publicArticle.highlights])
|
||||
|
||||
const sharedBy = useMemo(() => {
|
||||
if (moreHighlightsCount < 1) return undefined
|
||||
return props.publicArticle.highlights[0].user
|
||||
}, [moreHighlightsCount, props.publicArticle.highlights])
|
||||
// const sharedBy = useMemo(() => {
|
||||
// if (moreHighlightsCount < 1) return undefined
|
||||
// return props.publicArticle.highlights[0].user
|
||||
// }, [moreHighlightsCount, props.publicArticle.highlights])
|
||||
|
||||
const articleSite = useMemo(() => {
|
||||
try {
|
||||
@ -124,7 +124,7 @@ function LoadedContent(props: LoadedContentProps): JSX.Element {
|
||||
site={articleSite}
|
||||
/>
|
||||
|
||||
{!showAllHighlights && moreHighlightsCount > 0 && sharedBy && (
|
||||
{!showAllHighlights && moreHighlightsCount > 0 && (
|
||||
<Button onClick={() => setShowAllHighlights(true)}>
|
||||
<Box
|
||||
css={{ width: '8px', color: '$grayBackground', mr: '4px' }}
|
||||
@ -132,7 +132,7 @@ function LoadedContent(props: LoadedContentProps): JSX.Element {
|
||||
/>
|
||||
Read {moreHighlightsCount} more highlight
|
||||
{moreHighlightsCount > 1 ? 's ' : ' '}
|
||||
from {sharedBy.name}
|
||||
{/* from {sharedBy.name} */}
|
||||
</Button>
|
||||
)}
|
||||
|
||||
|
||||
@ -15,7 +15,7 @@ import {
|
||||
import { Tweet } from 'react-twitter-widgets'
|
||||
import { render } from 'react-dom'
|
||||
import { isDarkTheme } from '../../../lib/themeUpdater'
|
||||
import { debounce } from 'lodash'
|
||||
import debounce from 'lodash/debounce'
|
||||
import { ArticleMutations } from '../../../lib/articleActions'
|
||||
|
||||
export type ArticleProps = {
|
||||
|
||||
@ -10,19 +10,11 @@ import { MutableRefObject, useEffect, useState } from 'react'
|
||||
import { ReportIssuesModal } from './ReportIssuesModal'
|
||||
import { reportIssueMutation } from '../../../lib/networking/mutations/reportIssueMutation'
|
||||
import { ArticleHeaderToolbar } from './ArticleHeaderToolbar'
|
||||
import { articleKeyboardCommands } from '../../../lib/keyboardShortcuts/navigationShortcuts'
|
||||
import { useKeyboardShortcuts } from '../../../lib/keyboardShortcuts/useKeyboardShortcuts'
|
||||
import { ShareArticleModal } from './ShareArticleModal'
|
||||
import { userPersonalizationMutation } from '../../../lib/networking/mutations/userPersonalizationMutation'
|
||||
import { webBaseURL } from '../../../lib/appConfig'
|
||||
import { updateThemeLocally } from '../../../lib/themeUpdater'
|
||||
import { EditLabelsModal } from './EditLabelsModal'
|
||||
import Script from 'next/script'
|
||||
import { useRouter } from 'next/router'
|
||||
import { ArticleMutations } from '../../../lib/articleActions'
|
||||
|
||||
type ArticleContainerProps = {
|
||||
viewerUsername: string
|
||||
article: ArticleAttributes
|
||||
articleMutations: ArticleMutations
|
||||
scrollElementRef: MutableRefObject<HTMLDivElement | null>
|
||||
@ -35,7 +27,6 @@ type ArticleContainerProps = {
|
||||
}
|
||||
|
||||
export function ArticleContainer(props: ArticleContainerProps): JSX.Element {
|
||||
const router = useRouter()
|
||||
const [showShareModal, setShowShareModal] = useState(false)
|
||||
const [showLabelsModal, setShowLabelsModal] = useState(false)
|
||||
const [showNotesSidebar, setShowNotesSidebar] = useState(false)
|
||||
@ -50,28 +41,6 @@ export function ArticleContainer(props: ArticleContainerProps): JSX.Element {
|
||||
await userPersonalizationMutation({ fontSize: newFontSize })
|
||||
}
|
||||
|
||||
useKeyboardShortcuts(
|
||||
articleKeyboardCommands(router, async (action) => {
|
||||
switch (action) {
|
||||
case 'openOriginalArticle':
|
||||
const url = props.article.url
|
||||
if (url) {
|
||||
window.open(url, '_blank')
|
||||
}
|
||||
break
|
||||
case 'incrementFontSize':
|
||||
await updateFontSize(Math.min(fontSize + 2, 28))
|
||||
break
|
||||
case 'decrementFontSize':
|
||||
await updateFontSize(Math.max(fontSize - 2, 10))
|
||||
break
|
||||
case 'editLabels':
|
||||
setShowLabelsModal(true)
|
||||
break
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
// Listen for font size and color mode change events sent from host apps (ios, macos...)
|
||||
useEffect(() => {
|
||||
const increaseFontSize = async () => {
|
||||
@ -123,16 +92,6 @@ export function ArticleContainer(props: ArticleContainerProps): JSX.Element {
|
||||
|
||||
return (
|
||||
<>
|
||||
{!props.isAppleAppEmbed && (
|
||||
<>
|
||||
<Script async src="/static/scripts/mathJaxConfiguration.js" />
|
||||
<Script
|
||||
async
|
||||
id="MathJax-script"
|
||||
src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
<Box
|
||||
id="article-container"
|
||||
css={{
|
||||
@ -213,7 +172,6 @@ export function ArticleContainer(props: ArticleContainerProps): JSX.Element {
|
||||
<Box css={{ height: '100px' }} />
|
||||
</Box>
|
||||
<HighlightsLayer
|
||||
viewerUsername={props.viewerUsername}
|
||||
highlights={props.article.highlights}
|
||||
articleTitle={props.article.title}
|
||||
articleAuthor={props.article.author ?? ''}
|
||||
@ -238,7 +196,7 @@ export function ArticleContainer(props: ArticleContainerProps): JSX.Element {
|
||||
onOpenChange={(open: boolean) => setShowReportIssuesModal(open)}
|
||||
/>
|
||||
) : null}
|
||||
{showShareModal && (
|
||||
{/* {showShareModal && (
|
||||
<ShareArticleModal
|
||||
url={`${webBaseURL}/${props.viewerUsername}/${props.article.slug}/highlights?r=true`}
|
||||
title={props.article.title}
|
||||
@ -249,19 +207,7 @@ export function ArticleContainer(props: ArticleContainerProps): JSX.Element {
|
||||
originalArticleUrl={props.article.originalArticleUrl}
|
||||
onOpenChange={(open: boolean) => setShowShareModal(open)}
|
||||
/>
|
||||
)}
|
||||
{showLabelsModal && (
|
||||
<EditLabelsModal
|
||||
labels={labels}
|
||||
article={props.article}
|
||||
onOpenChange={() => {
|
||||
setShowLabelsModal(false)
|
||||
}}
|
||||
setLabels={(labels: string[]) => {
|
||||
setLabels(labels)
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
)} */}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@ -10,15 +10,16 @@ import { CrossIcon } from '../../elements/images/CrossIcon'
|
||||
import { theme } from '../../tokens/stitches.config'
|
||||
import { useGetLabelsQuery } from '../../../lib/networking/queries/useGetLabelsQuery'
|
||||
import { ChangeEvent, useCallback, useState } from 'react'
|
||||
import { Label } from '../../elements/Label'
|
||||
import { setLabelsMutation } from '../../../lib/networking/mutations/setLabelsMutation'
|
||||
import { ArticleAttributes } from '../../../lib/networking/queries/useGetArticleQuery'
|
||||
import { Label } from '../../../lib/networking/fragments/labelFragment'
|
||||
import { LabelChip } from '../../elements/LabelChip'
|
||||
|
||||
type EditLabelsModalProps = {
|
||||
labels: string[]
|
||||
labels: Label[]
|
||||
article: ArticleAttributes
|
||||
onOpenChange: (open: boolean) => void
|
||||
setLabels: (labels: string[]) => void
|
||||
setLabels: (labels: Label[]) => void
|
||||
}
|
||||
|
||||
export function EditLabelsModal(props: EditLabelsModalProps): JSX.Element {
|
||||
@ -26,7 +27,7 @@ export function EditLabelsModal(props: EditLabelsModalProps): JSX.Element {
|
||||
const { labels } = useGetLabelsQuery()
|
||||
|
||||
const saveAndExit = useCallback(async () => {
|
||||
const result = await setLabelsMutation(props.article.id, selectedLabels)
|
||||
const result = await setLabelsMutation(props.article.id, selectedLabels.map((l) => l.id))
|
||||
console.log('result of setting labels', result)
|
||||
props.onOpenChange(false)
|
||||
props.setLabels(selectedLabels)
|
||||
@ -34,12 +35,12 @@ export function EditLabelsModal(props: EditLabelsModalProps): JSX.Element {
|
||||
|
||||
const handleChange = useCallback(
|
||||
(event: ChangeEvent<HTMLInputElement>) => {
|
||||
const label = event.target.value
|
||||
if (event.target.checked) {
|
||||
setSelectedLabels([...selectedLabels, label])
|
||||
} else {
|
||||
setSelectedLabels(selectedLabels.filter((l) => l !== label))
|
||||
}
|
||||
// const label = event.target.value
|
||||
// if (event.target.checked) {
|
||||
// setSelectedLabels([...selectedLabels, label])
|
||||
// } else {
|
||||
// setSelectedLabels(selectedLabels.filter((l) => l !== label))
|
||||
// }
|
||||
},
|
||||
[selectedLabels]
|
||||
)
|
||||
@ -81,21 +82,21 @@ export function EditLabelsModal(props: EditLabelsModalProps): JSX.Element {
|
||||
key={label.id}
|
||||
css={{ height: '50px', verticalAlign: 'middle' }}
|
||||
onClick={() => {
|
||||
if (selectedLabels.includes(label.id)) {
|
||||
setSelectedLabels(
|
||||
selectedLabels.filter((id) => id !== label.id)
|
||||
)
|
||||
} else {
|
||||
setSelectedLabels([...selectedLabels, label.id])
|
||||
}
|
||||
// if (selectedLabels.includes(label.id)) {
|
||||
// setSelectedLabels(
|
||||
// selectedLabels.filter((id) => id !== label.id)
|
||||
// )
|
||||
// } else {
|
||||
// setSelectedLabels([...selectedLabels, label.id])
|
||||
// }
|
||||
}}
|
||||
>
|
||||
<Label color={label.color} text={label.name} />
|
||||
<LabelChip color={label.color} text={label.name} />
|
||||
<input
|
||||
type="checkbox"
|
||||
value={label.id}
|
||||
onChange={handleChange}
|
||||
checked={selectedLabels.includes(label.id)}
|
||||
checked={selectedLabels.includes(label)}
|
||||
/>
|
||||
</HStack>
|
||||
))}
|
||||
|
||||
@ -17,7 +17,7 @@ import { readableUpdatedAtMessage } from './../../../lib/dateFormatting'
|
||||
import { useConfirmListener } from '../../../lib/keyboardShortcuts/useKeyboardShortcuts'
|
||||
import { createHighlight } from '../../../lib/highlights/createHighlight'
|
||||
import { createHighlightMutation } from '../../../lib/networking/mutations/createHighlightMutation'
|
||||
import toast from 'react-hot-toast'
|
||||
import { showErrorToast } from '../../../lib/toastHelpers'
|
||||
|
||||
type HighlightNoteModalProps = {
|
||||
author: string
|
||||
@ -59,14 +59,14 @@ export function HighlightNoteModal(
|
||||
props.onUpdate({ ...props.highlight, annotation: noteContent })
|
||||
props.onOpenChange(false)
|
||||
} else {
|
||||
toast.error('Error updating your note', { position: 'bottom-right' })
|
||||
showErrorToast('Error updating your note', { position: 'bottom-right' })
|
||||
}
|
||||
} if (!props.highlight && props.createHighlightForNote) {
|
||||
const result = await props.createHighlightForNote(noteContent)
|
||||
if (result) {
|
||||
props.onOpenChange(true)
|
||||
} else {
|
||||
toast.error('Error saving highlight', { position: 'bottom-right' })
|
||||
showErrorToast('Error saving highlight', { position: 'bottom-right' })
|
||||
}
|
||||
} else {
|
||||
props.onOpenChange(false)
|
||||
|
||||
@ -3,8 +3,6 @@ import { makeHighlightStartEndOffset } from '../../../lib/highlights/highlightGe
|
||||
import type { HighlightLocation } from '../../../lib/highlights/highlightGenerator'
|
||||
import { useSelection } from '../../../lib/highlights/useSelection'
|
||||
import type { Highlight } from '../../../lib/networking/fragments/highlightFragment'
|
||||
import { shareHighlightToFeedMutation } from '../../../lib/networking/mutations/shareHighlightToFeedMutation'
|
||||
import { shareHighlightCommentMutation } from '../../../lib/networking/mutations/updateShareHighlightCommentMutation'
|
||||
import {
|
||||
highlightIdAttribute,
|
||||
highlightNoteIdAttribute,
|
||||
@ -15,14 +13,12 @@ import { removeHighlights } from '../../../lib/highlights/deleteHighlight'
|
||||
import { createHighlight } from '../../../lib/highlights/createHighlight'
|
||||
import { HighlightNoteModal } from './HighlightNoteModal'
|
||||
import { ShareHighlightModal } from './ShareHighlightModal'
|
||||
import { HighlightPostToFeedModal } from './HighlightPostToFeedModal'
|
||||
import { HighlightsModal } from './HighlightsModal'
|
||||
import { useCanShareNative } from '../../../lib/hooks/useCanShareNative'
|
||||
import toast from 'react-hot-toast'
|
||||
import { showErrorToast } from '../../../lib/toastHelpers'
|
||||
import { ArticleMutations } from '../../../lib/articleActions'
|
||||
|
||||
type HighlightsLayerProps = {
|
||||
viewerUsername: string
|
||||
highlights: Highlight[]
|
||||
articleId: string
|
||||
articleTitle: string
|
||||
@ -35,7 +31,7 @@ type HighlightsLayerProps = {
|
||||
articleMutations: ArticleMutations
|
||||
}
|
||||
|
||||
type HighlightModalAction = 'none' | 'addComment' | 'postToFeed' | 'share'
|
||||
type HighlightModalAction = 'none' | 'addComment' | 'share'
|
||||
|
||||
type HighlightActionProps = {
|
||||
highlight?: Highlight
|
||||
@ -113,32 +109,6 @@ export function HighlightsLayer(props: HighlightsLayerProps): JSX.Element {
|
||||
[highlights, highlightLocations]
|
||||
)
|
||||
|
||||
const postToFeedCallback = useCallback(
|
||||
async (highlight: Highlight, annotation: string | undefined) => {
|
||||
await shareHighlightToFeedMutation({
|
||||
id: highlight.id,
|
||||
share: highlight.sharedAt == undefined,
|
||||
})
|
||||
|
||||
await shareHighlightCommentMutation({
|
||||
highlightId: highlight.id,
|
||||
annotation,
|
||||
})
|
||||
|
||||
// Toggle the sharedAt field after mutating the highlight
|
||||
const mutatedHighlight = highlight
|
||||
mutatedHighlight.sharedAt = highlight.sharedAt
|
||||
? undefined
|
||||
: new Date().toISOString()
|
||||
mutatedHighlight.annotation = annotation
|
||||
const unmutatedHighlights = highlights.filter(
|
||||
($0) => $0.id !== highlight.id
|
||||
)
|
||||
setHighlights([...unmutatedHighlights, mutatedHighlight])
|
||||
},
|
||||
[highlights]
|
||||
)
|
||||
|
||||
const handleNativeShare = useCallback(
|
||||
(highlightID: string) => {
|
||||
navigator
|
||||
@ -220,7 +190,7 @@ export function HighlightsLayer(props: HighlightsLayerProps): JSX.Element {
|
||||
annotation
|
||||
)
|
||||
if (!result) {
|
||||
toast.error('Error saving highlight', { position: 'bottom-right' })
|
||||
showErrorToast('Error saving highlight', { position: 'bottom-right' })
|
||||
}
|
||||
// if (successAction === 'share' && canShareNative) {
|
||||
// handleNativeShare(highlight.shortId)
|
||||
@ -348,16 +318,6 @@ export function HighlightsLayer(props: HighlightsLayerProps): JSX.Element {
|
||||
createHighlightCallback('share')
|
||||
}
|
||||
break
|
||||
case 'post':
|
||||
if (focusedHighlight) {
|
||||
setHighlightModalAction({
|
||||
highlight: focusedHighlight,
|
||||
highlightModalAction: 'postToFeed',
|
||||
})
|
||||
} else {
|
||||
createHighlightCallback('postToFeed')
|
||||
}
|
||||
break
|
||||
case 'unshare':
|
||||
console.log('unshare')
|
||||
break // TODO: implement -- need to show confirmation dialog
|
||||
@ -460,23 +420,6 @@ export function HighlightsLayer(props: HighlightsLayerProps): JSX.Element {
|
||||
)
|
||||
}
|
||||
|
||||
if (
|
||||
highlightModalAction?.highlightModalAction == 'postToFeed' &&
|
||||
highlightModalAction.highlight
|
||||
) {
|
||||
return (
|
||||
<HighlightPostToFeedModal
|
||||
highlight={highlightModalAction.highlight}
|
||||
author={props.articleAuthor}
|
||||
title={props.articleTitle}
|
||||
onCommit={postToFeedCallback}
|
||||
onOpenChange={() =>
|
||||
setHighlightModalAction({ highlightModalAction: 'none' })
|
||||
}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
if (
|
||||
highlightModalAction?.highlightModalAction == 'share' &&
|
||||
highlightModalAction.highlight
|
||||
|
||||
@ -4,7 +4,7 @@ import { Button } from '../../elements/Button'
|
||||
import { StyledText } from '../../elements/StyledText'
|
||||
import { X, Check } from 'phosphor-react'
|
||||
import { useState } from 'react'
|
||||
import toast from 'react-hot-toast'
|
||||
import { showErrorToast } from '../../../lib/toastHelpers'
|
||||
|
||||
type ShareArticleModalProps = {
|
||||
onOpenChange: (open: boolean) => void
|
||||
@ -149,7 +149,7 @@ export function SnoozeLinkModal(
|
||||
props.submit(snoozeOption, sendReminder, msg)
|
||||
props.onOpenChange(false)
|
||||
} else {
|
||||
toast.error('No option selected', { position: 'bottom-right' })
|
||||
showErrorToast('No option selected', { position: 'bottom-right' })
|
||||
}
|
||||
}}
|
||||
>Save</Button>
|
||||
@ -158,4 +158,4 @@ export function SnoozeLinkModal(
|
||||
</ModalContent>
|
||||
</ModalRoot>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -13,6 +13,7 @@ import { useState, useCallback } from 'react'
|
||||
import { createArticleFromURLMutation } from '../../../lib/networking/mutations/createArticleFromURLMutation'
|
||||
import { saveUrlMutation } from '../../../lib/networking/mutations/saveUrlMutation'
|
||||
import toast from 'react-hot-toast'
|
||||
import { showErrorToast } from '../../../lib/toastHelpers'
|
||||
|
||||
type AddLinkModalProps = {
|
||||
onOpenChange: (open: boolean) => void
|
||||
@ -42,7 +43,7 @@ export function AddLinkModal(props: AddLinkModalProps): JSX.Element {
|
||||
</Box>
|
||||
), { position: 'bottom-right' })
|
||||
} else {
|
||||
toast.error('Error saving link', { position: 'bottom-right' })
|
||||
showErrorToast('Error saving link', { position: 'bottom-right' })
|
||||
}
|
||||
}, [link])
|
||||
|
||||
@ -100,7 +101,7 @@ export function AddLinkModal(props: AddLinkModalProps): JSX.Element {
|
||||
// `https` to give the link a protocol.
|
||||
const newLink = `https://${link}`
|
||||
if (!validateLink(newLink)) {
|
||||
toast.error('Invalid link', { position: 'bottom-right' })
|
||||
showErrorToast('Invalid link', { position: 'bottom-right' })
|
||||
return
|
||||
}
|
||||
setLink(newLink)
|
||||
|
||||
@ -27,7 +27,7 @@ import { ShareArticleModal } from '../article/ShareArticleModal'
|
||||
import { userPersonalizationMutation } from '../../../lib/networking/mutations/userPersonalizationMutation'
|
||||
import { useGetUserPreferences } from '../../../lib/networking/queries/useGetUserPreferences'
|
||||
import { webBaseURL } from '../../../lib/appConfig'
|
||||
import toast, { Toaster } from 'react-hot-toast'
|
||||
import { Toaster } from 'react-hot-toast'
|
||||
import { SnoozeLinkModal } from '../article/SnoozeLinkModal'
|
||||
import {
|
||||
createReminderMutation,
|
||||
@ -35,6 +35,7 @@ import {
|
||||
} from '../../../lib/networking/mutations/createReminderMutation'
|
||||
import { useFetchMoreScroll } from '../../../lib/hooks/useFetchMoreScroll'
|
||||
import { usePersistedState } from '../../../lib/hooks/usePersistedState'
|
||||
import { showErrorToast, showSuccessToast } from '../../../lib/toastHelpers'
|
||||
|
||||
export type LayoutType = 'LIST_LAYOUT' | 'GRID_LAYOUT'
|
||||
|
||||
@ -654,10 +655,10 @@ function HomeFeedGrid(props: HomeFeedContentProps): JSX.Element {
|
||||
return props.actionHandler('archive', props.snoozeTarget)
|
||||
})
|
||||
.then(() => {
|
||||
toast.success(msg, { position: 'bottom-right' })
|
||||
showSuccessToast(msg, { position: 'bottom-right' })
|
||||
})
|
||||
.catch((error) => {
|
||||
toast.error('There was an error snoozing your link.', {
|
||||
showErrorToast('There was an error snoozing your link.', {
|
||||
position: 'bottom-right',
|
||||
})
|
||||
})
|
||||
|
||||
@ -8,7 +8,7 @@ import { UpdateHighlightInput } from "./networking/mutations/updateHighlightMuta
|
||||
export type ArticleMutations = {
|
||||
createHighlightMutation: (input: CreateHighlightInput) => Promise<Highlight | undefined>
|
||||
deleteHighlightMutation: (highlightId: string) => Promise<boolean>
|
||||
mergeHighlightMutation: (input: MergeHighlightInput) => Promise<MergeHighlightOutput | undefined>
|
||||
mergeHighlightMutation: (input: MergeHighlightInput) => Promise<Highlight | undefined>
|
||||
updateHighlightMutation: (input: UpdateHighlightInput) => Promise<string | undefined>
|
||||
articleReadingProgressMutation: (input: ArticleReadingProgressMutationInput) => Promise<boolean>
|
||||
}
|
||||
@ -89,12 +89,11 @@ export async function createHighlight(
|
||||
let keptHighlights = input.existingHighlights
|
||||
|
||||
if (shouldMerge) {
|
||||
const result = await articleMutations.mergeHighlightMutation({
|
||||
highlight = await articleMutations.mergeHighlightMutation({
|
||||
...newHighlightAttributes,
|
||||
overlapHighlightIdList: input.selection.overlapHighlights,
|
||||
})
|
||||
|
||||
highlight = result?.mergeHighlight.highlight
|
||||
keptHighlights = input.existingHighlights.filter(
|
||||
($0) => !input.selection.overlapHighlights.includes($0.id)
|
||||
)
|
||||
|
||||
@ -67,12 +67,16 @@ function nodeAttributesFromHighlight(
|
||||
const patch = highlight.patch
|
||||
const id = highlight.id
|
||||
const withNote = !!highlight.annotation
|
||||
const customColor = !highlight.createdByMe
|
||||
? stringToColour(highlight.user.profile.username)
|
||||
: undefined
|
||||
const tooltip = !highlight.createdByMe
|
||||
? `Created by: @${highlight.user.profile.username}`
|
||||
: undefined
|
||||
const customColor = undefined
|
||||
const tooltip = undefined
|
||||
// We've disabled shared highlights, so passing undefined
|
||||
// here now, and removing the user object from highlights
|
||||
// !highlight.createdByMe
|
||||
// ? stringToColour(highlight.user.profile.username)
|
||||
// : undefined
|
||||
// const tooltip = !highlight.createdByMe
|
||||
// ? `Created by: @${highlight.user.profile.username}`
|
||||
// : undefined
|
||||
|
||||
return makeHighlightNodeAttributes(patch, id, withNote, customColor, tooltip)
|
||||
}
|
||||
|
||||
@ -9,19 +9,9 @@ export const highlightFragment = gql`
|
||||
suffix
|
||||
patch
|
||||
annotation
|
||||
createdAt
|
||||
createdByMe
|
||||
updatedAt
|
||||
sharedAt
|
||||
user {
|
||||
id
|
||||
name
|
||||
profile {
|
||||
id
|
||||
pictureUrl
|
||||
username
|
||||
}
|
||||
}
|
||||
createdByMe
|
||||
}
|
||||
`
|
||||
|
||||
@ -33,11 +23,9 @@ export type Highlight = {
|
||||
suffix?: string
|
||||
patch: string
|
||||
annotation?: string
|
||||
createdAt: string
|
||||
updatedAt: string
|
||||
user: User
|
||||
createdByMe: boolean
|
||||
sharedAt?: string
|
||||
updatedAt: string
|
||||
sharedAt: string
|
||||
}
|
||||
|
||||
export type User = {
|
||||
|
||||
@ -6,6 +6,7 @@ export const labelFragment = gql`
|
||||
name
|
||||
color
|
||||
description
|
||||
createdAt
|
||||
}
|
||||
`
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { gql } from 'graphql-request'
|
||||
import { gqlFetcher } from '../networkHelpers'
|
||||
import { Highlight } from './../fragments/highlightFragment'
|
||||
import { Highlight, highlightFragment } from './../fragments/highlightFragment'
|
||||
|
||||
export type CreateHighlightInput = {
|
||||
prefix: string
|
||||
@ -28,7 +28,7 @@ export async function createHighlightMutation(
|
||||
createHighlight(input: $input) {
|
||||
... on CreateHighlightSuccess {
|
||||
highlight {
|
||||
...NewHighlight
|
||||
...HighlightFields
|
||||
}
|
||||
}
|
||||
|
||||
@ -37,7 +37,7 @@ export async function createHighlightMutation(
|
||||
}
|
||||
}
|
||||
}
|
||||
${NewHighlightFragment}
|
||||
${highlightFragment}
|
||||
`
|
||||
|
||||
try {
|
||||
@ -48,28 +48,3 @@ export async function createHighlightMutation(
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
|
||||
const NewHighlightFragment = gql`
|
||||
fragment NewHighlight on Highlight {
|
||||
id
|
||||
shortId
|
||||
quote
|
||||
prefix
|
||||
suffix
|
||||
patch
|
||||
createdAt
|
||||
updatedAt
|
||||
annotation
|
||||
sharedAt
|
||||
user {
|
||||
id
|
||||
name
|
||||
profile {
|
||||
id
|
||||
pictureUrl
|
||||
username
|
||||
}
|
||||
}
|
||||
createdByMe
|
||||
}
|
||||
`
|
||||
|
||||
@ -25,7 +25,7 @@ type InnerMergeHighlightOutput = {
|
||||
|
||||
export async function mergeHighlightMutation(
|
||||
input: MergeHighlightInput
|
||||
): Promise<MergeHighlightOutput | undefined> {
|
||||
): Promise<Highlight | undefined> {
|
||||
const mutation = gql`
|
||||
mutation MergeHighlight($input: MergeHighlightInput!) {
|
||||
mergeHighlight(input: $input) {
|
||||
@ -41,15 +41,6 @@ export async function mergeHighlightMutation(
|
||||
updatedAt
|
||||
annotation
|
||||
sharedAt
|
||||
user {
|
||||
id
|
||||
name
|
||||
profile {
|
||||
id
|
||||
pictureUrl
|
||||
username
|
||||
}
|
||||
}
|
||||
createdByMe
|
||||
}
|
||||
overlapHighlightIdList
|
||||
@ -63,7 +54,8 @@ export async function mergeHighlightMutation(
|
||||
|
||||
try {
|
||||
const data = await gqlFetcher(mutation, { input })
|
||||
return data as MergeHighlightOutput | undefined
|
||||
const output = data as MergeHighlightOutput | undefined
|
||||
return output?.mergeHighlight.highlight
|
||||
} catch {
|
||||
return undefined
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import { gql } from 'graphql-request'
|
||||
import useSWR from 'swr'
|
||||
import { Label, labelFragment } from '../fragments/labelFragment'
|
||||
import { publicGqlFetcher } from '../networkHelpers'
|
||||
|
||||
type LabelsQueryResponse = {
|
||||
@ -16,25 +17,13 @@ type LabelsData = {
|
||||
labels?: unknown
|
||||
}
|
||||
|
||||
export type Label = {
|
||||
id: string
|
||||
name: string
|
||||
color: string
|
||||
description?: string
|
||||
createdAt: Date
|
||||
}
|
||||
|
||||
export function useGetLabelsQuery(): LabelsQueryResponse {
|
||||
const query = gql`
|
||||
query GetLabels {
|
||||
labels {
|
||||
... on LabelsSuccess {
|
||||
labels {
|
||||
id
|
||||
name
|
||||
color
|
||||
description
|
||||
createdAt
|
||||
...LabelFields
|
||||
}
|
||||
}
|
||||
... on LabelsError {
|
||||
@ -42,6 +31,7 @@ export function useGetLabelsQuery(): LabelsQueryResponse {
|
||||
}
|
||||
}
|
||||
}
|
||||
${labelFragment}
|
||||
`
|
||||
|
||||
const { data, mutate, error, isValidating } = useSWR(query, publicGqlFetcher)
|
||||
|
||||
@ -6,7 +6,8 @@ import { articleFragment } from '../fragments/articleFragment'
|
||||
import { setLinkArchivedMutation } from '../mutations/setLinkArchivedMutation'
|
||||
import { deleteLinkMutation } from '../mutations/deleteLinkMutation'
|
||||
import { articleReadingProgressMutation } from '../mutations/articleReadingProgressMutation'
|
||||
import { Label } from './useGetLabelsQuery'
|
||||
import { Label } from './../fragments/labelFragment'
|
||||
import { showErrorToast, showSuccessToast } from '../../toastHelpers'
|
||||
|
||||
export type LibraryItemsQueryInput = {
|
||||
limit: number
|
||||
@ -206,6 +207,12 @@ export function useGetLibraryItemsQuery({
|
||||
setLinkArchivedMutation({
|
||||
linkId: item.node.id,
|
||||
archived: true,
|
||||
}).then((res) => {
|
||||
if (res) {
|
||||
showSuccessToast('Link archived', { position: 'bottom-right' })
|
||||
} else {
|
||||
showErrorToast('Error archiving link', { position: 'bottom-right' })
|
||||
}
|
||||
})
|
||||
|
||||
break
|
||||
@ -225,11 +232,24 @@ export function useGetLibraryItemsQuery({
|
||||
setLinkArchivedMutation({
|
||||
linkId: item.node.id,
|
||||
archived: false,
|
||||
}).then((res) => {
|
||||
if (res) {
|
||||
showSuccessToast('Link unarchived', { position: 'bottom-right' })
|
||||
} else {
|
||||
showErrorToast('Error unarchiving link', { position: 'bottom-right' })
|
||||
}
|
||||
})
|
||||
break
|
||||
case 'delete':
|
||||
updateData(undefined)
|
||||
deleteLinkMutation(item.node.id)
|
||||
.then((res) => {
|
||||
if (res) {
|
||||
showSuccessToast('Link removed', { position: 'bottom-right' })
|
||||
} else {
|
||||
showErrorToast('Error removing link', { position: 'bottom-right' })
|
||||
}
|
||||
})
|
||||
break
|
||||
case 'mark-read':
|
||||
updateData({
|
||||
|
||||
65
packages/web/lib/toastHelpers.tsx
Normal file
65
packages/web/lib/toastHelpers.tsx
Normal file
@ -0,0 +1,65 @@
|
||||
import { toast, ToastOptions } from 'react-hot-toast'
|
||||
import { CheckCircle, WarningCircle, X } from 'phosphor-react'
|
||||
import { Box, HStack } from '../components/elements/LayoutPrimitives'
|
||||
import { styled } from '@stitches/react'
|
||||
|
||||
const toastStyles = {
|
||||
minWidth: 265,
|
||||
height: 56,
|
||||
borderRadius: 4,
|
||||
boxShadow: '0px 2px 8px rgba(32, 31, 29, 0.33)',
|
||||
margin: 0,
|
||||
paddingLeft: 6,
|
||||
paddingRight: 6,
|
||||
paddingTop: 12,
|
||||
paddingBottom: 12,
|
||||
}
|
||||
|
||||
const messageStyles = {
|
||||
fontSize: 14,
|
||||
fontWeight: 'bolder',
|
||||
color: 'white',
|
||||
flex: 1,
|
||||
marginLeft: 16,
|
||||
}
|
||||
|
||||
const MessageContainer = styled(Box, messageStyles)
|
||||
const FullWidthContainer = styled(HStack, {
|
||||
width: '100%',
|
||||
})
|
||||
|
||||
type ToastType = 'success' | 'error'
|
||||
|
||||
const showToast = (
|
||||
message: string,
|
||||
background: string,
|
||||
type: ToastType,
|
||||
options?: ToastOptions
|
||||
) => {
|
||||
return toast(
|
||||
({ id }) => (
|
||||
<FullWidthContainer alignment='center'>
|
||||
{type === 'success' ? <CheckCircle size={24} color='white' /> : <WarningCircle size={24} color='white' />}
|
||||
<MessageContainer>{message}</MessageContainer>
|
||||
<HStack distribution='end' css={{marginLeft: 16}}>
|
||||
<X size={18} style={{cursor: 'pointer'}} color='#CCEAC4' weight='bold' onClick={() => toast.dismiss(id)} />
|
||||
</HStack>
|
||||
</FullWidthContainer>
|
||||
),
|
||||
{
|
||||
style: {
|
||||
...toastStyles,
|
||||
background: background,
|
||||
},
|
||||
duration: 2000,
|
||||
...options,
|
||||
})
|
||||
}
|
||||
|
||||
export const showSuccessToast = (message: string, options?: ToastOptions) => {
|
||||
return showToast(message, '#55B938', 'success', options)
|
||||
}
|
||||
|
||||
export const showErrorToast = (message: string, options?: ToastOptions) => {
|
||||
return showToast(message, '#cc0000', 'error', options)
|
||||
}
|
||||
@ -6,9 +6,9 @@ import { useRouter } from 'next/router'
|
||||
import { VStack } from './../../../components/elements/LayoutPrimitives'
|
||||
import { ArticleContainer } from './../../../components/templates/article/ArticleContainer'
|
||||
import { PdfArticleContainerProps } from './../../../components/templates/article/PdfArticleContainer'
|
||||
import { useRef } from 'react'
|
||||
import { useRef, useState } from 'react'
|
||||
import { useKeyboardShortcuts } from '../../../lib/keyboardShortcuts/useKeyboardShortcuts'
|
||||
import { navigationCommands } from '../../../lib/keyboardShortcuts/navigationShortcuts'
|
||||
import { articleKeyboardCommands, navigationCommands } from '../../../lib/keyboardShortcuts/navigationShortcuts'
|
||||
import dynamic from 'next/dynamic'
|
||||
import { useGetUserPreferences } from '../../../lib/networking/queries/useGetUserPreferences'
|
||||
import { webBaseURL } from '../../../lib/appConfig'
|
||||
@ -18,6 +18,11 @@ import { deleteHighlightMutation } from '../../../lib/networking/mutations/delet
|
||||
import { mergeHighlightMutation } from '../../../lib/networking/mutations/mergeHighlightMutation'
|
||||
import { articleReadingProgressMutation } from '../../../lib/networking/mutations/articleReadingProgressMutation'
|
||||
import { updateHighlightMutation } from '../../../lib/networking/mutations/updateHighlightMutation'
|
||||
import { userPersonalizationMutation } from '../../../lib/networking/mutations/userPersonalizationMutation'
|
||||
import Script from 'next/script'
|
||||
import { EditLabelsModal } from '../../../components/templates/article/EditLabelsModal'
|
||||
import { Label } from '../../../lib/networking/fragments/labelFragment'
|
||||
import { isVipUser } from '../../../lib/featureFlag'
|
||||
|
||||
const PdfArticleContainerNoSSR = dynamic<PdfArticleContainerProps>(
|
||||
() => import('./../../../components/templates/article/PdfArticleContainer'),
|
||||
@ -28,6 +33,7 @@ export default function Home(): JSX.Element {
|
||||
const router = useRouter()
|
||||
const scrollRef = useRef<HTMLDivElement | null>(null)
|
||||
const { slug } = router.query
|
||||
const [showLabelsModal, setShowLabelsModal] = useState(false)
|
||||
|
||||
// Populate data cache
|
||||
const { viewerData } = useGetViewerQuery()
|
||||
@ -38,9 +44,39 @@ export default function Home(): JSX.Element {
|
||||
})
|
||||
const { preferencesData } = useGetUserPreferences()
|
||||
const article = articleData?.article.article
|
||||
const [fontSize, setFontSize] = useState(preferencesData?.fontSize ?? 20)
|
||||
|
||||
useKeyboardShortcuts(navigationCommands(router))
|
||||
|
||||
const updateFontSize = async (newFontSize: number) => {
|
||||
setFontSize(newFontSize)
|
||||
await userPersonalizationMutation({ fontSize: newFontSize })
|
||||
}
|
||||
|
||||
useKeyboardShortcuts(
|
||||
articleKeyboardCommands(router, async (action) => {
|
||||
switch (action) {
|
||||
case 'openOriginalArticle':
|
||||
const url = article?.url
|
||||
if (url) {
|
||||
window.open(url, '_blank')
|
||||
}
|
||||
break
|
||||
case 'incrementFontSize':
|
||||
await updateFontSize(Math.min(fontSize + 2, 28))
|
||||
break
|
||||
case 'decrementFontSize':
|
||||
await updateFontSize(Math.max(fontSize - 2, 10))
|
||||
break
|
||||
case 'editLabels':
|
||||
if (viewerData?.me && isVipUser(viewerData?.me)) {
|
||||
setShowLabelsModal(true)
|
||||
}
|
||||
break
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
if (article && viewerData?.me) {
|
||||
return (
|
||||
<PrimaryLayout
|
||||
@ -53,6 +89,12 @@ export default function Home(): JSX.Element {
|
||||
description: article.description,
|
||||
}}
|
||||
>
|
||||
<Script async src="/static/scripts/mathJaxConfiguration.js" />
|
||||
<Script
|
||||
async
|
||||
id="MathJax-script"
|
||||
src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"
|
||||
/>
|
||||
<Toaster />
|
||||
|
||||
{article.contentReader == 'PDF' ? (
|
||||
@ -72,9 +114,8 @@ export default function Home(): JSX.Element {
|
||||
scrollElementRef={scrollRef}
|
||||
isAppleAppEmbed={false}
|
||||
highlightBarDisabled={false}
|
||||
viewerUsername={viewerData.me?.profile?.username}
|
||||
highlightsBaseURL={`${webBaseURL}/${viewerData.me?.profile?.username}/${slug}/highlights`}
|
||||
fontSize={preferencesData?.fontSize}
|
||||
fontSize={fontSize}
|
||||
articleMutations={{
|
||||
createHighlightMutation,
|
||||
deleteHighlightMutation,
|
||||
@ -83,6 +124,18 @@ export default function Home(): JSX.Element {
|
||||
articleReadingProgressMutation,
|
||||
}}
|
||||
/>
|
||||
{showLabelsModal && (
|
||||
<EditLabelsModal
|
||||
labels={article.labels || []}
|
||||
article={article}
|
||||
onOpenChange={() => {
|
||||
setShowLabelsModal(false)
|
||||
}}
|
||||
setLabels={(labels: Label[]) => {
|
||||
// setLabels(labels)
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</VStack>
|
||||
)}
|
||||
</PrimaryLayout>
|
||||
|
||||
@ -12,6 +12,7 @@ import { deleteHighlightMutation } from '../../../../lib/networking/mutations/de
|
||||
import { mergeHighlightMutation } from '../../../../lib/networking/mutations/mergeHighlightMutation'
|
||||
import { updateHighlightMutation } from '../../../../lib/networking/mutations/updateHighlightMutation'
|
||||
import { articleReadingProgressMutation } from '../../../../lib/networking/mutations/articleReadingProgressMutation'
|
||||
import Script from 'next/script'
|
||||
|
||||
type AppArticleEmbedContentProps = {
|
||||
slug: string
|
||||
@ -78,6 +79,12 @@ function AppArticleEmbedContent(
|
||||
width: '100vw',
|
||||
}}
|
||||
>
|
||||
<Script async src="/static/scripts/mathJaxConfiguration.js" />
|
||||
<Script
|
||||
async
|
||||
id="MathJax-script"
|
||||
src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"
|
||||
/>
|
||||
<VStack
|
||||
alignment="center"
|
||||
distribution="center"
|
||||
@ -88,7 +95,6 @@ function AppArticleEmbedContent(
|
||||
scrollElementRef={scrollRef}
|
||||
isAppleAppEmbed={true}
|
||||
highlightBarDisabled={props.highlightBarDisabled}
|
||||
viewerUsername={props.username}
|
||||
highlightsBaseURL={`${webBaseURL}/${props.username}/${props.slug}/highlights`}
|
||||
fontSize={props.fontSize}
|
||||
margin={props.margin}
|
||||
|
||||
@ -22,6 +22,7 @@ import { toast, Toaster } from 'react-hot-toast'
|
||||
import { useCallback } from 'react'
|
||||
import { StyledText } from '../../components/elements/StyledText'
|
||||
import { applyStoredTheme } from '../../lib/themeUpdater'
|
||||
import { showSuccessToast } from '../../lib/toastHelpers'
|
||||
import Link from 'next/link'
|
||||
|
||||
enum TextType {
|
||||
@ -165,11 +166,7 @@ function CopyTextButton(props: CopyTextButtonProps): JSX.Element {
|
||||
|
||||
const copy = useCallback(() => {
|
||||
copyLink()
|
||||
toast(
|
||||
props.type == TextType.EmailAddress
|
||||
? 'Email Address Copied'
|
||||
: 'Confirmation Code Copied'
|
||||
)
|
||||
showSuccessToast(props.type == TextType.EmailAddress ? 'Email Address Copied' : 'Confirmation Code Copied');
|
||||
}, [])
|
||||
|
||||
return (
|
||||
@ -186,14 +183,14 @@ export default function EmailsPage(): JSX.Element {
|
||||
applyStoredTheme(false)
|
||||
|
||||
async function createEmail(): Promise<void> {
|
||||
showSuccessToast('Email Created')
|
||||
await createNewsletterEmailMutation()
|
||||
revalidate()
|
||||
toast.success('Email Created')
|
||||
}
|
||||
async function deleteEmail(id: string): Promise<void> {
|
||||
await deleteNewsletterEmailMutation(id)
|
||||
revalidate()
|
||||
toast.success('Email Deleted!')
|
||||
showSuccessToast('Email Deleted')
|
||||
}
|
||||
return (
|
||||
<PrimaryLayout pageTestId="settings-emails-tag">
|
||||
|
||||
@ -1,12 +1,13 @@
|
||||
import { PrimaryLayout } from '../../components/templates/PrimaryLayout'
|
||||
import { Button } from '../../components/elements/Button'
|
||||
import { Box, VStack } from '../../components/elements/LayoutPrimitives'
|
||||
import { toast, Toaster } from 'react-hot-toast'
|
||||
import { Toaster } from 'react-hot-toast'
|
||||
import { useGetLabelsQuery } from '../../lib/networking/queries/useGetLabelsQuery'
|
||||
import { createLabelMutation } from '../../lib/networking/mutations/createLabelMutation'
|
||||
import { deleteLabelMutation } from '../../lib/networking/mutations/deleteLabelMutation'
|
||||
import { useState } from 'react'
|
||||
import { applyStoredTheme } from '../../lib/themeUpdater'
|
||||
import { showErrorToast, showSuccessToast } from '../../lib/toastHelpers'
|
||||
|
||||
export default function LabelsPage(): JSX.Element {
|
||||
const { labels, revalidate, isValidating } = useGetLabelsQuery()
|
||||
@ -20,16 +21,16 @@ export default function LabelsPage(): JSX.Element {
|
||||
const res = await createLabelMutation(name, color, description)
|
||||
if (res) {
|
||||
if (res.createLabel.errorCodes && res.createLabel.errorCodes.length > 0) {
|
||||
toast.error(res.createLabel.errorCodes[0])
|
||||
showErrorToast(res.createLabel.errorCodes[0])
|
||||
} else {
|
||||
toast.success('Label created')
|
||||
showSuccessToast('Label created')
|
||||
setName('')
|
||||
setColor('')
|
||||
setDescription('')
|
||||
revalidate()
|
||||
}
|
||||
} else {
|
||||
toast.error('Failed to create label')
|
||||
showErrorToast('Failed to create label')
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
392
yarn.lock
392
yarn.lock
@ -4433,6 +4433,27 @@
|
||||
"@babel/runtime" "^7.13.10"
|
||||
"@radix-ui/react-compose-refs" "0.1.0"
|
||||
|
||||
"@radix-ui/react-tooltip@^0.1.7":
|
||||
version "0.1.7"
|
||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-tooltip/-/react-tooltip-0.1.7.tgz#6f8c00d6e489565d14abf209ce0fb8853c8c8ee3"
|
||||
integrity sha512-eiBUsVOHenZ0JR16tl970bB0DafJBz6mFgSGfIGIVpflFj0LIsIDiLMsYyvYdx1KwwsIUDTEZtxcPm/sWjPzqA==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.13.10"
|
||||
"@radix-ui/primitive" "0.1.0"
|
||||
"@radix-ui/react-compose-refs" "0.1.0"
|
||||
"@radix-ui/react-context" "0.1.1"
|
||||
"@radix-ui/react-id" "0.1.5"
|
||||
"@radix-ui/react-popper" "0.1.4"
|
||||
"@radix-ui/react-portal" "0.1.4"
|
||||
"@radix-ui/react-presence" "0.1.2"
|
||||
"@radix-ui/react-primitive" "0.1.4"
|
||||
"@radix-ui/react-slot" "0.1.2"
|
||||
"@radix-ui/react-use-controllable-state" "0.1.0"
|
||||
"@radix-ui/react-use-escape-keydown" "0.1.0"
|
||||
"@radix-ui/react-use-previous" "0.1.1"
|
||||
"@radix-ui/react-use-rect" "0.1.1"
|
||||
"@radix-ui/react-visually-hidden" "0.1.4"
|
||||
|
||||
"@radix-ui/react-use-body-pointer-events@0.1.0":
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-use-body-pointer-events/-/react-use-body-pointer-events-0.1.0.tgz#29b211464493f8ca5149ce34b96b95abbc97d741"
|
||||
@ -4606,17 +4627,17 @@
|
||||
tiny-hashes "^1.0.1"
|
||||
|
||||
"@sendgrid/client@^7.6.0":
|
||||
version "7.6.0"
|
||||
resolved "https://registry.yarnpkg.com/@sendgrid/client/-/client-7.6.0.tgz#f90cb8759c96e1d90224f29ad98f8fdc2be287f3"
|
||||
integrity sha512-cpBVZKLlMTO+vpE18krTixubYmZa98oTbLkqBDuTiA3zRkW+urrxg7pDR24TkI35Mid0Zru8jDHwnOiqrXu0TA==
|
||||
version "7.6.2"
|
||||
resolved "https://registry.yarnpkg.com/@sendgrid/client/-/client-7.6.2.tgz#5d08949120dad679f34260f1b875b4f57a8d688e"
|
||||
integrity sha512-Yw3i3vPBBwfiIi+4i7+1f1rwQoLlLsu3qW16d1UuRp6RgX6H6yHYb2/PfqwNyCC0qzqIWGUKPWwYe5ggcr5Guw==
|
||||
dependencies:
|
||||
"@sendgrid/helpers" "^7.6.0"
|
||||
axios "^0.21.4"
|
||||
"@sendgrid/helpers" "^7.6.2"
|
||||
axios "^0.26.0"
|
||||
|
||||
"@sendgrid/helpers@^7.6.0":
|
||||
version "7.6.0"
|
||||
resolved "https://registry.yarnpkg.com/@sendgrid/helpers/-/helpers-7.6.0.tgz#b381bfab391bcd66c771811b22bb6bb2d5c1dfc6"
|
||||
integrity sha512-0uWD+HSXLl4Z/X3cN+UMQC20RE7xwAACgppnfjDyvKG0KvJcUgDGz7HDdQkiMUdcVWfmyk6zKSg7XKfKzBjTwA==
|
||||
"@sendgrid/helpers@^7.6.0", "@sendgrid/helpers@^7.6.2":
|
||||
version "7.6.2"
|
||||
resolved "https://registry.yarnpkg.com/@sendgrid/helpers/-/helpers-7.6.2.tgz#e4abdd4e259611ed549ae8e0f4a46cd4f587e5d1"
|
||||
integrity sha512-kGW0kM2AOHfXjcvB6Lgwa/nMv8IALu0KyNY9X4HSa3MtLohymuhbG9HgjrOh66+BkbsfA03H3bcT0+sPVJ0GKQ==
|
||||
dependencies:
|
||||
deepmerge "^4.2.2"
|
||||
|
||||
@ -6969,7 +6990,7 @@ JSONStream@^1.0.4:
|
||||
jsonparse "^1.2.0"
|
||||
through ">=2.2.7 <3"
|
||||
|
||||
abab@^2.0.0, abab@^2.0.3, abab@^2.0.5:
|
||||
abab@^2.0.3, abab@^2.0.5:
|
||||
version "2.0.5"
|
||||
resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.5.tgz#c0b678fb32d60fc1219c784d6a826fe385aeb79a"
|
||||
integrity sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==
|
||||
@ -7002,14 +7023,6 @@ accepts@~1.3.4, accepts@~1.3.5:
|
||||
mime-types "~2.1.34"
|
||||
negotiator "0.6.3"
|
||||
|
||||
acorn-globals@^4.3.0:
|
||||
version "4.3.4"
|
||||
resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.3.4.tgz#9fa1926addc11c97308c4e66d7add0d40c3272e7"
|
||||
integrity sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A==
|
||||
dependencies:
|
||||
acorn "^6.0.1"
|
||||
acorn-walk "^6.0.1"
|
||||
|
||||
acorn-globals@^6.0.0:
|
||||
version "6.0.0"
|
||||
resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-6.0.0.tgz#46cdd39f0f8ff08a876619b55f5ac8a6dc770b45"
|
||||
@ -7028,11 +7041,6 @@ acorn-jsx@^5.3.1:
|
||||
resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937"
|
||||
integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==
|
||||
|
||||
acorn-walk@^6.0.1:
|
||||
version "6.2.0"
|
||||
resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-6.2.0.tgz#123cb8f3b84c2171f1f7fb252615b1c78a6b1a8c"
|
||||
integrity sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==
|
||||
|
||||
acorn-walk@^7.1.1:
|
||||
version "7.2.0"
|
||||
resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc"
|
||||
@ -7048,26 +7056,16 @@ acorn-walk@^8.1.1:
|
||||
resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.1.1.tgz#3ddab7f84e4a7e2313f6c414c5b7dac85f4e3ebc"
|
||||
integrity sha512-FbJdceMlPHEAWJOILDk1fXD8lnTlEIWFkqtfk+MvmL5q/qlHfN7GEHcsFZWt/Tea9jRNPWUZG4G976nqAAmU9w==
|
||||
|
||||
acorn@^6.0.1, acorn@^6.0.4:
|
||||
version "6.4.2"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.2.tgz#35866fd710528e92de10cf06016498e47e39e1e6"
|
||||
integrity sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==
|
||||
|
||||
acorn@^7.1.1:
|
||||
version "7.4.1"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa"
|
||||
integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==
|
||||
|
||||
acorn@^8.0.4, acorn@^8.5.0, acorn@^8.7.0:
|
||||
acorn@^8.0.4, acorn@^8.2.4, acorn@^8.4.1, acorn@^8.5.0, acorn@^8.7.0:
|
||||
version "8.7.0"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.0.tgz#90951fde0f8f09df93549481e5fc141445b791cf"
|
||||
integrity sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==
|
||||
|
||||
acorn@^8.2.4, acorn@^8.4.1:
|
||||
version "8.5.0"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.5.0.tgz#4512ccb99b3698c752591e9bb4472e38ad43cee2"
|
||||
integrity sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q==
|
||||
|
||||
add-stream@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/add-stream/-/add-stream-1.0.0.tgz#6a7990437ca736d5e1288db92bd3266d5f5cb2aa"
|
||||
@ -7487,11 +7485,6 @@ array-each@^1.0.1:
|
||||
resolved "https://registry.yarnpkg.com/array-each/-/array-each-1.0.1.tgz#a794af0c05ab1752846ee753a1f211a05ba0c44f"
|
||||
integrity sha1-p5SvDAWrF1KEbudTofIRoFugxE8=
|
||||
|
||||
array-equal@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93"
|
||||
integrity sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=
|
||||
|
||||
array-flatten@1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2"
|
||||
@ -7614,11 +7607,6 @@ ast-types-flow@^0.0.7:
|
||||
resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.7.tgz#f70b735c6bca1a5c9c22d982c3e39e7feba3bdad"
|
||||
integrity sha1-9wtzXGvKGlycItmCw+Oef+ujva0=
|
||||
|
||||
async-limiter@~1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd"
|
||||
integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==
|
||||
|
||||
async-retry@^1.2.1, async-retry@^1.3.3:
|
||||
version "1.3.3"
|
||||
resolved "https://registry.yarnpkg.com/async-retry/-/async-retry-1.3.3.tgz#0e7f36c04d8478e7a58bdbed80cedf977785f280"
|
||||
@ -9171,11 +9159,6 @@ cssfilter@0.0.10:
|
||||
resolved "https://registry.yarnpkg.com/cssfilter/-/cssfilter-0.0.10.tgz#c6d2672632a2e5c83e013e6864a42ce8defd20ae"
|
||||
integrity sha1-xtJnJjKi5cg+AT5oZKQs6N79IK4=
|
||||
|
||||
cssom@0.3.x, cssom@^0.3.4, cssom@~0.3.6:
|
||||
version "0.3.8"
|
||||
resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a"
|
||||
integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==
|
||||
|
||||
cssom@^0.4.4:
|
||||
version "0.4.4"
|
||||
resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.4.4.tgz#5a66cf93d2d0b661d80bf6a44fb65f5c2e4e0a10"
|
||||
@ -9186,12 +9169,10 @@ cssom@^0.5.0:
|
||||
resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.5.0.tgz#d254fa92cd8b6fbd83811b9fbaed34663cc17c36"
|
||||
integrity sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==
|
||||
|
||||
cssstyle@^1.1.1:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-1.4.0.tgz#9d31328229d3c565c61e586b02041a28fccdccf1"
|
||||
integrity sha512-GBrLZYZ4X4x6/QEoBnIrqb8B/f5l4+8me2dkom/j1Gtbxy0kBv6OGzKuAsGM75bkGwGAFkt56Iwg28S3XTZgSA==
|
||||
dependencies:
|
||||
cssom "0.3.x"
|
||||
cssom@~0.3.6:
|
||||
version "0.3.8"
|
||||
resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a"
|
||||
integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==
|
||||
|
||||
cssstyle@^2.3.0:
|
||||
version "2.3.0"
|
||||
@ -9229,15 +9210,6 @@ dashdash@^1.12.0:
|
||||
dependencies:
|
||||
assert-plus "^1.0.0"
|
||||
|
||||
data-urls@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-1.1.0.tgz#15ee0582baa5e22bb59c77140da8f9c76963bbfe"
|
||||
integrity sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==
|
||||
dependencies:
|
||||
abab "^2.0.0"
|
||||
whatwg-mimetype "^2.2.0"
|
||||
whatwg-url "^7.0.0"
|
||||
|
||||
data-urls@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-2.0.0.tgz#156485a72963a970f5d5821aaf642bef2bf2db9b"
|
||||
@ -9247,14 +9219,14 @@ data-urls@^2.0.0:
|
||||
whatwg-mimetype "^2.3.0"
|
||||
whatwg-url "^8.0.0"
|
||||
|
||||
data-urls@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-3.0.0.tgz#3ff551c986d7c6234a0ac4bbf20a269e1cd6b378"
|
||||
integrity sha512-4AefxbTTdFtxDUdh0BuMBs2qJVL25Mow2zlcuuePegQwgD6GEmQao42LLEeksOui8nL4RcNEugIpFP7eRd33xg==
|
||||
data-urls@^3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-3.0.1.tgz#597fc2ae30f8bc4dbcf731fcd1b1954353afc6f8"
|
||||
integrity sha512-Ds554NeT5Gennfoo9KN50Vh6tpgtvYEwraYjejXnyTpu1C7oXKxdFk75REooENHE8ndTVOJuv+BEs4/J/xcozw==
|
||||
dependencies:
|
||||
abab "^2.0.3"
|
||||
whatwg-mimetype "^2.3.0"
|
||||
whatwg-url "^9.0.0"
|
||||
whatwg-mimetype "^3.0.0"
|
||||
whatwg-url "^10.0.0"
|
||||
|
||||
dataloader@2.0.0, dataloader@^2.0.0:
|
||||
version "2.0.0"
|
||||
@ -9682,13 +9654,6 @@ domelementtype@^2.0.1, domelementtype@^2.2.0:
|
||||
resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.2.0.tgz#9a0b6c2782ed6a1c7323d42267183df9bd8b1d57"
|
||||
integrity sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==
|
||||
|
||||
domexception@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/domexception/-/domexception-1.0.1.tgz#937442644ca6a31261ef36e3ec677fe805582c90"
|
||||
integrity sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==
|
||||
dependencies:
|
||||
webidl-conversions "^4.0.2"
|
||||
|
||||
domexception@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/domexception/-/domexception-2.0.1.tgz#fb44aefba793e1574b0af6aed2801d057529f304"
|
||||
@ -9696,6 +9661,13 @@ domexception@^2.0.1:
|
||||
dependencies:
|
||||
webidl-conversions "^5.0.0"
|
||||
|
||||
domexception@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/domexception/-/domexception-4.0.0.tgz#4ad1be56ccadc86fc76d033353999a8037d03673"
|
||||
integrity sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==
|
||||
dependencies:
|
||||
webidl-conversions "^7.0.0"
|
||||
|
||||
domhandler@^3.0.0:
|
||||
version "3.3.0"
|
||||
resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-3.3.0.tgz#6db7ea46e4617eb15cf875df68b2b8524ce0037a"
|
||||
@ -10070,18 +10042,6 @@ escape-string-regexp@^2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344"
|
||||
integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==
|
||||
|
||||
escodegen@^1.11.0:
|
||||
version "1.14.3"
|
||||
resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.14.3.tgz#4e7b81fba61581dc97582ed78cab7f0e8d63f503"
|
||||
integrity sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==
|
||||
dependencies:
|
||||
esprima "^4.0.1"
|
||||
estraverse "^4.2.0"
|
||||
esutils "^2.0.2"
|
||||
optionator "^0.8.1"
|
||||
optionalDependencies:
|
||||
source-map "~0.6.1"
|
||||
|
||||
escodegen@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.0.0.tgz#5e32b12833e8aa8fa35e1bf0befa89380484c7dd"
|
||||
@ -10329,7 +10289,7 @@ esrecurse@^4.3.0:
|
||||
dependencies:
|
||||
estraverse "^5.2.0"
|
||||
|
||||
estraverse@^4.1.1, estraverse@^4.2.0:
|
||||
estraverse@^4.1.1:
|
||||
version "4.3.0"
|
||||
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d"
|
||||
integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==
|
||||
@ -11764,13 +11724,6 @@ hpagent@^0.1.1:
|
||||
resolved "https://registry.yarnpkg.com/hpagent/-/hpagent-0.1.2.tgz#cab39c66d4df2d4377dbd212295d878deb9bdaa9"
|
||||
integrity sha512-ePqFXHtSQWAFXYmj+JtOTHr84iNrII4/QRlAAPPE+zqnKy4xJo7Ie1Y4kC7AdB+LxLxSTTzBMASsEcy0q8YyvQ==
|
||||
|
||||
html-encoding-sniffer@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz#e70d84b94da53aa375e11fe3a351be6642ca46f8"
|
||||
integrity sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==
|
||||
dependencies:
|
||||
whatwg-encoding "^1.0.1"
|
||||
|
||||
html-encoding-sniffer@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz#42a6dc4fd33f00281176e8b23759ca4e4fa185f3"
|
||||
@ -11778,6 +11731,13 @@ html-encoding-sniffer@^2.0.1:
|
||||
dependencies:
|
||||
whatwg-encoding "^1.0.5"
|
||||
|
||||
html-encoding-sniffer@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz#2cb1a8cf0db52414776e5b2a7a04d5dd98158de9"
|
||||
integrity sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==
|
||||
dependencies:
|
||||
whatwg-encoding "^2.0.0"
|
||||
|
||||
html-entities@^2.3.2:
|
||||
version "2.3.2"
|
||||
resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.3.2.tgz#760b404685cb1d794e4f4b744332e3b00dcfe488"
|
||||
@ -11950,6 +11910,13 @@ iconv-lite@0.4.24, iconv-lite@^0.4.24:
|
||||
dependencies:
|
||||
safer-buffer ">= 2.1.2 < 3"
|
||||
|
||||
iconv-lite@0.6.3:
|
||||
version "0.6.3"
|
||||
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501"
|
||||
integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==
|
||||
dependencies:
|
||||
safer-buffer ">= 2.1.2 < 3.0.0"
|
||||
|
||||
iconv-lite@^0.6.2:
|
||||
version "0.6.2"
|
||||
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.2.tgz#ce13d1875b0c3a674bd6a04b7f76b01b1b6ded01"
|
||||
@ -13307,39 +13274,7 @@ jsbn@~0.1.0:
|
||||
resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
|
||||
integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM=
|
||||
|
||||
jsdom@^13.1:
|
||||
version "13.2.0"
|
||||
resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-13.2.0.tgz#b1a0dbdadc255435262be8ea3723d2dba0d7eb3a"
|
||||
integrity sha512-cG1NtMWO9hWpqRNRR3dSvEQa8bFI6iLlqU2x4kwX51FQjp0qus8T9aBaAO6iGp3DeBrhdwuKxckknohkmfvsFw==
|
||||
dependencies:
|
||||
abab "^2.0.0"
|
||||
acorn "^6.0.4"
|
||||
acorn-globals "^4.3.0"
|
||||
array-equal "^1.0.0"
|
||||
cssom "^0.3.4"
|
||||
cssstyle "^1.1.1"
|
||||
data-urls "^1.1.0"
|
||||
domexception "^1.0.1"
|
||||
escodegen "^1.11.0"
|
||||
html-encoding-sniffer "^1.0.2"
|
||||
nwsapi "^2.0.9"
|
||||
parse5 "5.1.0"
|
||||
pn "^1.1.0"
|
||||
request "^2.88.0"
|
||||
request-promise-native "^1.0.5"
|
||||
saxes "^3.1.5"
|
||||
symbol-tree "^3.2.2"
|
||||
tough-cookie "^2.5.0"
|
||||
w3c-hr-time "^1.0.1"
|
||||
w3c-xmlserializer "^1.0.1"
|
||||
webidl-conversions "^4.0.2"
|
||||
whatwg-encoding "^1.0.5"
|
||||
whatwg-mimetype "^2.3.0"
|
||||
whatwg-url "^7.0.0"
|
||||
ws "^6.1.2"
|
||||
xml-name-validator "^3.0.0"
|
||||
|
||||
jsdom@^16.4.0, jsdom@^16.6.0:
|
||||
jsdom@^16.6.0:
|
||||
version "16.7.0"
|
||||
resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.7.0.tgz#918ae71965424b197c819f8183a754e18977b710"
|
||||
integrity sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==
|
||||
@ -13372,23 +13307,23 @@ jsdom@^16.4.0, jsdom@^16.6.0:
|
||||
ws "^7.4.6"
|
||||
xml-name-validator "^3.0.0"
|
||||
|
||||
jsdom@^17.0.0:
|
||||
version "17.0.0"
|
||||
resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-17.0.0.tgz#3ec82d1d30030649c8defedc45fff6aa3e5d06ae"
|
||||
integrity sha512-MUq4XdqwtNurZDVeKScENMPHnkgmdIvMzZ1r1NSwHkDuaqI6BouPjr+17COo4/19oLNnmdpFDPOHVpgIZmZ+VA==
|
||||
jsdom@^19.0, jsdom@^19.0.0:
|
||||
version "19.0.0"
|
||||
resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-19.0.0.tgz#93e67c149fe26816d38a849ea30ac93677e16b6a"
|
||||
integrity sha512-RYAyjCbxy/vri/CfnjUWJQQtZ3LKlLnDqj+9XLNnJPgEGeirZs3hllKR20re8LUZ6o1b1X4Jat+Qd26zmP41+A==
|
||||
dependencies:
|
||||
abab "^2.0.5"
|
||||
acorn "^8.4.1"
|
||||
acorn "^8.5.0"
|
||||
acorn-globals "^6.0.0"
|
||||
cssom "^0.5.0"
|
||||
cssstyle "^2.3.0"
|
||||
data-urls "^3.0.0"
|
||||
data-urls "^3.0.1"
|
||||
decimal.js "^10.3.1"
|
||||
domexception "^2.0.1"
|
||||
domexception "^4.0.0"
|
||||
escodegen "^2.0.0"
|
||||
form-data "^4.0.0"
|
||||
html-encoding-sniffer "^2.0.1"
|
||||
http-proxy-agent "^4.0.1"
|
||||
html-encoding-sniffer "^3.0.0"
|
||||
http-proxy-agent "^5.0.0"
|
||||
https-proxy-agent "^5.0.0"
|
||||
is-potential-custom-element-name "^1.0.1"
|
||||
nwsapi "^2.2.0"
|
||||
@ -13397,13 +13332,13 @@ jsdom@^17.0.0:
|
||||
symbol-tree "^3.2.4"
|
||||
tough-cookie "^4.0.0"
|
||||
w3c-hr-time "^1.0.2"
|
||||
w3c-xmlserializer "^2.0.0"
|
||||
webidl-conversions "^6.1.0"
|
||||
whatwg-encoding "^1.0.5"
|
||||
whatwg-mimetype "^2.3.0"
|
||||
whatwg-url "^9.0.0"
|
||||
ws "^8.0.0"
|
||||
xml-name-validator "^3.0.0"
|
||||
w3c-xmlserializer "^3.0.0"
|
||||
webidl-conversions "^7.0.0"
|
||||
whatwg-encoding "^2.0.0"
|
||||
whatwg-mimetype "^3.0.0"
|
||||
whatwg-url "^10.0.0"
|
||||
ws "^8.2.3"
|
||||
xml-name-validator "^4.0.0"
|
||||
|
||||
jsesc@^2.5.1:
|
||||
version "2.5.2"
|
||||
@ -15283,7 +15218,7 @@ number-is-nan@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d"
|
||||
integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=
|
||||
|
||||
nwsapi@^2.0.9, nwsapi@^2.2.0:
|
||||
nwsapi@^2.2.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7"
|
||||
integrity sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==
|
||||
@ -15906,11 +15841,6 @@ parse5-htmlparser2-tree-adapter@^6.0.0:
|
||||
dependencies:
|
||||
parse5 "^6.0.1"
|
||||
|
||||
parse5@5.1.0:
|
||||
version "5.1.0"
|
||||
resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.0.tgz#c59341c9723f414c452975564c7c00a68d58acd2"
|
||||
integrity sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==
|
||||
|
||||
parse5@6.0.1, parse5@^6.0.1:
|
||||
version "6.0.1"
|
||||
resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b"
|
||||
@ -16184,11 +16114,6 @@ plop@^2.7.1:
|
||||
ora "^3.4.0"
|
||||
v8flags "^2.0.10"
|
||||
|
||||
pn@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb"
|
||||
integrity sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==
|
||||
|
||||
portfinder@^1.0.28:
|
||||
version "1.0.28"
|
||||
resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.28.tgz#67c4622852bd5374dd1dd900f779f53462fac778"
|
||||
@ -17092,22 +17017,6 @@ replaceall@^0.1.6:
|
||||
resolved "https://registry.yarnpkg.com/replaceall/-/replaceall-0.1.6.tgz#81d81ac7aeb72d7f5c4942adf2697a3220688d8e"
|
||||
integrity sha1-gdgax663LX9cSUKt8ml6MiBojY4=
|
||||
|
||||
request-promise-core@1.1.4:
|
||||
version "1.1.4"
|
||||
resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.4.tgz#3eedd4223208d419867b78ce815167d10593a22f"
|
||||
integrity sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==
|
||||
dependencies:
|
||||
lodash "^4.17.19"
|
||||
|
||||
request-promise-native@^1.0.5:
|
||||
version "1.0.9"
|
||||
resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.9.tgz#e407120526a5efdc9a39b28a5679bf47b9d9dc28"
|
||||
integrity sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==
|
||||
dependencies:
|
||||
request-promise-core "1.1.4"
|
||||
stealthy-require "^1.1.1"
|
||||
tough-cookie "^2.3.3"
|
||||
|
||||
request@^2.88.0, request@^2.88.2:
|
||||
version "2.88.2"
|
||||
resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3"
|
||||
@ -17357,13 +17266,6 @@ sax@>=0.6.0:
|
||||
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
|
||||
integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==
|
||||
|
||||
saxes@^3.1.5:
|
||||
version "3.1.11"
|
||||
resolved "https://registry.yarnpkg.com/saxes/-/saxes-3.1.11.tgz#d59d1fd332ec92ad98a2e0b2ee644702384b1c5b"
|
||||
integrity sha512-Ydydq3zC+WYDJK1+gRxRapLIED9PWeSuuS41wqyoRmzvhhh9nc+QQrVMKJYzJFULazeGhzSV0QleN2wD3boh2g==
|
||||
dependencies:
|
||||
xmlchars "^2.1.1"
|
||||
|
||||
saxes@^5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/saxes/-/saxes-5.0.1.tgz#eebab953fa3b7608dbe94e5dadb15c888fa6696d"
|
||||
@ -17996,11 +17898,6 @@ static-extend@^0.1.1:
|
||||
resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c"
|
||||
integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=
|
||||
|
||||
stealthy-require@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b"
|
||||
integrity sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=
|
||||
|
||||
stream-events@^1.0.4, stream-events@^1.0.5:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/stream-events/-/stream-events-1.0.5.tgz#bbc898ec4df33a4902d892333d47da9bf1c406d5"
|
||||
@ -18349,7 +18246,7 @@ symbol-observable@^1.0.4, symbol-observable@^1.1.0:
|
||||
resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804"
|
||||
integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==
|
||||
|
||||
symbol-tree@^3.2.2, symbol-tree@^3.2.4:
|
||||
symbol-tree@^3.2.4:
|
||||
version "3.2.4"
|
||||
resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2"
|
||||
integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==
|
||||
@ -18672,14 +18569,6 @@ touch@^3.1.0:
|
||||
dependencies:
|
||||
nopt "~1.0.10"
|
||||
|
||||
tough-cookie@^2.3.3, tough-cookie@^2.5.0, tough-cookie@~2.5.0:
|
||||
version "2.5.0"
|
||||
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2"
|
||||
integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==
|
||||
dependencies:
|
||||
psl "^1.1.28"
|
||||
punycode "^2.1.1"
|
||||
|
||||
tough-cookie@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.0.0.tgz#d822234eeca882f991f0f908824ad2622ddbece4"
|
||||
@ -18689,12 +18578,13 @@ tough-cookie@^4.0.0:
|
||||
punycode "^2.1.1"
|
||||
universalify "^0.1.2"
|
||||
|
||||
tr46@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09"
|
||||
integrity sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=
|
||||
tough-cookie@~2.5.0:
|
||||
version "2.5.0"
|
||||
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2"
|
||||
integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==
|
||||
dependencies:
|
||||
punycode "^2.1.0"
|
||||
psl "^1.1.28"
|
||||
punycode "^2.1.1"
|
||||
|
||||
tr46@^2.1.0:
|
||||
version "2.1.0"
|
||||
@ -18703,6 +18593,13 @@ tr46@^2.1.0:
|
||||
dependencies:
|
||||
punycode "^2.1.1"
|
||||
|
||||
tr46@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/tr46/-/tr46-3.0.0.tgz#555c4e297a950617e8eeddef633c87d4d9d6cbf9"
|
||||
integrity sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==
|
||||
dependencies:
|
||||
punycode "^2.1.1"
|
||||
|
||||
tr46@~0.0.3:
|
||||
version "0.0.3"
|
||||
resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
|
||||
@ -19362,22 +19259,13 @@ voca@^1.4.0:
|
||||
resolved "https://registry.yarnpkg.com/voca/-/voca-1.4.0.tgz#e15ac58b38290b72acc0c330366b6cc7984924d7"
|
||||
integrity sha512-8Xz4H3vhYRGbFupLtl6dHwMx0ojUcjt0HYkqZ9oBCfipd/5mD7Md58m2/dq7uPuZU/0T3Gb1m66KS9jn+I+14Q==
|
||||
|
||||
w3c-hr-time@^1.0.1, w3c-hr-time@^1.0.2:
|
||||
w3c-hr-time@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd"
|
||||
integrity sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==
|
||||
dependencies:
|
||||
browser-process-hrtime "^1.0.0"
|
||||
|
||||
w3c-xmlserializer@^1.0.1:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-1.1.2.tgz#30485ca7d70a6fd052420a3d12fd90e6339ce794"
|
||||
integrity sha512-p10l/ayESzrBMYWRID6xbuCKh2Fp77+sA0doRuGn4tTIMrrZVeqfpKjXHY+oDh3K4nLdPgNwMTVP6Vp4pvqbNg==
|
||||
dependencies:
|
||||
domexception "^1.0.1"
|
||||
webidl-conversions "^4.0.2"
|
||||
xml-name-validator "^3.0.0"
|
||||
|
||||
w3c-xmlserializer@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz#3e7104a05b75146cc60f564380b7f683acf1020a"
|
||||
@ -19385,6 +19273,13 @@ w3c-xmlserializer@^2.0.0:
|
||||
dependencies:
|
||||
xml-name-validator "^3.0.0"
|
||||
|
||||
w3c-xmlserializer@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-3.0.0.tgz#06cdc3eefb7e4d0b20a560a5a3aeb0d2d9a65923"
|
||||
integrity sha512-3WFqGEgSXIyGhOmAFtlicJNMjEps8b1MG31NCA0/vOF9+nKMUW1ckhi9cnNHmf88Rzw5V+dwIwsm2C7X8k9aQg==
|
||||
dependencies:
|
||||
xml-name-validator "^4.0.0"
|
||||
|
||||
walkdir@^0.4.0:
|
||||
version "0.4.1"
|
||||
resolved "https://registry.yarnpkg.com/walkdir/-/walkdir-0.4.1.tgz#dc119f83f4421df52e3061e514228a2db20afa39"
|
||||
@ -19434,11 +19329,6 @@ webidl-conversions@^3.0.0:
|
||||
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871"
|
||||
integrity sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=
|
||||
|
||||
webidl-conversions@^4.0.2:
|
||||
version "4.0.2"
|
||||
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad"
|
||||
integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==
|
||||
|
||||
webidl-conversions@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-5.0.0.tgz#ae59c8a00b121543a2acc65c0434f57b0fc11aff"
|
||||
@ -19449,6 +19339,11 @@ webidl-conversions@^6.1.0:
|
||||
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-6.1.0.tgz#9111b4d7ea80acd40f5270d666621afa78b69514"
|
||||
integrity sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==
|
||||
|
||||
webidl-conversions@^7.0.0:
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-7.0.0.tgz#256b4e1882be7debbf01d05f0aa2039778ea080a"
|
||||
integrity sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==
|
||||
|
||||
webpack-bundle-analyzer@^4.5.0:
|
||||
version "4.5.0"
|
||||
resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.5.0.tgz#1b0eea2947e73528754a6f9af3e91b2b6e0f79d5"
|
||||
@ -19586,23 +19481,43 @@ websocket-extensions@>=0.1.1:
|
||||
resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42"
|
||||
integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==
|
||||
|
||||
whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.5:
|
||||
whatwg-encoding@^1.0.5:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0"
|
||||
integrity sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==
|
||||
dependencies:
|
||||
iconv-lite "0.4.24"
|
||||
|
||||
whatwg-encoding@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz#e7635f597fd87020858626805a2729fa7698ac53"
|
||||
integrity sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==
|
||||
dependencies:
|
||||
iconv-lite "0.6.3"
|
||||
|
||||
whatwg-fetch@^3.4.1:
|
||||
version "3.6.2"
|
||||
resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz#dced24f37f2624ed0281725d51d0e2e3fe677f8c"
|
||||
integrity sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA==
|
||||
|
||||
whatwg-mimetype@^2.2.0, whatwg-mimetype@^2.3.0:
|
||||
whatwg-mimetype@^2.3.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf"
|
||||
integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==
|
||||
|
||||
whatwg-mimetype@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz#5fa1a7623867ff1af6ca3dc72ad6b8a4208beba7"
|
||||
integrity sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==
|
||||
|
||||
whatwg-url@^10.0.0:
|
||||
version "10.0.0"
|
||||
resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-10.0.0.tgz#37264f720b575b4a311bd4094ed8c760caaa05da"
|
||||
integrity sha512-CLxxCmdUby142H5FZzn4D8ikO1cmypvXVQktsgosNy4a4BHrDHeciBBGZhb0bNoR5/MltoCatso+vFjjGx8t0w==
|
||||
dependencies:
|
||||
tr46 "^3.0.0"
|
||||
webidl-conversions "^7.0.0"
|
||||
|
||||
whatwg-url@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d"
|
||||
@ -19611,15 +19526,6 @@ whatwg-url@^5.0.0:
|
||||
tr46 "~0.0.3"
|
||||
webidl-conversions "^3.0.0"
|
||||
|
||||
whatwg-url@^7.0.0:
|
||||
version "7.1.0"
|
||||
resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.1.0.tgz#c2c492f1eca612988efd3d2266be1b9fc6170d06"
|
||||
integrity sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==
|
||||
dependencies:
|
||||
lodash.sortby "^4.7.0"
|
||||
tr46 "^1.0.1"
|
||||
webidl-conversions "^4.0.2"
|
||||
|
||||
whatwg-url@^8.0.0, whatwg-url@^8.4.0, whatwg-url@^8.5.0:
|
||||
version "8.7.0"
|
||||
resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.7.0.tgz#656a78e510ff8f3937bc0bcbe9f5c0ac35941b77"
|
||||
@ -19629,14 +19535,6 @@ whatwg-url@^8.0.0, whatwg-url@^8.4.0, whatwg-url@^8.5.0:
|
||||
tr46 "^2.1.0"
|
||||
webidl-conversions "^6.1.0"
|
||||
|
||||
whatwg-url@^9.0.0:
|
||||
version "9.1.0"
|
||||
resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-9.1.0.tgz#1b112cf237d72cd64fa7882b9c3f6234a1c3050d"
|
||||
integrity sha512-CQ0UcrPHyomtlOCot1TL77WyMIm/bCwrJ2D6AOKGwEczU9EpyoqAokfqrf/MioU9kHcMsmJZcg1egXix2KYEsA==
|
||||
dependencies:
|
||||
tr46 "^2.1.0"
|
||||
webidl-conversions "^6.1.0"
|
||||
|
||||
which-boxed-primitive@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6"
|
||||
@ -19831,29 +19729,12 @@ ws@7.4.6:
|
||||
resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c"
|
||||
integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==
|
||||
|
||||
"ws@^5.2.0 || ^6.0.0 || ^7.0.0", ws@^7.2.3, ws@^7.4.6:
|
||||
version "7.5.3"
|
||||
resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.3.tgz#160835b63c7d97bfab418fc1b8a9fced2ac01a74"
|
||||
integrity sha512-kQ/dHIzuLrS6Je9+uv81ueZomEwH0qVYstcAQ4/Z93K8zeko9gtAbttJWzoC5ukqXY1PpoouV3+VSOqEAFt5wg==
|
||||
|
||||
ws@^6.1.2:
|
||||
version "6.2.2"
|
||||
resolved "https://registry.yarnpkg.com/ws/-/ws-6.2.2.tgz#dd5cdbd57a9979916097652d78f1cc5faea0c32e"
|
||||
integrity sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==
|
||||
dependencies:
|
||||
async-limiter "~1.0.0"
|
||||
|
||||
ws@^7.3.1:
|
||||
"ws@^5.2.0 || ^6.0.0 || ^7.0.0", ws@^7.2.3, ws@^7.3.1, ws@^7.4.6:
|
||||
version "7.5.7"
|
||||
resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.7.tgz#9e0ac77ee50af70d58326ecff7e85eb3fa375e67"
|
||||
integrity sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A==
|
||||
|
||||
ws@^8.0.0:
|
||||
version "8.2.3"
|
||||
resolved "https://registry.yarnpkg.com/ws/-/ws-8.2.3.tgz#63a56456db1b04367d0b721a0b80cae6d8becbba"
|
||||
integrity sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==
|
||||
|
||||
ws@^8.3.0, ws@^8.4.2:
|
||||
ws@^8.2.3, ws@^8.3.0, ws@^8.4.2:
|
||||
version "8.5.0"
|
||||
resolved "https://registry.yarnpkg.com/ws/-/ws-8.5.0.tgz#bfb4be96600757fe5382de12c670dab984a1ed4f"
|
||||
integrity sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==
|
||||
@ -19868,6 +19749,11 @@ xml-name-validator@^3.0.0:
|
||||
resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a"
|
||||
integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==
|
||||
|
||||
xml-name-validator@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-4.0.0.tgz#79a006e2e63149a8600f15430f0a4725d1524835"
|
||||
integrity sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==
|
||||
|
||||
xml2js@^0.4.23:
|
||||
version "0.4.23"
|
||||
resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.23.tgz#a0c69516752421eb2ac758ee4d4ccf58843eac66"
|
||||
@ -19881,7 +19767,7 @@ xmlbuilder@~11.0.0:
|
||||
resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3"
|
||||
integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==
|
||||
|
||||
xmlchars@^2.1.1, xmlchars@^2.2.0:
|
||||
xmlchars@^2.2.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb"
|
||||
integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==
|
||||
|
||||
Reference in New Issue
Block a user