mirror of
https://github.com/iptv-org/database.git
synced 2025-05-09 19:20:01 -04:00
Update scripts
This commit is contained in:
parent
37b4197fb2
commit
6244ba7adb
54 changed files with 2020 additions and 1145 deletions
|
@ -1,17 +0,0 @@
|
|||
type BlockedProps = {
|
||||
channel: string
|
||||
reason: string
|
||||
ref: string
|
||||
}
|
||||
|
||||
export class Blocked {
|
||||
channel: string
|
||||
reason: string
|
||||
ref: string
|
||||
|
||||
constructor({ ref, reason, channel }: BlockedProps) {
|
||||
this.channel = channel
|
||||
this.reason = reason
|
||||
this.ref = ref
|
||||
}
|
||||
}
|
42
scripts/models/blocklistRecord.ts
Normal file
42
scripts/models/blocklistRecord.ts
Normal file
|
@ -0,0 +1,42 @@
|
|||
import { BlocklistRecordData } from '../types/blocklistRecord'
|
||||
import { Dictionary } from '@freearhey/core'
|
||||
import { Model } from './model'
|
||||
import Joi from 'joi'
|
||||
|
||||
export class BlocklistRecord extends Model {
|
||||
channelId: string
|
||||
reason: string
|
||||
ref: string
|
||||
|
||||
constructor(data: BlocklistRecordData) {
|
||||
super()
|
||||
|
||||
this.channelId = data.channel
|
||||
this.reason = data.reason
|
||||
this.ref = data.ref
|
||||
}
|
||||
|
||||
hasValidChannelId(channelsKeyById: Dictionary): boolean {
|
||||
return channelsKeyById.has(this.channelId)
|
||||
}
|
||||
|
||||
data(): BlocklistRecordData {
|
||||
return {
|
||||
channel: this.channelId,
|
||||
reason: this.reason,
|
||||
ref: this.ref
|
||||
}
|
||||
}
|
||||
|
||||
getSchema() {
|
||||
return Joi.object({
|
||||
channel: Joi.string()
|
||||
.regex(/^[A-Za-z0-9]+\.[a-z]{2}$/)
|
||||
.required(),
|
||||
reason: Joi.string()
|
||||
.valid(...['dmca', 'nsfw'])
|
||||
.required(),
|
||||
ref: Joi.string().uri().required()
|
||||
})
|
||||
}
|
||||
}
|
33
scripts/models/category.ts
Normal file
33
scripts/models/category.ts
Normal file
|
@ -0,0 +1,33 @@
|
|||
import { CategoryData } from '../types/category'
|
||||
import { Model } from './model'
|
||||
import Joi from 'joi'
|
||||
|
||||
export class Category extends Model {
|
||||
id: string
|
||||
name: string
|
||||
|
||||
constructor(data: CategoryData) {
|
||||
super()
|
||||
|
||||
this.id = data.id
|
||||
this.name = data.name
|
||||
}
|
||||
|
||||
data(): CategoryData {
|
||||
return {
|
||||
id: this.id,
|
||||
name: this.name
|
||||
}
|
||||
}
|
||||
|
||||
getSchema() {
|
||||
return Joi.object({
|
||||
id: Joi.string()
|
||||
.regex(/^[a-z]+$/)
|
||||
.required(),
|
||||
name: Joi.string()
|
||||
.regex(/^[A-Z]+$/i)
|
||||
.required()
|
||||
})
|
||||
}
|
||||
}
|
|
@ -1,91 +1,237 @@
|
|||
type ChannelProps = {
|
||||
id: string
|
||||
name?: string
|
||||
alt_names?: string[]
|
||||
network?: string
|
||||
owners?: string[]
|
||||
country?: string
|
||||
subdivision?: string
|
||||
city?: string
|
||||
broadcast_area?: string[]
|
||||
languages?: string[]
|
||||
categories?: string[]
|
||||
is_nsfw?: boolean
|
||||
launched?: string
|
||||
closed?: string
|
||||
replaced_by?: string
|
||||
website?: string
|
||||
logo?: string
|
||||
}
|
||||
import { Dictionary, Collection } from '@freearhey/core'
|
||||
import { ChannelData } from '../types/channel'
|
||||
import { createChannelId } from '../utils'
|
||||
import JoiDate from '@joi/date'
|
||||
import { Model } from './model'
|
||||
import { Feed } from './feed'
|
||||
import BaseJoi from 'joi'
|
||||
import { IssueData } from '../core'
|
||||
|
||||
export class Channel {
|
||||
id: string
|
||||
name?: string
|
||||
alt_names?: string[]
|
||||
network?: string
|
||||
owners?: string[]
|
||||
country?: string
|
||||
subdivision?: string
|
||||
city?: string
|
||||
broadcast_area?: string[]
|
||||
languages?: string[]
|
||||
categories?: string[]
|
||||
is_nsfw?: boolean
|
||||
launched?: string
|
||||
closed?: string
|
||||
replaced_by?: string
|
||||
website?: string
|
||||
logo?: string
|
||||
const Joi = BaseJoi.extend(JoiDate)
|
||||
|
||||
constructor({
|
||||
id,
|
||||
name,
|
||||
alt_names,
|
||||
network,
|
||||
owners,
|
||||
country,
|
||||
subdivision,
|
||||
city,
|
||||
broadcast_area,
|
||||
languages,
|
||||
categories,
|
||||
is_nsfw,
|
||||
launched,
|
||||
closed,
|
||||
replaced_by,
|
||||
website,
|
||||
logo
|
||||
}: ChannelProps) {
|
||||
export class Channel extends Model {
|
||||
id: string
|
||||
name: string
|
||||
altNames?: Collection
|
||||
networkName?: string
|
||||
ownerNames?: Collection
|
||||
countryCode: string
|
||||
subdivisionCode?: string
|
||||
cityName?: string
|
||||
categoryIds?: Collection
|
||||
isNSFW: boolean
|
||||
launchedDateString?: string
|
||||
closedDateString?: string
|
||||
replacedBy?: string
|
||||
websiteUrl?: string
|
||||
logoUrl: string
|
||||
feeds?: Collection
|
||||
|
||||
constructor(data: ChannelData) {
|
||||
super()
|
||||
|
||||
this.id = data.id
|
||||
this.name = data.name
|
||||
this.altNames = data.alt_names ? new Collection(data.alt_names) : undefined
|
||||
this.networkName = data.network
|
||||
this.ownerNames = data.owners ? new Collection(data.owners) : undefined
|
||||
this.countryCode = data.country
|
||||
this.subdivisionCode = data.subdivision
|
||||
this.cityName = data.city
|
||||
this.categoryIds = data.categories ? new Collection(data.categories) : undefined
|
||||
this.isNSFW = data.is_nsfw
|
||||
this.launchedDateString = data.launched
|
||||
this.closedDateString = data.closed
|
||||
this.replacedBy = data.replaced_by
|
||||
this.websiteUrl = data.website
|
||||
this.logoUrl = data.logo
|
||||
}
|
||||
|
||||
setId(id: string): this {
|
||||
this.id = id
|
||||
this.name = name
|
||||
this.alt_names = alt_names
|
||||
this.network = network
|
||||
this.owners = owners
|
||||
this.country = country
|
||||
this.subdivision = subdivision
|
||||
this.city = city
|
||||
this.broadcast_area = broadcast_area
|
||||
this.languages = languages
|
||||
this.categories = categories
|
||||
this.is_nsfw = is_nsfw
|
||||
this.launched = launched
|
||||
this.closed = closed
|
||||
this.replaced_by = replaced_by
|
||||
this.website = website
|
||||
this.logo = logo
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
data() {
|
||||
const { ...object } = this
|
||||
update(issueData: IssueData): this {
|
||||
const data = {
|
||||
channel_name: issueData.getString('channel_name'),
|
||||
alt_names: issueData.getArray('alt_names'),
|
||||
network: issueData.getString('network'),
|
||||
owners: issueData.getArray('owners'),
|
||||
country: issueData.getString('country'),
|
||||
subdivision: issueData.getString('subdivision'),
|
||||
city: issueData.getString('city'),
|
||||
categories: issueData.getArray('categories'),
|
||||
is_nsfw: issueData.getBoolean('is_nsfw'),
|
||||
launched: issueData.getString('launched'),
|
||||
closed: issueData.getString('closed'),
|
||||
replaced_by: issueData.getString('replaced_by'),
|
||||
website: issueData.getString('website'),
|
||||
logo: issueData.getString('logo')
|
||||
}
|
||||
|
||||
return object
|
||||
if (data.channel_name !== undefined) this.name = data.channel_name
|
||||
if (data.alt_names !== undefined) this.altNames = new Collection(data.alt_names)
|
||||
if (data.network !== undefined) this.networkName = data.network
|
||||
if (data.owners !== undefined) this.ownerNames = new Collection(data.owners)
|
||||
if (data.country !== undefined) this.countryCode = data.country
|
||||
if (data.subdivision !== undefined) this.subdivisionCode = data.subdivision
|
||||
if (data.city !== undefined) this.cityName = data.city
|
||||
if (data.categories !== undefined) this.categoryIds = new Collection(data.categories)
|
||||
if (data.is_nsfw !== undefined) this.isNSFW = data.is_nsfw
|
||||
if (data.launched !== undefined) this.launchedDateString = data.launched
|
||||
if (data.closed !== undefined) this.closedDateString = data.closed
|
||||
if (data.replaced_by !== undefined) this.replacedBy = data.replaced_by
|
||||
if (data.website !== undefined) this.websiteUrl = data.website
|
||||
if (data.logo !== undefined) this.logoUrl = data.logo
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
merge(channel: Channel) {
|
||||
const data: { [key: string]: string | string[] | boolean | undefined } = channel.data()
|
||||
for (const prop in data) {
|
||||
if (data[prop] === undefined) continue
|
||||
this[prop] = data[prop]
|
||||
withFeeds(feedsGroupedByChannelId: Dictionary): this {
|
||||
this.feeds = new Collection(feedsGroupedByChannelId.get(this.id))
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
getFeeds(): Collection {
|
||||
if (!this.feeds) return new Collection()
|
||||
|
||||
return this.feeds
|
||||
}
|
||||
|
||||
hasValidId(): boolean {
|
||||
const expectedId = createChannelId(this.name, this.countryCode)
|
||||
|
||||
return expectedId === this.id
|
||||
}
|
||||
|
||||
hasMainFeed(): boolean {
|
||||
const feeds = this.getFeeds()
|
||||
|
||||
if (feeds.isEmpty()) return false
|
||||
|
||||
const mainFeed = feeds.find((feed: Feed) => feed.isMain)
|
||||
|
||||
return !!mainFeed
|
||||
}
|
||||
|
||||
hasMoreThanOneMainFeed(): boolean {
|
||||
const mainFeeds = this.getFeeds().filter((feed: Feed) => feed.isMain)
|
||||
|
||||
return mainFeeds.count() > 1
|
||||
}
|
||||
|
||||
hasValidReplacedBy(channelsKeyById: Dictionary, feedsKeyByStreamId: Dictionary): boolean {
|
||||
if (!this.replacedBy) return true
|
||||
|
||||
const [channelId, feedId] = this.replacedBy.split('@')
|
||||
|
||||
if (channelsKeyById.missing(channelId)) return false
|
||||
if (feedId && feedsKeyByStreamId.missing(this.replacedBy)) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
hasValidCountryCode(countriesKeyByCode: Dictionary): boolean {
|
||||
return countriesKeyByCode.has(this.countryCode)
|
||||
}
|
||||
|
||||
hasValidSubdivisionCode(subdivisionsKeyByCode: Dictionary): boolean {
|
||||
return !this.subdivisionCode || subdivisionsKeyByCode.has(this.subdivisionCode)
|
||||
}
|
||||
|
||||
hasValidCategoryIds(categoriesKeyById: Dictionary): boolean {
|
||||
const hasInvalid = this.getCategoryIds().find((id: string) => categoriesKeyById.missing(id))
|
||||
|
||||
return !hasInvalid
|
||||
}
|
||||
|
||||
getCategoryIds(): Collection {
|
||||
if (!this.categoryIds) return new Collection()
|
||||
|
||||
return this.categoryIds
|
||||
}
|
||||
|
||||
getAltNames(): Collection {
|
||||
if (!this.altNames) return new Collection()
|
||||
|
||||
return this.altNames
|
||||
}
|
||||
|
||||
getOwnerNames(): Collection {
|
||||
if (!this.ownerNames) return new Collection()
|
||||
|
||||
return this.ownerNames
|
||||
}
|
||||
|
||||
data(): ChannelData {
|
||||
return {
|
||||
id: this.id,
|
||||
name: this.name,
|
||||
alt_names: this.getAltNames().all(),
|
||||
network: this.networkName,
|
||||
owners: this.getOwnerNames().all(),
|
||||
country: this.countryCode,
|
||||
subdivision: this.subdivisionCode,
|
||||
city: this.cityName,
|
||||
categories: this.getCategoryIds().all(),
|
||||
is_nsfw: this.isNSFW,
|
||||
launched: this.launchedDateString,
|
||||
closed: this.closedDateString,
|
||||
replaced_by: this.replacedBy,
|
||||
website: this.websiteUrl,
|
||||
logo: this.logoUrl
|
||||
}
|
||||
}
|
||||
|
||||
getSchema() {
|
||||
return Joi.object({
|
||||
id: Joi.string()
|
||||
.regex(/^[A-Za-z0-9]+\.[a-z]{2}$/)
|
||||
.required(),
|
||||
name: Joi.string()
|
||||
.regex(/^[a-z0-9-!:&.+'/»#%°$@?|¡–\s_—]+$/i)
|
||||
.regex(/^((?!\s-\s).)*$/)
|
||||
.required(),
|
||||
alt_names: Joi.array().items(
|
||||
Joi.string()
|
||||
.regex(/^[^",]+$/)
|
||||
.invalid(Joi.ref('name'))
|
||||
),
|
||||
network: Joi.string()
|
||||
.regex(/^[^",]+$/)
|
||||
.allow(null),
|
||||
owners: Joi.array().items(Joi.string().regex(/^[^",]+$/)),
|
||||
country: Joi.string()
|
||||
.regex(/^[A-Z]{2}$/)
|
||||
.required(),
|
||||
subdivision: Joi.string()
|
||||
.regex(/^[A-Z]{2}-[A-Z0-9]{1,3}$/)
|
||||
.allow(null),
|
||||
city: Joi.string()
|
||||
.regex(/^[^",]+$/)
|
||||
.allow(null),
|
||||
categories: Joi.array().items(Joi.string().regex(/^[a-z]+$/)),
|
||||
is_nsfw: Joi.boolean().strict().required(),
|
||||
launched: Joi.date().format('YYYY-MM-DD').raw().allow(null),
|
||||
closed: Joi.date().format('YYYY-MM-DD').raw().allow(null).greater(Joi.ref('launched')),
|
||||
replaced_by: Joi.string()
|
||||
.regex(/^[A-Za-z0-9]+\.[a-z]{2}($|@[A-Za-z0-9]+$)/)
|
||||
.allow(null),
|
||||
website: Joi.string()
|
||||
.regex(/,/, { invert: true })
|
||||
.uri({
|
||||
scheme: ['http', 'https']
|
||||
})
|
||||
.allow(null),
|
||||
logo: Joi.string()
|
||||
.regex(/,/, { invert: true })
|
||||
.uri({
|
||||
scheme: ['https']
|
||||
})
|
||||
.required()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
54
scripts/models/country.ts
Normal file
54
scripts/models/country.ts
Normal file
|
@ -0,0 +1,54 @@
|
|||
import { Collection, Dictionary } from '@freearhey/core'
|
||||
import { CountryData } from '../types/country'
|
||||
import { Model } from './model'
|
||||
import Joi from 'joi'
|
||||
|
||||
export class Country extends Model {
|
||||
code: string
|
||||
name: string
|
||||
flagEmoji: string
|
||||
languageCodes: Collection
|
||||
|
||||
constructor(data: CountryData) {
|
||||
super()
|
||||
|
||||
this.code = data.code
|
||||
this.name = data.name
|
||||
this.flagEmoji = data.flag
|
||||
this.languageCodes = new Collection(data.languages)
|
||||
}
|
||||
|
||||
hasValidLanguageCodes(languagesKeyByCode: Dictionary): boolean {
|
||||
const hasInvalid = this.languageCodes.find((code: string) => languagesKeyByCode.missing(code))
|
||||
|
||||
return !hasInvalid
|
||||
}
|
||||
|
||||
data(): CountryData {
|
||||
return {
|
||||
code: this.code,
|
||||
name: this.name,
|
||||
flag: this.flagEmoji,
|
||||
languages: this.languageCodes.all()
|
||||
}
|
||||
}
|
||||
|
||||
getSchema() {
|
||||
return Joi.object({
|
||||
name: Joi.string()
|
||||
.regex(/^[\sA-Z\u00C0-\u00FF().-]+$/i)
|
||||
.required(),
|
||||
code: Joi.string()
|
||||
.regex(/^[A-Z]{2}$/)
|
||||
.required(),
|
||||
languages: Joi.array().items(
|
||||
Joi.string()
|
||||
.regex(/^[a-z]{3}$/)
|
||||
.required()
|
||||
),
|
||||
flag: Joi.string()
|
||||
.regex(/^[\uD83C][\uDDE6-\uDDFF][\uD83C][\uDDE6-\uDDFF]$/)
|
||||
.required()
|
||||
})
|
||||
}
|
||||
}
|
|
@ -1,55 +1,147 @@
|
|||
type FeedProps = {
|
||||
channel: string
|
||||
id: string
|
||||
name?: string
|
||||
is_main?: boolean
|
||||
broadcast_area?: string[]
|
||||
timezones?: string[]
|
||||
languages?: string[]
|
||||
video_format?: string
|
||||
}
|
||||
import { Collection, Dictionary } from '@freearhey/core'
|
||||
import { FeedData } from '../types/feed'
|
||||
import { createFeedId } from '../utils'
|
||||
import { Model } from './model'
|
||||
import JoiDate from '@joi/date'
|
||||
import BaseJoi from 'joi'
|
||||
import { IssueData } from '../core'
|
||||
|
||||
export class Feed {
|
||||
channel: string
|
||||
id: string
|
||||
name?: string
|
||||
is_main?: boolean
|
||||
broadcast_area: string[]
|
||||
timezones: string[]
|
||||
languages: string[]
|
||||
video_format?: string
|
||||
const Joi = BaseJoi.extend(JoiDate)
|
||||
|
||||
constructor({
|
||||
channel,
|
||||
id,
|
||||
name,
|
||||
is_main,
|
||||
broadcast_area,
|
||||
timezones,
|
||||
languages,
|
||||
video_format
|
||||
}: FeedProps) {
|
||||
this.channel = channel
|
||||
export class Feed extends Model {
|
||||
channelId: string
|
||||
id: string
|
||||
name: string
|
||||
isMain: boolean
|
||||
broadcastAreaCodes: Collection
|
||||
timezoneIds: Collection
|
||||
languageCodes: Collection
|
||||
videoFormat?: string
|
||||
|
||||
constructor(data: FeedData) {
|
||||
super()
|
||||
|
||||
this.channelId = data.channel
|
||||
this.id = data.id
|
||||
this.name = data.name
|
||||
this.isMain = data.is_main
|
||||
this.broadcastAreaCodes = new Collection(data.broadcast_area)
|
||||
this.timezoneIds = new Collection(data.timezones)
|
||||
this.languageCodes = new Collection(data.languages)
|
||||
this.videoFormat = data.video_format
|
||||
}
|
||||
|
||||
setId(id: string): this {
|
||||
this.id = id
|
||||
this.name = name
|
||||
this.is_main = is_main
|
||||
this.broadcast_area = broadcast_area || []
|
||||
this.timezones = timezones || []
|
||||
this.languages = languages || []
|
||||
this.video_format = video_format
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
data() {
|
||||
const { ...object } = this
|
||||
update(issueData: IssueData): this {
|
||||
const data = {
|
||||
feed_name: issueData.getString('feed_name'),
|
||||
is_main: issueData.getBoolean('is_main'),
|
||||
broadcast_area: issueData.getArray('broadcast_area'),
|
||||
timezones: issueData.getArray('timezones'),
|
||||
languages: issueData.getArray('languages'),
|
||||
video_format: issueData.getString('video_format')
|
||||
}
|
||||
|
||||
return object
|
||||
if (data.feed_name !== undefined) this.name = data.feed_name
|
||||
if (data.is_main !== undefined) this.isMain = data.is_main
|
||||
if (data.broadcast_area !== undefined)
|
||||
this.broadcastAreaCodes = new Collection(data.broadcast_area)
|
||||
if (data.timezones !== undefined) this.timezoneIds = new Collection(data.timezones)
|
||||
if (data.languages !== undefined) this.languageCodes = new Collection(data.languages)
|
||||
if (data.video_format !== undefined) this.videoFormat = data.video_format
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
merge(feed: Feed) {
|
||||
const data: { [key: string]: string | string[] | boolean | undefined } = feed.data()
|
||||
for (const prop in data) {
|
||||
if (data[prop] === undefined) continue
|
||||
this[prop] = data[prop]
|
||||
hasValidId(): boolean {
|
||||
const expectedId = createFeedId(this.name)
|
||||
|
||||
return expectedId === this.id
|
||||
}
|
||||
|
||||
hasValidChannelId(channelsKeyById: Dictionary): boolean {
|
||||
return channelsKeyById.has(this.channelId)
|
||||
}
|
||||
|
||||
hasValidTimezones(timezonesKeyById: Dictionary): boolean {
|
||||
const hasInvalid = this.timezoneIds.find((id: string) => timezonesKeyById.missing(id))
|
||||
|
||||
return !hasInvalid
|
||||
}
|
||||
|
||||
hasValidBroadcastAreaCodes(
|
||||
countriesKeyByCode: Dictionary,
|
||||
subdivisionsKeyByCode: Dictionary,
|
||||
regionsKeyByCode: Dictionary
|
||||
): boolean {
|
||||
const hasInvalid = this.broadcastAreaCodes.find((areaCode: string) => {
|
||||
const [type, code] = areaCode.split('/')
|
||||
switch (type) {
|
||||
case 'c':
|
||||
return countriesKeyByCode.missing(code)
|
||||
case 's':
|
||||
return subdivisionsKeyByCode.missing(code)
|
||||
case 'r':
|
||||
return regionsKeyByCode.missing(code)
|
||||
}
|
||||
})
|
||||
|
||||
return !hasInvalid
|
||||
}
|
||||
|
||||
getStreamId(): string {
|
||||
return `${this.channelId}@${this.id}`
|
||||
}
|
||||
|
||||
data(): FeedData {
|
||||
return {
|
||||
channel: this.channelId,
|
||||
id: this.id,
|
||||
name: this.name,
|
||||
is_main: this.isMain,
|
||||
broadcast_area: this.broadcastAreaCodes.all(),
|
||||
timezones: this.timezoneIds.all(),
|
||||
languages: this.languageCodes.all(),
|
||||
video_format: this.videoFormat
|
||||
}
|
||||
}
|
||||
|
||||
getSchema() {
|
||||
return Joi.object({
|
||||
channel: Joi.string()
|
||||
.regex(/^[A-Za-z0-9]+\.[a-z]{2}$/)
|
||||
.required(),
|
||||
id: Joi.string()
|
||||
.regex(/^[A-Za-z0-9]+$/)
|
||||
.required(),
|
||||
name: Joi.string()
|
||||
.regex(/^[a-z0-9-!:&.+'/»#%°$@?|¡–\s_—]+$/i)
|
||||
.regex(/^((?!\s-\s).)*$/)
|
||||
.required(),
|
||||
is_main: Joi.boolean().strict().required(),
|
||||
broadcast_area: Joi.array().items(
|
||||
Joi.string()
|
||||
.regex(/^(s\/[A-Z]{2}-[A-Z0-9]{1,3}|c\/[A-Z]{2}|r\/[A-Z0-9]{2,7})$/)
|
||||
.required()
|
||||
),
|
||||
timezones: Joi.array().items(
|
||||
Joi.string()
|
||||
.regex(/^[a-z-_/]+$/i)
|
||||
.required()
|
||||
),
|
||||
languages: Joi.array().items(
|
||||
Joi.string()
|
||||
.regex(/^[a-z]{3}$/)
|
||||
.required()
|
||||
),
|
||||
video_format: Joi.string()
|
||||
.regex(/^\d+(i|p)$/)
|
||||
.allow(null)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
export * from './channel'
|
||||
export * from './blocked'
|
||||
export * from './blocklistRecord'
|
||||
export * from './feed'
|
||||
export * from './region'
|
||||
export * from './subdivision'
|
||||
export * from './category'
|
||||
export * from './country'
|
||||
export * from './language'
|
||||
export * from './timezone'
|
||||
|
|
31
scripts/models/language.ts
Normal file
31
scripts/models/language.ts
Normal file
|
@ -0,0 +1,31 @@
|
|||
import { LanguageData } from '../types/language'
|
||||
import { Model } from './model'
|
||||
import Joi from 'joi'
|
||||
|
||||
export class Language extends Model {
|
||||
code: string
|
||||
name: string
|
||||
|
||||
constructor(data: LanguageData) {
|
||||
super()
|
||||
|
||||
this.code = data.code
|
||||
this.name = data.name
|
||||
}
|
||||
|
||||
data(): LanguageData {
|
||||
return {
|
||||
code: this.code,
|
||||
name: this.name
|
||||
}
|
||||
}
|
||||
|
||||
getSchema() {
|
||||
return Joi.object({
|
||||
code: Joi.string()
|
||||
.regex(/^[a-z]{3}$/)
|
||||
.required(),
|
||||
name: Joi.string().required()
|
||||
})
|
||||
}
|
||||
}
|
15
scripts/models/model.ts
Normal file
15
scripts/models/model.ts
Normal file
|
@ -0,0 +1,15 @@
|
|||
export class Model {
|
||||
line?: number
|
||||
|
||||
constructor() {}
|
||||
|
||||
setLine(line: number): this {
|
||||
this.line = line
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
getLine(): number {
|
||||
return this.line || 0
|
||||
}
|
||||
}
|
48
scripts/models/region.ts
Normal file
48
scripts/models/region.ts
Normal file
|
@ -0,0 +1,48 @@
|
|||
import { Collection, Dictionary } from '@freearhey/core'
|
||||
import { RegionData } from '../types/region'
|
||||
import { Model } from './model'
|
||||
import Joi from 'joi'
|
||||
|
||||
export class Region extends Model {
|
||||
code: string
|
||||
name: string
|
||||
countryCodes: Collection
|
||||
|
||||
constructor(data: RegionData) {
|
||||
super()
|
||||
|
||||
this.code = data.code
|
||||
this.name = data.name
|
||||
this.countryCodes = new Collection(data.countries)
|
||||
}
|
||||
|
||||
hasValidCountryCodes(countriesKeyByCode: Dictionary): boolean {
|
||||
const hasInvalid = this.countryCodes.find((code: string) => countriesKeyByCode.missing(code))
|
||||
|
||||
return !hasInvalid
|
||||
}
|
||||
|
||||
data(): RegionData {
|
||||
return {
|
||||
code: this.code,
|
||||
name: this.name,
|
||||
countries: this.countryCodes.all()
|
||||
}
|
||||
}
|
||||
|
||||
getSchema() {
|
||||
return Joi.object({
|
||||
name: Joi.string()
|
||||
.regex(/^[\sA-Z\u00C0-\u00FF().,-]+$/i)
|
||||
.required(),
|
||||
code: Joi.string()
|
||||
.regex(/^[A-Z]{2,7}$/)
|
||||
.required(),
|
||||
countries: Joi.array().items(
|
||||
Joi.string()
|
||||
.regex(/^[A-Z]{2}$/)
|
||||
.required()
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
42
scripts/models/subdivision.ts
Normal file
42
scripts/models/subdivision.ts
Normal file
|
@ -0,0 +1,42 @@
|
|||
import { SubdivisionData } from '../types/subdivision'
|
||||
import { Dictionary } from '@freearhey/core'
|
||||
import { Model } from './model'
|
||||
import Joi from 'joi'
|
||||
|
||||
export class Subdivision extends Model {
|
||||
code: string
|
||||
name: string
|
||||
countryCode: string
|
||||
|
||||
constructor(data: SubdivisionData) {
|
||||
super()
|
||||
|
||||
this.code = data.code
|
||||
this.name = data.name
|
||||
this.countryCode = data.country
|
||||
}
|
||||
|
||||
hasValidCountryCode(countriesKeyByCode: Dictionary): boolean {
|
||||
return countriesKeyByCode.has(this.countryCode)
|
||||
}
|
||||
|
||||
data(): SubdivisionData {
|
||||
return {
|
||||
code: this.code,
|
||||
name: this.name,
|
||||
country: this.countryCode
|
||||
}
|
||||
}
|
||||
|
||||
getSchema() {
|
||||
return Joi.object({
|
||||
country: Joi.string()
|
||||
.regex(/^[A-Z]{2}$/)
|
||||
.required(),
|
||||
name: Joi.string().required(),
|
||||
code: Joi.string()
|
||||
.regex(/^[A-Z]{2}-[A-Z0-9]{1,3}$/)
|
||||
.required()
|
||||
})
|
||||
}
|
||||
}
|
44
scripts/models/timezone.ts
Normal file
44
scripts/models/timezone.ts
Normal file
|
@ -0,0 +1,44 @@
|
|||
import { Collection, Dictionary } from '@freearhey/core'
|
||||
import { TimezoneData } from '../types/timezone'
|
||||
import { Model } from './model'
|
||||
import Joi from 'joi'
|
||||
|
||||
export class Timezone extends Model {
|
||||
id: string
|
||||
utcOffset: string
|
||||
countryCodes: Collection
|
||||
|
||||
constructor(data: TimezoneData) {
|
||||
super()
|
||||
|
||||
this.id = data.id
|
||||
this.utcOffset = data.utc_offset
|
||||
this.countryCodes = new Collection(data.countries)
|
||||
}
|
||||
|
||||
hasValidCountryCodes(countriesKeyByCode: Dictionary): boolean {
|
||||
const hasInvalid = this.countryCodes.find((code: string) => countriesKeyByCode.missing(code))
|
||||
|
||||
return !hasInvalid
|
||||
}
|
||||
|
||||
data(): TimezoneData {
|
||||
return {
|
||||
id: this.id,
|
||||
utc_offset: this.utcOffset,
|
||||
countries: this.countryCodes.all()
|
||||
}
|
||||
}
|
||||
|
||||
getSchema() {
|
||||
return Joi.object({
|
||||
id: Joi.string()
|
||||
.regex(/^[a-z-_/]+$/i)
|
||||
.required(),
|
||||
utc_offset: Joi.string()
|
||||
.regex(/^(\+|-)\d{2}:\d{2}$/)
|
||||
.required(),
|
||||
countries: Joi.array().items(Joi.string().regex(/^[A-Z]{2}$/))
|
||||
})
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue