diff --git a/.github/ISSUE_TEMPLATE/__channels_add.yml b/.github/ISSUE_TEMPLATE/1_channels_add.yml similarity index 63% rename from .github/ISSUE_TEMPLATE/__channels_add.yml rename to .github/ISSUE_TEMPLATE/1_channels_add.yml index b3ab5bd0..f4591849 100644 --- a/.github/ISSUE_TEMPLATE/__channels_add.yml +++ b/.github/ISSUE_TEMPLATE/1_channels_add.yml @@ -62,24 +62,6 @@ body: description: Name of the city from which the channel is transmitted placeholder: 'Hefei' - - type: input - id: broadcast_area - attributes: - label: Broadcast Area - description: List of codes describing the broadcasting area of the channel separated by `;`. Any combination of `r/`, `c/`, `s/` - placeholder: 'c/CN;r/EUR' - validations: - required: true - - - type: input - id: languages - attributes: - label: Languages - description: List of languages in which the channel is broadcast separated by `;`. A list of all supported languages and their codes can be found in [data/languages.csv](https://github.com/iptv-org/database/blob/master/data/languages.csv) - placeholder: 'zho;eng' - validations: - required: true - - type: input id: categories attributes: @@ -98,27 +80,6 @@ body: validations: required: true - - type: input - id: launched - attributes: - label: Launched (optional) - description: Launch date of the channel (`YYYY-MM-DD`) - placeholder: '2016-07-28' - - - type: input - id: closed - attributes: - label: Closed (optional) - description: Date on which the channel closed (`YYYY-MM-DD`) - placeholder: '2020-05-31' - - - type: input - id: replaced_by - attributes: - label: Replaced By (optional) - description: The ID of the channel that this channel was replaced by - placeholder: 'CCTV1.cn' - - type: input id: website attributes: @@ -135,7 +96,92 @@ body: validations: required: true + - type: markdown + attributes: + value: | + ## Main Feed + Description of the main feed of the channel + + - type: input + id: feed_name + attributes: + label: Feed Name + description: "Name of the feed in English. May include: `a-z`, `0-9`, `space`, `-`, `!`, `:`, `&`, `.`, `+`, `'`, `/`, `»`, `#`, `%`, `°`, `$`, `@`, `?`, `|`, `¡`" + placeholder: 'SD' + value: 'SD' + validations: + required: true + + - type: input + id: broadcast_area + attributes: + label: Broadcast Area + description: "List of codes describing the broadcasting area of the feed separated by `;`. Any combination of `r/`, `c/`, `s/`. A full list of supported codes can be found here: [countries](https://github.com/iptv-org/database/blob/master/data/countries.csv), [subdivisions](https://github.com/iptv-org/database/blob/master/data/subdivisions.csv), [regions](https://github.com/iptv-org/database/blob/master/data/regions.csv)" + placeholder: 'c/CN' + validations: + required: true + + - type: input + id: timezones + attributes: + label: Timezones + description: List of broadcast time zones separated by `;`. A list of all supported timezones and their codes can be found in [data/timezones.csv](https://github.com/iptv-org/database/blob/master/data/timezones.csv) + placeholder: 'Asia/Shanghai' + validations: + required: true + + - type: input + id: languages + attributes: + label: Languages + description: List of languages in which the feed is broadcast separated by `;`. A list of all supported languages and their codes can be found in [data/languages.csv](https://github.com/iptv-org/database/blob/master/data/languages.csv) + placeholder: 'zho;eng' + validations: + required: true + + - type: input + id: video_format + attributes: + label: Format + description: Video format of the broadcast + default: 6 + options: + - '4320p' + - '2160p' + - '1080p' + - '1080i' + - '720p' + - '576p' + - '576i' + - '480p' + - '480i' + - '360p' + - '240p' + validations: + required: true + + - type: input + id: launched + attributes: + label: Launched (optional) + description: Launch date of the feed (`YYYY-MM-DD`) + placeholder: '2016-07-28' + + - type: input + id: closed + attributes: + label: Closed (optional) + description: Date on which the feed closed (`YYYY-MM-DD`) + placeholder: '2020-05-31' + + - type: input + id: replaced_by + attributes: + label: Replaced By (optional) + description: "ID of the channel and feed this feed was replaced with. Possible values: `` or `@`" + placeholder: 'CCTV1.cn@SD' + - type: textarea attributes: label: Notes - description: 'Anything else we should know about this channel?' + description: 'Anything else we should know?' diff --git a/.github/ISSUE_TEMPLATE/__channels_edit.yml b/.github/ISSUE_TEMPLATE/2_channels_edit.yml similarity index 74% rename from .github/ISSUE_TEMPLATE/__channels_edit.yml rename to .github/ISSUE_TEMPLATE/2_channels_edit.yml index 91d247fa..65332c0e 100644 --- a/.github/ISSUE_TEMPLATE/__channels_edit.yml +++ b/.github/ISSUE_TEMPLATE/2_channels_edit.yml @@ -4,6 +4,11 @@ title: 'Edit: ' labels: ['channels:edit'] body: + - type: markdown + attributes: + value: | + Please specify exactly what should be changed. To delete an existing value without replacement use the `~` symbol. + - type: input id: id attributes: @@ -13,11 +18,6 @@ body: validations: required: true - - type: markdown - attributes: - value: | - Please specify exactly what should be changed. To delete an existing value without replacement use the `~` symbol. - - type: input id: name attributes: @@ -67,20 +67,6 @@ body: description: Name of the city from which the channel is transmitted placeholder: 'Hefei' - - type: input - id: broadcast_area - attributes: - label: Broadcast Area - description: List of codes describing the broadcasting area of the channel separated by `;`. Any combination of `r/`, `c/`, `s/` - placeholder: 'c/CN;r/EUR' - - - type: input - id: languages - attributes: - label: Languages - description: List of languages in which the channel is broadcast separated by `;`. A list of all supported languages and their codes can be found in [data/languages.csv](https://github.com/iptv-org/database/blob/master/data/languages.csv) - placeholder: 'zho;eng' - - type: input id: categories attributes: @@ -97,27 +83,6 @@ body: - 'FALSE' - 'TRUE' - - type: input - id: launched - attributes: - label: Launched - description: Launch date of the channel (`YYYY-MM-DD`) - placeholder: '2016-07-28' - - - type: input - id: closed - attributes: - label: Closed - description: Date on which the channel closed (`YYYY-MM-DD`) - placeholder: '2020-05-31' - - - type: input - id: replaced_by - attributes: - label: Replaced By - description: The ID of the channel that this channel was replaced by - placeholder: 'CCTV1.cn' - - type: input id: website attributes: diff --git a/.github/ISSUE_TEMPLATE/__channels_remove.yml b/.github/ISSUE_TEMPLATE/3_channels_remove.yml similarity index 67% rename from .github/ISSUE_TEMPLATE/__channels_remove.yml rename to .github/ISSUE_TEMPLATE/3_channels_remove.yml index fea7d866..d0ea7937 100644 --- a/.github/ISSUE_TEMPLATE/__channels_remove.yml +++ b/.github/ISSUE_TEMPLATE/3_channels_remove.yml @@ -4,9 +4,14 @@ title: 'Remove: ' labels: ['channels:remove'] body: + - type: markdown + attributes: + value: | + Deleting a channel will also delete all associated feeds and records in the blocklist. + - type: input attributes: - label: Channel ID (required) + label: Channel ID description: The ID of the channel that should be removed placeholder: 'AnhuiTV.cn' validations: @@ -14,7 +19,7 @@ body: - type: dropdown attributes: - label: Reason (required) + label: Reason description: Select the reason for removal from the list below options: - 'Duplicate' @@ -25,5 +30,5 @@ body: - type: textarea attributes: - label: Notes - description: 'Any additional information' + label: Notes (optional) + description: 'Anything else we should know?' diff --git a/.github/ISSUE_TEMPLATE/4_feeds_add.yml b/.github/ISSUE_TEMPLATE/4_feeds_add.yml new file mode 100644 index 00000000..a1b89bac --- /dev/null +++ b/.github/ISSUE_TEMPLATE/4_feeds_add.yml @@ -0,0 +1,113 @@ +name: ➕ Add feed +description: Request to add a channel feed into the database +title: 'Add: ' +labels: ['feeds:add'] + +body: + - type: markdown + attributes: + value: | + Please fill out the issue form as much as you can so we could efficiently process your request. + + - type: input + id: channel_id + attributes: + label: Channel ID (required) + description: ID of the channel to which this feed belongs + placeholder: 'HBO.us' + validations: + required: true + + - type: input + id: feed_name + attributes: + label: Feed Name + description: "Name of the feed in English. May include: `a-z`, `0-9`, `space`, `-`, `!`, `:`, `&`, `.`, `+`, `'`, `/`, `»`, `#`, `%`, `°`, `$`, `@`, `?`, `|`, `¡`" + placeholder: 'SD' + validations: + required: true + + - type: dropdown + id: is_main + attributes: + label: Main Feed + description: Indicates if this feed is the main for the channel + options: + - 'FALSE' + - 'TRUE' + validations: + required: true + + - type: input + id: broadcast_area + attributes: + label: Broadcast Area + description: "List of codes describing the broadcasting area of the feed separated by `;`. Any combination of `r/`, `c/`, `s/`. A full list of supported codes can be found here: [data/countries.csv](https://github.com/iptv-org/database/blob/master/data/countries.csv), [data/subdivisions.csv](https://github.com/iptv-org/database/blob/master/data/subdivisions.csv), [data/regions.csv](https://github.com/iptv-org/database/blob/master/data/regions.csv)" + placeholder: 'c/CN' + validations: + required: true + + - type: input + id: timezones + attributes: + label: Timezones + description: List of broadcast time zones separated by `;`. A list of all supported timezones and their codes can be found in [data/timezones.csv](https://github.com/iptv-org/database/blob/master/data/timezones.csv) + placeholder: 'Asia/Shanghai' + validations: + required: true + + - type: input + id: languages + attributes: + label: Languages + description: List of languages in which the feed is broadcast separated by `;`. A list of all supported languages and their codes can be found in [data/languages.csv](https://github.com/iptv-org/database/blob/master/data/languages.csv) + placeholder: 'zho;eng' + validations: + required: true + + - type: input + id: video_format + attributes: + label: Format + description: Video format of the broadcast + default: 6 + options: + - '4320p' + - '2160p' + - '1080p' + - '1080i' + - '720p' + - '576p' + - '576i' + - '480p' + - '480i' + - '360p' + - '240p' + validations: + required: true + + - type: input + id: launched + attributes: + label: Launched (optional) + description: Launch date of the feed (`YYYY-MM-DD`) + placeholder: '2016-07-28' + + - type: input + id: closed + attributes: + label: Closed (optional) + description: Date on which the feed closed (`YYYY-MM-DD`) + placeholder: '2020-05-31' + + - type: input + id: replaced_by + attributes: + label: Replaced By (optional) + description: "ID of the channel and feed this feed was replaced with. Possible values: `` or `@`" + placeholder: 'CCTV1.cn@SD' + + - type: textarea + attributes: + label: Notes + description: 'Anything else we should know?' diff --git a/.github/ISSUE_TEMPLATE/5_feeds_edit.yml b/.github/ISSUE_TEMPLATE/5_feeds_edit.yml new file mode 100644 index 00000000..6042da04 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/5_feeds_edit.yml @@ -0,0 +1,109 @@ +name: ✏️ Edit feed +description: Request to edit feed description +title: 'Edit: ' +labels: ['feeds:edit'] + +body: + - type: markdown + attributes: + value: | + Please specify exactly what should be changed. To delete an existing value without replacement use the `~` symbol. + + - type: input + id: channel_id + attributes: + label: Channel ID (required) + description: ID of the channel to which this feed belongs + placeholder: 'HBO.us' + validations: + required: true + + - type: input + id: feed_id + attributes: + label: Feed ID (required) + description: The ID of the feed that should be updated + placeholder: 'West' + validations: + required: true + + - type: input + id: feed_name + attributes: + label: Feed Name + description: "Name of the feed in English. May include: `a-z`, `0-9`, `space`, `-`, `!`, `:`, `&`, `.`, `+`, `'`, `/`, `»`, `#`, `%`, `°`, `$`, `@`, `?`, `|`, `¡`" + placeholder: 'West HD' + + - type: dropdown + id: is_main + attributes: + label: Main Feed + description: Indicates if this feed is the main for the channel + options: + - 'FALSE' + - 'TRUE' + + - type: input + id: broadcast_area + attributes: + label: Broadcast Area + description: "List of codes describing the broadcasting area of the feed separated by `;`. Any combination of `r/`, `c/`, `s/`. A full list of supported codes can be found here: [countries](https://github.com/iptv-org/database/blob/master/data/countries.csv), [subdivisions](https://github.com/iptv-org/database/blob/master/data/subdivisions.csv), [regions](https://github.com/iptv-org/database/blob/master/data/regions.csv)" + placeholder: 'c/CN' + + - type: input + id: timezones + attributes: + label: Timezones + description: List of broadcast time zones separated by `;`. A list of all supported timezones and their codes can be found in [data/timezones.csv](https://github.com/iptv-org/database/blob/master/data/timezones.csv) + placeholder: 'Asia/Shanghai' + + - type: input + id: languages + attributes: + label: Languages + description: List of languages in which the feed is broadcast separated by `;`. A list of all supported languages and their codes can be found in [data/languages.csv](https://github.com/iptv-org/database/blob/master/data/languages.csv) + placeholder: 'zho;eng' + + - type: input + id: video_format + attributes: + label: Format + description: Video format of the broadcast + options: + - '4320p' + - '2160p' + - '1080p' + - '1080i' + - '720p' + - '576p' + - '576i' + - '480p' + - '480i' + - '360p' + - '240p' + + - type: input + id: launched + attributes: + label: Launched + description: Launch date of the feed (`YYYY-MM-DD`) + placeholder: '2016-07-28' + + - type: input + id: closed + attributes: + label: Closed + description: Date on which the feed closed (`YYYY-MM-DD`) + placeholder: '2020-05-31' + + - type: input + id: replaced_by + attributes: + label: Replaced By + description: "ID of the channel and feed this feed was replaced with. Possible values: `` or `@`" + placeholder: 'CCTV1.cn@SD' + + - type: textarea + attributes: + label: Notes + description: 'Anything else we should know?' diff --git a/.github/ISSUE_TEMPLATE/6_feeds_remove.yml b/.github/ISSUE_TEMPLATE/6_feeds_remove.yml new file mode 100644 index 00000000..95e625f3 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/6_feeds_remove.yml @@ -0,0 +1,38 @@ +name: 🗑️ Remove feed +description: Request to remove a feed from the database +title: 'Remove: ' +labels: ['feeds:remove'] + +body: + - type: input + id: channel_id + attributes: + label: Channel ID + description: ID of the channel to which this feed belongs + placeholder: 'HBO.us' + validations: + required: true + + - type: input + id: feed_id + attributes: + label: Feed ID + description: The ID of the feed that should be updated + placeholder: 'West' + validations: + required: true + + - type: dropdown + attributes: + label: Reason + description: Select the reason for removal from the list below + options: + - 'Duplicate' + - 'Other' + validations: + required: true + + - type: textarea + attributes: + label: Notes (optional) + description: 'Anything else we should know?' diff --git a/.github/ISSUE_TEMPLATE/_blocklist_add.yml b/.github/ISSUE_TEMPLATE/7_blocklist_add.yml similarity index 84% rename from .github/ISSUE_TEMPLATE/_blocklist_add.yml rename to .github/ISSUE_TEMPLATE/7_blocklist_add.yml index d12e4311..a640ee9c 100644 --- a/.github/ISSUE_TEMPLATE/_blocklist_add.yml +++ b/.github/ISSUE_TEMPLATE/7_blocklist_add.yml @@ -5,7 +5,7 @@ labels: ['blocklist:add'] body: - type: input - id: id + id: channel attributes: label: Channel ID description: The ID of the channel that should be blocked @@ -28,7 +28,7 @@ body: id: ref attributes: label: Reference - description: Link to the official request for channel removal + description: Link to DMCA notice or approved channel removal request placeholder: 'https://github.com/iptv-org/iptv/issues/1831' validations: required: true @@ -36,4 +36,4 @@ body: - type: textarea attributes: label: Notes (optional) - description: 'Any additional information' + description: 'Anything else we should know?' diff --git a/.github/ISSUE_TEMPLATE/_blocklist_remove.yml b/.github/ISSUE_TEMPLATE/8_blocklist_remove.yml similarity index 58% rename from .github/ISSUE_TEMPLATE/_blocklist_remove.yml rename to .github/ISSUE_TEMPLATE/8_blocklist_remove.yml index 4e02b489..fe06c9b5 100644 --- a/.github/ISSUE_TEMPLATE/_blocklist_remove.yml +++ b/.github/ISSUE_TEMPLATE/8_blocklist_remove.yml @@ -5,24 +5,17 @@ labels: ['blocklist:remove'] body: - type: input + id: channel attributes: - label: Channel ID (required) + label: Channel ID description: The ID of the channel that should be removed placeholder: 'AnhuiTV.cn' validations: required: true - - type: dropdown - attributes: - label: Reason (required) - description: Select the reason for removal from the list below - options: - - 'Invalid channel id' - - 'Other' - validations: - required: true - - type: textarea attributes: label: Notes - description: 'Any additional information' + description: 'Describe in detail the reason for removing the channel from the blocklist' + validations: + required: true diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1f94551c..90e65c51 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -11,9 +11,9 @@ ### How to add a new channel to the database? -The easiest way is to send a request through this [form](https://github.com/iptv-org/database/issues/new?assignees=&labels=channels%3Aadd&projects=&template=__channels_add.yml&title=Add%3A+). Just fill in all the information you know about the channel and press send. Once your request is approved, the channel will automatically be added to the database. +The easiest way is to send a request through this [form](https://github.com/iptv-org/database/issues/new?assignees=&labels=channels%3Aadd&projects=&template=1_channels_add.yml&title=Add%3A+). Just fill in all the information you know about the channel and press send. Once your request is approved, the channel will automatically be added to the database. -If you want to add more than one channel, you can do it directly by editing the [data/channels.csv](data/channels.csv) file in any text editor. After editing the file, just [commit](https://docs.github.com/en/pull-requests/committing-changes-to-your-project/creating-and-editing-commits/about-commits) all changes and send us a [pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests). +If you want to add more than one channel, you can do it directly by editing the [data/channels.csv](data/channels.csv) file in any text editor. After that, just [commit](https://docs.github.com/en/pull-requests/committing-changes-to-your-project/creating-and-editing-commits/about-commits) all changes and send us a [pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests). **IMPORTANT:** Before sending the request, make sure that the number of columns in the file has not changed and that all rows end with [CRLF](https://developer.mozilla.org/en-US/docs/Glossary/CRLF). Otherwise we will not be able to review this request. @@ -21,7 +21,7 @@ If you want to add more than one channel, you can do it directly by editing the As with adding a channel, this can be done in several ways. -The first option is to send a request through this [form](https://github.com/iptv-org/database/issues/new?assignees=&labels=channels%3Aedit&projects=&template=__channels_edit.yml&title=Edit%3A+). Just specify the ID of the channel you want to edit and the new data. To delete a value, insert `~` in the desired field. After your request is approved, the channel description will be automatically updated. +The first option is to send a request through this [form](https://github.com/iptv-org/database/issues/new?assignees=&labels=channels%3Aedit&projects=&template=2_channels_edit.yml&title=Edit%3A+). Just specify the ID of the channel you want to edit and the new data. To delete a value, insert `~` in the desired field. After your request is approved, the channel description will be automatically updated. The second option is to edit the [data/channels.csv](data/channels.csv) file using a text editor and then send us a [pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests). @@ -29,13 +29,35 @@ The second option is to edit the [data/channels.csv](data/channels.csv) file usi ### How to remove a channel from the database? -To remove a channel just fill out this [form](https://github.com/iptv-org/database/issues/new?assignees=&labels=channels%3Aremove&projects=&template=__channels_remove.yml&title=Remove%3A+) with channel ID and the reason for deletion. +To remove a channel fill out this [form](https://github.com/iptv-org/database/issues/new?assignees=&labels=channels%3Aremove&projects=&template=3_channels_remove.yml&title=Remove%3A+) with channel ID and the reason for deletion. -**NOTE:** Closing a channel is not a reason to remove it from the database. In this case you just need to mark the channel as closed. +**NOTE:** Closing a channel is not a reason to remove it from the database. ### How to mark a channel as closed? -To do this, use this [form](https://github.com/iptv-org/database/issues/new?assignees=&labels=channels%3Aedit&projects=&template=__channels_edit.yml&title=Edit%3A+). In it, in the "Closed" field you will need to specify at least the approximate date of closing. And there you can also specify the ID of the channel that replaced it, if necessary. +To do this, you need to mark the main feed of the channel as closed. [How to mark a feed as closed?](#how-to-mark-a-feed-as-closed?) + +### How to add a new feed to the database? + +_Option 1:_ Send a request through this [form](https://github.com/iptv-org/database/issues/new?assignees=&labels=feeds%3Aadd&projects=&template=4_feeds_add.yml&title=Add%3A+). Fill in all the information you know about the feed and press send. Once your request is approved, the feed will automatically be added to the database. + +_Option 2:_ Edit the [data/feeds.csv](data/feeds.csv) file using a text editor and then send us a [pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests). + +### How to edit feed description? + +_Option 1:_ Send a request through this [form](https://github.com/iptv-org/database/issues/new?assignees=&labels=feeds%3Aedit&projects=&template=5_feeds_edit.yml&title=Edit%3A+). Specify the ID of the channel and feed you want to edit and the new data. To delete a value, insert `~` in the desired field. After your request is approved, the feed description will be automatically updated. + +_Option 2:_ Edit the [data/feeds.csv](data/feeds.csv) file using a text editor and then send us a [pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests). + +### How to remove a feed from the database? + +To remove a feed just fill out this [form](https://github.com/iptv-org/database/issues/new?assignees=&labels=feeds%3Aremove&projects=&template=6_feeds_remove.yml&title=Remove%3A+). + +**NOTE:** Ceased broadcasting is no reason to remove a feed from the database. In this case you just need to mark the feed as closed. + +### How to mark a feed as closed? + +To do this, use this [form](https://github.com/iptv-org/database/issues/new?assignees=&labels=feeds%3Aedit&projects=&template=5_feeds_edit.yml&title=Edit%3A+). In it, in the "Closed" field you will need to specify at least the approximate date of broadcast termination. And there you can also specify the ID of the channel and feed that replaced it, if necessary. ## Data Scheme @@ -51,16 +73,32 @@ To do this, use this [form](https://github.com/iptv-org/database/issues/new?assi | country | Country code from which the channel is transmitted. A list of all supported countries and their codes can be found in [data/countries.csv](data/countries.csv) | Required | `CN` | | subdivision | Code of the subdivision (e.g., provinces or states) from which the broadcast is transmitted. A list of all supported subdivisions and their codes can be found in [data/subdivisions.csv](data/subdivisions.csv). | Optional | `CN-AH` | | city | The name of the city in English from which the channel is broadcast. May contain any characters except `,` and `"`. | Optional | `Hefei` | -| broadcast_area | List of codes describing the broadcasting area of the channel separated by `;`. Any combination of `r/`, `c/`, `s/`. | Required | `c/CN;r/ASIA` | -| languages | List of languages in which the channel is broadcast separated by `;`. A list of all supported languages and their codes can be found in [data/languages.csv](data/languages.csv). | Required | `zho;eng` | +| broadcast_area | [DEPRECATED] List of codes describing the broadcasting area of the channel separated by `;`. Any combination of `r/`, `c/`, `s/`. | Required | `c/CN;r/ASIA` | +| languages | [DEPRECATED] List of languages in which the channel is broadcast separated by `;`. A list of all supported languages and their codes can be found in [data/languages.csv](data/languages.csv). | Required | `zho;eng` | | categories | List of categories to which this channel belongs separated by `;`. A list of all supported categories can be found in [data/categories.csv](data/categories.csv). | Optional | `animation;kids` | | is_nsfw | Indicates whether the channel broadcasts adult content (`TRUE` or `FALSE`). | Required | `FALSE` | -| launched | Launch date of the channel (`YYYY-MM-DD`). | Optional | `2016-07-28` | -| closed | Date on which the channel closed (`YYYY-MM-DD`). | Optional | `2020-05-31` | -| replaced_by | The ID of the channel that this channel was replaced by. | Optional | `CCTV1.cn` | +| launched | [DEPRECATED] Launch date of the channel (`YYYY-MM-DD`). | Optional | `2016-07-28` | +| closed | [DEPRECATED] Date on which the channel closed (`YYYY-MM-DD`). | Optional | `2020-05-31` | +| replaced_by | [DEPRECATED] The ID of the channel that this channel was replaced by. | Optional | `CCTV1.cn` | | website | Official website URL. | Optional | `http://www.ahtv.cn/` | | logo | Logo URL. Only URL with [HTTPS](https://ru.wikipedia.org/wiki/HTTPS) protocol are allowed. Supported image types: `PNG`, `JPEG`. Max size: 512x512 pixels. The link should not be [geo-blocked](https://en.wikipedia.org/wiki/Geo-blocking). May contain any characters except `,` and `"`. | Required | `https://example.com/logo.png` | +### feeds + +| Field | Description | Required | Example | +| -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | --------------------- | +| channel | ID of the channel to which this feed belongs. | Required | `HBO.us` | +| id | Unique feed ID derived from the `name`. May only contain Latin letters and numbers. | Required | `West` | +| name | Name of the feed in English. May include: `a-z`, `0-9`, `space`, `-`, `!`, `:`, `&`, `.`, `+`, `'`, `/`, `»`, `#`, `%`, `°`, `$`, `@`, `?`, \|, `¡`. | Required | `West` | +| is_main | Indicates if this feed is the main for the channel (`TRUE` or `FALSE`). | Required | `FALSE` | +| broadcast_area | List of codes describing the broadcasting area of the feed separated by `;`. Any combination of `r/`, `c/`, `s/` is allowed. A full list of supported codes can be found here: [data/countries.csv](https://github.com/iptv-org/database/blob/master/data/countries.csv), [data/subdivisions.csv](https://github.com/iptv-org/database/blob/master/data/subdivisions.csv), [data/regions.csv](https://github.com/iptv-org/database/blob/master/data/regions.csv). | Required | `s/US-CA;s/US-ID` | +| timezones | List of timezones in which the feed is broadcast separated by `;`. A list of all supported timezones and their codes can be found in [data/timezones.csv](data/timezones.csv). | Required | `America/Los_Angeles` | +| languages | List of languages in which the feed is broadcast separated by `;`. A list of all supported languages and their codes can be found in [data/languages.csv](data/languages.csv). | Required | `eng;spa` | +| video_format | Video format of the feed. | Required | `1080i` | +| launched | Launch date of the feed (`YYYY-MM-DD`). | Optional | `2016-07-28` | +| closed | Date on which the feed ceased broadcasting (`YYYY-MM-DD`). | Optional | `2020-05-31` | +| replaced_by | ID of the channel and feed this feed was replaced with. Possible values: `` or `@`. | Optional | `HBO.us@East` | + ### categories | Field | Description | Required | Example | @@ -86,11 +124,11 @@ To do this, use this [form](https://github.com/iptv-org/database/issues/new?assi ### subdivisions -| Field | Description | Required | Example | -| ------- | ------------------------------------------------------------------------------ | -------- | ------------------ | -| country | Country code of the division | Required | `CA` | -| name | Official subdivision name | Required | `British Columbia` | -| code | [ISO 3166-2](https://en.wikipedia.org/wiki/ISO_3166-2) code of the subdivision | Required | `CA-BC` | +| Field | Description | Required | Example | +| ------- | ------------------------------------------------------------------------------------------ | -------- | ------------------ | +| country | [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) code of the country | Required | `CA` | +| name | Official subdivision name | Required | `British Columbia` | +| code | [ISO 3166-2](https://en.wikipedia.org/wiki/ISO_3166-2) code of the subdivision | Required | `CA-BC` | ### regions @@ -100,6 +138,14 @@ To do this, use this [form](https://github.com/iptv-org/database/issues/new?assi | code | Abbreviated designation for the region. May only contain Latin letters in upper case. The minimum length is 3 letters. | Required | `CAS` | | countries | List of country codes in the region | Required | `KG;KZ;TJ;TM;UZ` | +### timezones + +| Field | Description | Required | Example | +| ---------- | ------------------------------------------------------------------------- | -------- | --------------------- | +| id | Timezone ID from [tz database](https://en.wikipedia.org/wiki/Tz_database) | Required | `Africa/Johannesburg` | +| utc_offset | [UTC offset](https://en.wikipedia.org/wiki/UTC_offset) for this time zone | Required | `+02:00` | +| countries | List of countries included in this time zone | Required | `ZA;LS;SZ` | + ### blocklist List of channels blocked at the request of copyright holders. diff --git a/data/feeds.csv b/data/feeds.csv new file mode 100644 index 00000000..ddc8b553 --- /dev/null +++ b/data/feeds.csv @@ -0,0 +1 @@ +channel,id,name,is_main,broadcast_area,timezones,languages,video_format,launched,closed,replaced_by \ No newline at end of file diff --git a/data/timezones.csv b/data/timezones.csv new file mode 100644 index 00000000..def89050 --- /dev/null +++ b/data/timezones.csv @@ -0,0 +1,417 @@ +id,utc_offset,countries +Africa/Abidjan,+00:00,CI;BF;GH;GM;GN;IS;ML;MR;SH;SL;SN;TG +Africa/Accra,+00:00,GH +Africa/Addis_Ababa,+03:00,ET +Africa/Algiers,+01:00,DZ +Africa/Asmara,+03:00,ER +Africa/Bamako,+00:00,ML +Africa/Bangui,+01:00,CF +Africa/Banjul,+00:00,GM +Africa/Bissau,+00:00,GW +Africa/Blantyre,+02:00,MW +Africa/Brazzaville,+01:00,CG +Africa/Bujumbura,+02:00,BI +Africa/Cairo,+02:00,EG +Africa/Casablanca,+00:00,MA +Africa/Ceuta,+01:00,ES +Africa/Conakry,+00:00,GN +Africa/Dakar,+00:00,SN +Africa/Dar_es_Salaam,+03:00,TZ +Africa/Djibouti,+03:00,DJ +Africa/Douala,+01:00,CM +Africa/El_Aaiun,+00:00,EH +Africa/Freetown,+00:00,SL +Africa/Gaborone,+02:00,BW +Africa/Harare,+02:00,ZW +Africa/Johannesburg,+02:00,ZA;LS;SZ +Africa/Juba,+02:00,SS +Africa/Kampala,+03:00,UG +Africa/Khartoum,+02:00,SD +Africa/Kigali,+02:00,RW +Africa/Kinshasa,+01:00,CD +Africa/Lagos,+01:00,NG;AO;BJ;CD;CF;CG;CM;GA;GQ;NE +Africa/Libreville,+01:00,GA +Africa/Lome,+00:00,TG +Africa/Luanda,+01:00,AO +Africa/Lubumbashi,+02:00,CD +Africa/Lusaka,+02:00,ZM +Africa/Malabo,+01:00,GQ +Africa/Maputo,+02:00,MZ;BI;BW;CD;MW;RW;ZM;ZW +Africa/Maseru,+02:00,LS +Africa/Mbabane,+02:00,SZ +Africa/Mogadishu,+03:00,SO +Africa/Monrovia,+00:00,LR +Africa/Nairobi,+03:00,KE;DJ;ER;ET;KM;MG;SO;TZ;UG;YT +Africa/Ndjamena,+01:00,TD +Africa/Niamey,+01:00,NE +Africa/Nouakchott,+00:00,MR +Africa/Ouagadougou,+00:00,BF +Africa/Porto-Novo,+01:00,BJ +Africa/Sao_Tome,+00:00,ST +Africa/Tripoli,+02:00,LY +Africa/Tunis,+01:00,TN +Africa/Windhoek,+01:00,NA +America/Adak,-10:00,US +America/Anchorage,-09:00,US +America/Anguilla,-04:00,AI +America/Antigua,-04:00,AG +America/Araguaina,-03:00,BR +America/Argentina/Buenos_Aires,-03:00,AR +America/Argentina/Catamarca,-03:00,AR +America/Argentina/Cordoba,-03:00,AR +America/Argentina/Jujuy,-03:00,AR +America/Argentina/La_Rioja,-03:00,AR +America/Argentina/Mendoza,-03:00,AR +America/Argentina/Rio_Gallegos,-03:00,AR +America/Argentina/Salta,-03:00,AR +America/Argentina/San_Juan,-03:00,AR +America/Argentina/San_Luis,-03:00,AR +America/Argentina/Tucuman,-03:00,AR +America/Argentina/Ushuaia,-03:00,AR +America/Aruba,-04:00,AW +America/Asuncion,-04:00,PY +America/Atikokan,-05:00,CA +America/Bahia,-03:00,BR +America/Bahia_Banderas,-06:00,MX +America/Barbados,-04:00,BB +America/Belem,-03:00,BR +America/Belize,-06:00,BZ +America/Blanc-Sablon,-04:00,CA +America/Boa_Vista,-04:00,BR +America/Bogota,-05:00,CO +America/Boise,-07:00,US +America/Cambridge_Bay,-07:00,CA +America/Campo_Grande,-04:00,BR +America/Cancun,-05:00,MX +America/Caracas,-04:00,VE +America/Cayenne,-03:00,GF +America/Cayman,-05:00,KY +America/Chicago,-06:00,US +America/Chihuahua,-07:00,MX +America/Costa_Rica,-06:00,CR +America/Creston,-07:00,CA +America/Cuiaba,-04:00,BR +America/Curacao,-04:00,CW +America/Danmarkshavn,+00:00,GL +America/Dawson,-07:00,CA +America/Dawson_Creek,-07:00,CA +America/Denver,-07:00,US +America/Detroit,-05:00,US +America/Dominica,-04:00,DM +America/Edmonton,-07:00,CA +America/Eirunepe,-05:00,BR +America/El_Salvador,-06:00,SV +America/Fort_Nelson,-07:00,CA +America/Fortaleza,-03:00,BR +America/Glace_Bay,-04:00,CA +America/Goose_Bay,-04:00,CA +America/Grand_Turk,-05:00,TC +America/Grenada,-04:00,GD +America/Guadeloupe,-04:00,GP +America/Guatemala,-06:00,GT +America/Guayaquil,-05:00,EC +America/Guyana,-04:00,GY +America/Halifax,-04:00,CA +America/Havana,-05:00,CU +America/Hermosillo,-07:00,MX +America/Indiana/Indianapolis,-05:00,US +America/Indiana/Knox,-06:00,US +America/Indiana/Marengo,-05:00,US +America/Indiana/Petersburg,-05:00,US +America/Indiana/Tell_City,-06:00,US +America/Indiana/Vevay,-05:00,US +America/Indiana/Vincennes,-05:00,US +America/Indiana/Winamac,-05:00,US +America/Inuvik,-07:00,CA +America/Iqaluit,-05:00,CA +America/Jamaica,-05:00,JM +America/Juneau,-09:00,US +America/Kentucky/Louisville,-05:00,US +America/Kentucky/Monticello,-05:00,US +America/Kralendijk,-04:00,BQ +America/La_Paz,-04:00,BO +America/Lima,-05:00,PE +America/Los_Angeles,-08:00,US +America/Lower_Princes,-04:00,SX +America/Maceio,-03:00,BR +America/Managua,-06:00,NI +America/Manaus,-04:00,BR +America/Marigot,-04:00,MF +America/Martinique,-04:00,MQ +America/Matamoros,-06:00,MX +America/Mazatlan,-07:00,MX +America/Menominee,-06:00,US +America/Merida,-06:00,MX +America/Metlakatla,-09:00,US +America/Mexico_City,-06:00,MX +America/Miquelon,-03:00,PM +America/Moncton,-04:00,CA +America/Monterrey,-06:00,MX +America/Montevideo,-03:00,UY +America/Montserrat,-04:00,MS +America/Nassau,-05:00,BS +America/New_York,-05:00,US +America/Nipigon,-05:00,CA +America/Nome,-09:00,US +America/Noronha,-02:00,BR +America/North_Dakota/Beulah,-06:00,US +America/North_Dakota/Center,-06:00,US +America/North_Dakota/New_Salem,-06:00,US +America/Nuuk,-02:00,GL +America/Ojinaga,-07:00,MX +America/Panama,-05:00,PA;CA;KY +America/Paramaribo,-03:00,SR +America/Phoenix,-07:00,US;CA +America/Port-au-Prince,-05:00,HT +America/Port_of_Spain,-04:00,TT +America/Porto_Velho,-04:00,BR +America/Puerto_Rico,-04:00,PR;AG;CA;AI;AW;BL;BQ;CW;DM;GD;GP;KN;LC;MF;MS;SX;TT;VC;VG;VI +America/Punta_Arenas,-03:00,CL +America/Rankin_Inlet,-06:00,CA +America/Recife,-03:00,BR +America/Regina,-06:00,CA +America/Resolute,-06:00,CA +America/Rio_Branco,-05:00,BR +America/Santarem,-03:00,BR +America/Santiago,-04:00,CL +America/Santo_Domingo,-04:00,DO +America/Sao_Paulo,-03:00,BR +America/Scoresbysund,-01:00,GL +America/Sitka,-09:00,US +America/St_Barthelemy,-04:00,BL +America/St_Johns,-03:30,CA +America/St_Kitts,-04:00,KN +America/St_Lucia,-04:00,LC +America/St_Thomas,-04:00,VI +America/St_Vincent,-04:00,VC +America/Swift_Current,-06:00,CA +America/Tegucigalpa,-06:00,HN +America/Thule,-04:00,GL +America/Thunder_Bay,-05:00,CA +America/Tijuana,-08:00,MX +America/Toronto,-05:00,CA;BS +America/Tortola,-04:00,VG +America/Vancouver,-08:00,CA +America/Whitehorse,-07:00,CA +America/Winnipeg,-06:00,CA +America/Yakutat,-09:00,US +Antarctica/Casey,+08:00,AQ +Antarctica/Davis,+07:00,AQ +Antarctica/DumontDUrville,+10:00,AQ +Antarctica/Macquarie,+10:00,AU +Antarctica/Mawson,+05:00,AQ +Antarctica/McMurdo,+12:00,AQ +Antarctica/Palmer,-03:00,AQ +Antarctica/Rothera,-03:00,AQ +Antarctica/Syowa,+03:00,AQ +Antarctica/Troll,+00:00,AQ +Antarctica/Vostok,+06:00,AQ +Arctic/Longyearbyen,+01:00,SJ +Asia/Aden,+03:00,YE +Asia/Almaty,+05:00,KZ +Asia/Amman,+02:00,JO +Asia/Anadyr,+12:00,RU +Asia/Aqtau,+05:00,KZ +Asia/Aqtobe,+05:00,KZ +Asia/Ashgabat,+05:00,TM +Asia/Atyrau,+05:00,KZ +Asia/Baghdad,+03:00,IQ +Asia/Bahrain,+03:00,BH +Asia/Baku,+04:00,AZ +Asia/Bangkok,+07:00,TH;CX;KH;LA;VN +Asia/Barnaul,+07:00,RU +Asia/Beirut,+02:00,LB +Asia/Bishkek,+06:00,KG +Asia/Brunei,+08:00,BN +Asia/Chita,+09:00,RU +Asia/Colombo,+05:30,LK +Asia/Damascus,+02:00,SY +Asia/Dhaka,+06:00,BD +Asia/Dili,+09:00,TL +Asia/Dubai,+04:00,AE;OM;RE;SC;TF +Asia/Dushanbe,+05:00,TJ +Asia/Famagusta,+02:00,CY +Asia/Gaza,+02:00,PS +Asia/Hebron,+02:00,PS +Asia/Ho_Chi_Minh,+07:00,VN +Asia/Hong_Kong,+08:00,HK +Asia/Hovd,+07:00,MN +Asia/Irkutsk,+08:00,RU +Asia/Jakarta,+07:00,ID +Asia/Jayapura,+09:00,ID +Asia/Jerusalem,+02:00,IL +Asia/Kabul,+04:30,AF +Asia/Kamchatka,+12:00,RU +Asia/Karachi,+05:00,PK +Asia/Kathmandu,+05:45,NP +Asia/Khandyga,+09:00,RU +Asia/Kolkata,+05:30,IN +Asia/Krasnoyarsk,+07:00,RU +Asia/Kuala_Lumpur,+08:00,MY +Asia/Kuching,+08:00,MY;BN +Asia/Kuwait,+03:00,KW +Asia/Macau,+08:00,MO +Asia/Magadan,+11:00,RU +Asia/Makassar,+08:00,ID +Asia/Manila,+08:00,PH +Asia/Muscat,+04:00,OM +Asia/Nicosia,+02:00,CY +Asia/Novokuznetsk,+07:00,RU +Asia/Novosibirsk,+07:00,RU +Asia/Omsk,+06:00,RU +Asia/Oral,+05:00,KZ +Asia/Phnom_Penh,+07:00,KH +Asia/Pontianak,+07:00,ID +Asia/Pyongyang,+09:00,KP +Asia/Qatar,+03:00,QA;BH +Asia/Qostanay,+06:00,KZ +Asia/Qyzylorda,+05:00,KZ +Asia/Riyadh,+03:00,SA;AQ;KW;YE +Asia/Sakhalin,+11:00,RU +Asia/Samarkand,+05:00,UZ +Asia/Seoul,+09:00,KR +Asia/Shanghai,+08:00,CN +Asia/Singapore,+08:00,SG;MY +Asia/Srednekolymsk,+11:00,RU +Asia/Taipei,+08:00,TW +Asia/Tashkent,+05:00,UZ +Asia/Tbilisi,+04:00,GE +Asia/Tehran,+03:30,IR +Asia/Thimphu,+06:00,BT +Asia/Tokyo,+09:00,JP +Asia/Tomsk,+07:00,RU +Asia/Ulaanbaatar,+08:00,MN +Asia/Urumqi,+06:00,CN +Asia/Ust-Nera,+10:00,RU +Asia/Vientiane,+07:00,LA +Asia/Vladivostok,+10:00,RU +Asia/Yakutsk,+09:00,RU +Asia/Yangon,+06:30,MM;CC +Asia/Yekaterinburg,+05:00,RU +Asia/Yerevan,+04:00,AM +Atlantic/Azores,-01:00,PT +Atlantic/Bermuda,-04:00,BM +Atlantic/Canary,+00:00,ES +Atlantic/Cape_Verde,-01:00,CV +Atlantic/Faroe,+00:00,FO +Atlantic/Madeira,+00:00,PT +Atlantic/Reykjavik,+00:00,IS +Atlantic/South_Georgia,-02:00,GS +Atlantic/St_Helena,+00:00,SH +Atlantic/Stanley,-03:00,FK +Australia/Adelaide,+09:30,AU +Australia/Brisbane,+10:00,AU +Australia/Broken_Hill,+09:30,AU +Australia/Darwin,+09:30,AU +Australia/Eucla,+08:45,AU +Australia/Hobart,+10:00,AU +Australia/Lindeman,+10:00,AU +Australia/Lord_Howe,+10:30,AU +Australia/Melbourne,+10:00,AU +Australia/Perth,+08:00,AU +Australia/Sydney,+10:00,AU +Europe/Amsterdam,+01:00,NL +Europe/Andorra,+01:00,AD +Europe/Astrakhan,+04:00,RU +Europe/Athens,+02:00,GR +Europe/Belgrade,+01:00,RS;BA;HR;ME;MK;SI +Europe/Berlin,+01:00,DE;DK;NO;SE;SJ +Europe/Bratislava,+01:00,SK +Europe/Brussels,+01:00,BE;LU;NL +Europe/Bucharest,+02:00,RO +Europe/Budapest,+01:00,HU +Europe/Chisinau,+02:00,MD +Europe/Copenhagen,+01:00,DK +Europe/Dublin,+00:00,IE +Europe/Gibraltar,+01:00,GI +Europe/Guernsey,+00:00,GG +Europe/Helsinki,+02:00,FI;AX +Europe/Isle_of_Man,+00:00,IM +Europe/Istanbul,+03:00,TR +Europe/Jersey,+00:00,JE +Europe/Kaliningrad,+02:00,RU +Europe/Kirov,+03:00,RU +Europe/Kyiv,+02:00,UA +Europe/Lisbon,+00:00,PT +Europe/Ljubljana,+01:00,SI +Europe/London,+00:00,UK;GG;IM;JE +Europe/Luxembourg,+01:00,LU +Europe/Madrid,+01:00,ES +Europe/Malta,+01:00,MT +Europe/Mariehamn,+02:00,AX +Europe/Minsk,+03:00,BY +Europe/Monaco,+01:00,MC +Europe/Moscow,+03:00,RU +Europe/Oslo,+01:00,NO +Europe/Paris,+01:00,FR;MC +Europe/Podgorica,+01:00,ME +Europe/Prague,+01:00,CZ;SK +Europe/Riga,+02:00,LV +Europe/Rome,+01:00,IT;SM;VA +Europe/Samara,+04:00,RU +Europe/San_Marino,+01:00,SM +Europe/Sarajevo,+01:00,BA +Europe/Saratov,+04:00,RU +Europe/Simferopol,+03:00,RU;UA +Europe/Skopje,+01:00,MK +Europe/Sofia,+02:00,BG +Europe/Stockholm,+01:00,SE +Europe/Tallinn,+02:00,EE +Europe/Tirane,+01:00,AL +Europe/Ulyanovsk,+04:00,RU +Europe/Vaduz,+01:00,LI +Europe/Vatican,+01:00,VA +Europe/Vienna,+01:00,AT +Europe/Vilnius,+02:00,LT +Europe/Volgograd,+03:00,RU +Europe/Warsaw,+01:00,PL +Europe/Zagreb,+01:00,HR +Europe/Zurich,+01:00,CH;DE;LI +Indian/Antananarivo,+03:00,MG +Indian/Chagos,+06:00,IO +Indian/Christmas,+07:00,CX +Indian/Cocos,+06:30,CC +Indian/Comoro,+03:00,KM +Indian/Kerguelen,+05:00,TF +Indian/Mahe,+04:00,SC +Indian/Maldives,+05:00,MV;TF +Indian/Mauritius,+04:00,MU +Indian/Mayotte,+03:00,YT +Indian/Reunion,+04:00,RE +Pacific/Apia,+13:00,WS +Pacific/Auckland,+12:00,NZ;AQ +Pacific/Bougainville,+11:00,PG +Pacific/Chatham,+12:45,NZ +Pacific/Chuuk,+10:00,FM +Pacific/Easter,-06:00,CL +Pacific/Efate,+11:00,VU +Pacific/Fakaofo,+13:00,TK +Pacific/Fiji,+12:00,FJ +Pacific/Funafuti,+12:00,TV +Pacific/Galapagos,-06:00,EC +Pacific/Gambier,-09:00,PF +Pacific/Guadalcanal,+11:00,SB;FM +Pacific/Guam,+10:00,GU;MP +Pacific/Honolulu,-10:00,US +Pacific/Kiritimati,+14:00,KI +Pacific/Kosrae,+11:00,FM +Pacific/Kwajalein,+12:00,MH +Pacific/Majuro,+12:00,MH +Pacific/Marquesas,-09:30,PF +Pacific/Midway,-11:00,UM +Pacific/Nauru,+12:00,NR +Pacific/Niue,-11:00,NU +Pacific/Norfolk,+11:00,NF +Pacific/Noumea,+11:00,NC +Pacific/Pago_Pago,-11:00,AS;UM +Pacific/Palau,+09:00,PW +Pacific/Pitcairn,-08:00,PN +Pacific/Pohnpei,+11:00,FM +Pacific/Port_Moresby,+10:00,PG;AQ;FM +Pacific/Rarotonga,-10:00,CK +Pacific/Saipan,+10:00,MP +Pacific/Tahiti,-10:00,PF +Pacific/Tarawa,+12:00,KI;MH;TV;UM;WF +Pacific/Tongatapu,+13:00,TO +Pacific/Wake,+12:00,UM +Pacific/Wallis,+12:00,WF \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 5a03aa22..1d1eb683 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,7 +7,7 @@ "name": "@iptv-org/database", "dependencies": { "@eslint/js": "^9.16.0", - "@freearhey/core": "^0.2.2", + "@freearhey/core": "^0.6.0", "@joi/date": "^2.1.0", "@json2csv/formatters": "^7.0.3", "@json2csv/node": "^7.0.3", @@ -56,73 +56,18 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", - "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", + "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", "dependencies": { - "@babel/highlight": "^7.23.4", - "chalk": "^2.4.2" + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/code-frame/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/code-frame/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/code-frame/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/code-frame/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" - }, - "node_modules/@babel/code-frame/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/code-frame/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/@babel/compat-data": { "version": "7.22.20", "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.20.tgz", @@ -309,17 +254,17 @@ } }, "node_modules/@babel/helper-string-parser": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", - "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", + "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", - "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", "engines": { "node": ">=6.9.0" } @@ -333,91 +278,24 @@ } }, "node_modules/@babel/helpers": { - "version": "7.23.1", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.1.tgz", - "integrity": "sha512-chNpneuK18yW5Oxsr+t553UZzzAs3aZnFm4bxhebsNTeshrC95yA7l5yl7GBAG+JG1rF0F7zzD2EixK9mWSDoA==", + "version": "7.26.10", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.10.tgz", + "integrity": "sha512-UPYc3SauzZ3JGgj87GgZ89JVdC5dj0AoetR5Bw6wj4niittNyFh6+eOGonYvJ1ao6B8lEa3Q3klS7ADZ53bc5g==", "dependencies": { - "@babel/template": "^7.22.15", - "@babel/traverse": "^7.23.0", - "@babel/types": "^7.23.0" + "@babel/template": "^7.26.9", + "@babel/types": "^7.26.10" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/highlight": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", - "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", - "dependencies": { - "@babel/helper-validator-identifier": "^7.22.20", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" - }, - "node_modules/@babel/highlight/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/@babel/parser": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.5.tgz", - "integrity": "sha512-hOOqoiNXrmGdFbhgCzu6GiURxUgM27Xwd/aPuu8RfHEZPBzL1Z54okAHAQjXfcQNwvrlkAmAp4SlRTZ45vlthQ==", + "version": "7.26.10", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.10.tgz", + "integrity": "sha512-6aQR2zGE/QFi8JpDLjUZEPYOs7+mhKXm86VaKFiLP35JQwQb6bwUE+XbvkH0EptsYhbNBSUGaUBLKqxH1xSgsA==", + "dependencies": { + "@babel/types": "^7.26.10" + }, "bin": { "parser": "bin/babel-parser.js" }, @@ -589,13 +467,13 @@ } }, "node_modules/@babel/template": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", - "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.26.9.tgz", + "integrity": "sha512-qyRplbeIpNZhmzOysF/wFMuP9sctmh2cFzRAZOn1YapxBsE1i9bJIY586R/WBLfLcmcBlM8ROBiQURnnNy+zfA==", "dependencies": { - "@babel/code-frame": "^7.22.13", - "@babel/parser": "^7.22.15", - "@babel/types": "^7.22.15" + "@babel/code-frame": "^7.26.2", + "@babel/parser": "^7.26.9", + "@babel/types": "^7.26.9" }, "engines": { "node": ">=6.9.0" @@ -630,13 +508,12 @@ } }, "node_modules/@babel/types": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.5.tgz", - "integrity": "sha512-ON5kSOJwVO6xXVRTvOI0eOnWe7VdUcIpsovGo9U/Br4Ie4UVFQTboO2cYnDhAGU6Fp+UxSiT+pMft0SMHfuq6w==", + "version": "7.26.10", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.10.tgz", + "integrity": "sha512-emqcG3vHrpxUKTrxcblR36dcrcoRDvKmnL/dCL6ZsHaShW80qxCAcNhzQZrpeM765VzEos+xOi4s+r4IXzTwdQ==", "dependencies": { - "@babel/helper-string-parser": "^7.23.4", - "@babel/helper-validator-identifier": "^7.22.20", - "to-fast-properties": "^2.0.0" + "@babel/helper-string-parser": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -672,13 +549,12 @@ } }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.23.1.tgz", - "integrity": "sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.1.tgz", + "integrity": "sha512-kfYGy8IdzTGy+z0vFGvExZtxkFlA4zAxgKEahG9KE1ScBjpQnFsNOX8KTU5ojNru5ed5CVoJYXFtoxaq5nFbjQ==", "cpu": [ "ppc64" ], - "license": "MIT", "optional": true, "os": [ "aix" @@ -688,13 +564,12 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.23.1.tgz", - "integrity": "sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.1.tgz", + "integrity": "sha512-dp+MshLYux6j/JjdqVLnMglQlFu+MuVeNrmT5nk6q07wNhCdSnB7QZj+7G8VMUGh1q+vj2Bq8kRsuyA00I/k+Q==", "cpu": [ "arm" ], - "license": "MIT", "optional": true, "os": [ "android" @@ -704,13 +579,12 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.23.1.tgz", - "integrity": "sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.1.tgz", + "integrity": "sha512-50tM0zCJW5kGqgG7fQ7IHvQOcAn9TKiVRuQ/lN0xR+T2lzEFvAi1ZcS8DiksFcEpf1t/GYOeOfCAgDHFpkiSmA==", "cpu": [ "arm64" ], - "license": "MIT", "optional": true, "os": [ "android" @@ -720,13 +594,12 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.23.1.tgz", - "integrity": "sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.1.tgz", + "integrity": "sha512-GCj6WfUtNldqUzYkN/ITtlhwQqGWu9S45vUXs7EIYf+7rCiiqH9bCloatO9VhxsL0Pji+PF4Lz2XXCES+Q8hDw==", "cpu": [ "x64" ], - "license": "MIT", "optional": true, "os": [ "android" @@ -736,13 +609,12 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.23.1.tgz", - "integrity": "sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.1.tgz", + "integrity": "sha512-5hEZKPf+nQjYoSr/elb62U19/l1mZDdqidGfmFutVUjjUZrOazAtwK+Kr+3y0C/oeJfLlxo9fXb1w7L+P7E4FQ==", "cpu": [ "arm64" ], - "license": "MIT", "optional": true, "os": [ "darwin" @@ -752,13 +624,12 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.23.1.tgz", - "integrity": "sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.1.tgz", + "integrity": "sha512-hxVnwL2Dqs3fM1IWq8Iezh0cX7ZGdVhbTfnOy5uURtao5OIVCEyj9xIzemDi7sRvKsuSdtCAhMKarxqtlyVyfA==", "cpu": [ "x64" ], - "license": "MIT", "optional": true, "os": [ "darwin" @@ -768,13 +639,12 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.23.1.tgz", - "integrity": "sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.1.tgz", + "integrity": "sha512-1MrCZs0fZa2g8E+FUo2ipw6jw5qqQiH+tERoS5fAfKnRx6NXH31tXBKI3VpmLijLH6yriMZsxJtaXUyFt/8Y4A==", "cpu": [ "arm64" ], - "license": "MIT", "optional": true, "os": [ "freebsd" @@ -784,13 +654,12 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.23.1.tgz", - "integrity": "sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.1.tgz", + "integrity": "sha512-0IZWLiTyz7nm0xuIs0q1Y3QWJC52R8aSXxe40VUxm6BB1RNmkODtW6LHvWRrGiICulcX7ZvyH6h5fqdLu4gkww==", "cpu": [ "x64" ], - "license": "MIT", "optional": true, "os": [ "freebsd" @@ -800,13 +669,12 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.23.1.tgz", - "integrity": "sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.1.tgz", + "integrity": "sha512-NdKOhS4u7JhDKw9G3cY6sWqFcnLITn6SqivVArbzIaf3cemShqfLGHYMx8Xlm/lBit3/5d7kXvriTUGa5YViuQ==", "cpu": [ "arm" ], - "license": "MIT", "optional": true, "os": [ "linux" @@ -816,13 +684,12 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.23.1.tgz", - "integrity": "sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.1.tgz", + "integrity": "sha512-jaN3dHi0/DDPelk0nLcXRm1q7DNJpjXy7yWaWvbfkPvI+7XNSc/lDOnCLN7gzsyzgu6qSAmgSvP9oXAhP973uQ==", "cpu": [ "arm64" ], - "license": "MIT", "optional": true, "os": [ "linux" @@ -832,13 +699,12 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.23.1.tgz", - "integrity": "sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.1.tgz", + "integrity": "sha512-OJykPaF4v8JidKNGz8c/q1lBO44sQNUQtq1KktJXdBLn1hPod5rE/Hko5ugKKZd+D2+o1a9MFGUEIUwO2YfgkQ==", "cpu": [ "ia32" ], - "license": "MIT", "optional": true, "os": [ "linux" @@ -848,13 +714,12 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.23.1.tgz", - "integrity": "sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.1.tgz", + "integrity": "sha512-nGfornQj4dzcq5Vp835oM/o21UMlXzn79KobKlcs3Wz9smwiifknLy4xDCLUU0BWp7b/houtdrgUz7nOGnfIYg==", "cpu": [ "loong64" ], - "license": "MIT", "optional": true, "os": [ "linux" @@ -864,13 +729,12 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.23.1.tgz", - "integrity": "sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.1.tgz", + "integrity": "sha512-1osBbPEFYwIE5IVB/0g2X6i1qInZa1aIoj1TdL4AaAb55xIIgbg8Doq6a5BzYWgr+tEcDzYH67XVnTmUzL+nXg==", "cpu": [ "mips64el" ], - "license": "MIT", "optional": true, "os": [ "linux" @@ -880,13 +744,12 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.23.1.tgz", - "integrity": "sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.1.tgz", + "integrity": "sha512-/6VBJOwUf3TdTvJZ82qF3tbLuWsscd7/1w+D9LH0W/SqUgM5/JJD0lrJ1fVIfZsqB6RFmLCe0Xz3fmZc3WtyVg==", "cpu": [ "ppc64" ], - "license": "MIT", "optional": true, "os": [ "linux" @@ -896,13 +759,12 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.23.1.tgz", - "integrity": "sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.1.tgz", + "integrity": "sha512-nSut/Mx5gnilhcq2yIMLMe3Wl4FK5wx/o0QuuCLMtmJn+WeWYoEGDN1ipcN72g1WHsnIbxGXd4i/MF0gTcuAjQ==", "cpu": [ "riscv64" ], - "license": "MIT", "optional": true, "os": [ "linux" @@ -912,13 +774,12 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.23.1.tgz", - "integrity": "sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.1.tgz", + "integrity": "sha512-cEECeLlJNfT8kZHqLarDBQso9a27o2Zd2AQ8USAEoGtejOrCYHNtKP8XQhMDJMtthdF4GBmjR2au3x1udADQQQ==", "cpu": [ "s390x" ], - "license": "MIT", "optional": true, "os": [ "linux" @@ -928,13 +789,12 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.23.1.tgz", - "integrity": "sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.1.tgz", + "integrity": "sha512-xbfUhu/gnvSEg+EGovRc+kjBAkrvtk38RlerAzQxvMzlB4fXpCFCeUAYzJvrnhFtdeyVCDANSjJvOvGYoeKzFA==", "cpu": [ "x64" ], - "license": "MIT", "optional": true, "os": [ "linux" @@ -943,14 +803,28 @@ "node": ">=18" } }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.1.tgz", + "integrity": "sha512-O96poM2XGhLtpTh+s4+nP7YCCAfb4tJNRVZHfIE7dgmax+yMP2WgMd2OecBuaATHKTHsLWHQeuaxMRnCsH8+5g==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.23.1.tgz", - "integrity": "sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.1.tgz", + "integrity": "sha512-X53z6uXip6KFXBQ+Krbx25XHV/NCbzryM6ehOAeAil7X7oa4XIq+394PWGnwaSQ2WRA0KI6PUO6hTO5zeF5ijA==", "cpu": [ "x64" ], - "license": "MIT", "optional": true, "os": [ "netbsd" @@ -960,13 +834,12 @@ } }, "node_modules/@esbuild/openbsd-arm64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.23.1.tgz", - "integrity": "sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.1.tgz", + "integrity": "sha512-Na9T3szbXezdzM/Kfs3GcRQNjHzM6GzFBeU1/6IV/npKP5ORtp9zbQjvkDJ47s6BCgaAZnnnu/cY1x342+MvZg==", "cpu": [ "arm64" ], - "license": "MIT", "optional": true, "os": [ "openbsd" @@ -976,13 +849,12 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.23.1.tgz", - "integrity": "sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.1.tgz", + "integrity": "sha512-T3H78X2h1tszfRSf+txbt5aOp/e7TAz3ptVKu9Oyir3IAOFPGV6O9c2naym5TOriy1l0nNf6a4X5UXRZSGX/dw==", "cpu": [ "x64" ], - "license": "MIT", "optional": true, "os": [ "openbsd" @@ -992,13 +864,12 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.23.1.tgz", - "integrity": "sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.1.tgz", + "integrity": "sha512-2H3RUvcmULO7dIE5EWJH8eubZAI4xw54H1ilJnRNZdeo8dTADEZ21w6J22XBkXqGJbe0+wnNJtw3UXRoLJnFEg==", "cpu": [ "x64" ], - "license": "MIT", "optional": true, "os": [ "sunos" @@ -1008,13 +879,12 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.23.1.tgz", - "integrity": "sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.1.tgz", + "integrity": "sha512-GE7XvrdOzrb+yVKB9KsRMq+7a2U/K5Cf/8grVFRAGJmfADr/e/ODQ134RK2/eeHqYV5eQRFxb1hY7Nr15fv1NQ==", "cpu": [ "arm64" ], - "license": "MIT", "optional": true, "os": [ "win32" @@ -1024,13 +894,12 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.23.1.tgz", - "integrity": "sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.1.tgz", + "integrity": "sha512-uOxSJCIcavSiT6UnBhBzE8wy3n0hOkJsBOzy7HDAuTDE++1DJMRRVCPGisULScHL+a/ZwdXPpXD3IyFKjA7K8A==", "cpu": [ "ia32" ], - "license": "MIT", "optional": true, "os": [ "win32" @@ -1040,13 +909,12 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.23.1.tgz", - "integrity": "sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.1.tgz", + "integrity": "sha512-Y1EQdcfwMSeQN/ujR5VayLOJ1BHaK+ssyk0AEzPjC+t1lITgsnccPqFjb6V+LsTp/9Iov4ysfjxLaGJ9RPtkVg==", "cpu": [ "x64" ], - "license": "MIT", "optional": true, "os": [ "win32" @@ -1163,9 +1031,9 @@ } }, "node_modules/@freearhey/core": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/@freearhey/core/-/core-0.2.2.tgz", - "integrity": "sha512-8eikSh+alXohY/0Qv8lls+6BG738vOqxGuLvMjwBasbwuz8S/Abr7fUAH65dGjPAsB3HMaDhjK5c6kcVz5GrcA==", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@freearhey/core/-/core-0.6.0.tgz", + "integrity": "sha512-RuMQPQhduhWbPx8raB8Nlr8FLd65HLhQxpKSRvnrVzQWw2lDZ9pJ3ANkYOOdwKy7gDZ63WDhF3lwMTJwnwWiSw==", "dependencies": { "@types/fs-extra": "^11.0.2", "@types/lodash": "^4.14.198", @@ -1178,6 +1046,7 @@ "node-gzip": "^1.1.2", "normalize-url": "^6.1.0", "object-treeify": "^2.1.1", + "run-script-os": "^1.1.6", "signale": "^1.4.0" } }, @@ -1895,9 +1764,9 @@ } }, "node_modules/@octokit/core": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@octokit/core/-/core-4.2.0.tgz", - "integrity": "sha512-AgvDRUg3COpR82P7PBdGZF/NNqGmtMq2NiPqeSsDIeCfYFOZ9gddqWNQHnFdEUf+YwOj4aZYmJnlPp7OXmDIDg==", + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-4.2.4.tgz", + "integrity": "sha512-rYKilwgzQ7/imScn3M9/pFfUf4I1AZEH3KhyJmtPdE2zfaXAn2mFfUy4FbKewzc2We5y/LlKLj36fWJLKC2SIQ==", "dependencies": { "@octokit/auth-token": "^3.0.0", "@octokit/graphql": "^5.0.0", @@ -1925,9 +1794,9 @@ } }, "node_modules/@octokit/graphql": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-5.0.5.tgz", - "integrity": "sha512-Qwfvh3xdqKtIznjX9lz2D458r7dJPP8l6r4GQkIdWQouZwHQK0mVT88uwiU2bdTU2OtT1uOlKpRciUWldpG0yQ==", + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-5.0.6.tgz", + "integrity": "sha512-Fxyxdy/JH0MnIB5h+UQ3yCoh1FG4kWXfFKkpWqjZHw/p+Kc8Y44Hu/kCgNBT6nU1shNumEchmW/sUO1JuQnPcw==", "dependencies": { "@octokit/request": "^6.0.0", "@octokit/types": "^9.0.0", @@ -1943,11 +1812,12 @@ "integrity": "sha512-VRaeH8nCDtF5aXWnjPuEMIYf1itK/s3JYyJcWFJT8X9pSNnBtriDf7wlEWsGuhPLl4QIH4xM8fqTXDwJ3Mu6sw==" }, "node_modules/@octokit/plugin-paginate-rest": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-6.0.0.tgz", - "integrity": "sha512-Sq5VU1PfT6/JyuXPyt04KZNVsFOSBaYOAq2QRZUwzVlI10KFvcbUo8lR258AAQL1Et60b0WuVik+zOWKLuDZxw==", + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-6.1.2.tgz", + "integrity": "sha512-qhrmtQeHU/IivxucOV1bbI/xZyC/iOBhclokv7Sut5vnejAIAEXVcGQeRpQlU39E0WwK9lNvJHphHri/DB6lbQ==", "dependencies": { - "@octokit/types": "^9.0.0" + "@octokit/tsconfig": "^1.0.2", + "@octokit/types": "^9.2.3" }, "engines": { "node": ">= 14" @@ -1971,9 +1841,9 @@ } }, "node_modules/@octokit/request": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/@octokit/request/-/request-6.2.3.tgz", - "integrity": "sha512-TNAodj5yNzrrZ/VxP+H5HiYaZep0H3GU0O7PaF+fhDrt8FPrnkei9Aal/txsN/1P7V3CPiThG0tIvpPDYUsyAA==", + "version": "6.2.8", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-6.2.8.tgz", + "integrity": "sha512-ow4+pkVQ+6XVVsekSYBzJC0VTVvh/FCTUUgTsboGq+DTeWdyIFV8WSCdo0RIxk6wSkBTHqIK1mYuY7nOBXOchw==", "dependencies": { "@octokit/endpoint": "^7.0.0", "@octokit/request-error": "^3.0.0", @@ -1999,6 +1869,11 @@ "node": ">= 14" } }, + "node_modules/@octokit/tsconfig": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@octokit/tsconfig/-/tsconfig-1.0.2.tgz", + "integrity": "sha512-I0vDR0rdtP8p2lGMzvsJzbhdOWy405HcGovrspJ8RRibHnyRgggUSNO5AIox5LmqiwmatHKYsvj6VGFHkqS7lA==" + }, "node_modules/@octokit/types": { "version": "9.3.2", "resolved": "https://registry.npmjs.org/@octokit/types/-/types-9.3.2.tgz", @@ -3030,11 +2905,10 @@ } }, "node_modules/esbuild": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.23.1.tgz", - "integrity": "sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.1.tgz", + "integrity": "sha512-BGO5LtrGC7vxnqucAe/rmvKdJllfGaYWdyABvyMoXQlfYMb2bbRuReWR5tEGE//4LcNJj9XrkovTqNYRFZHAMQ==", "hasInstallScript": true, - "license": "MIT", "bin": { "esbuild": "bin/esbuild" }, @@ -3042,30 +2916,31 @@ "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.23.1", - "@esbuild/android-arm": "0.23.1", - "@esbuild/android-arm64": "0.23.1", - "@esbuild/android-x64": "0.23.1", - "@esbuild/darwin-arm64": "0.23.1", - "@esbuild/darwin-x64": "0.23.1", - "@esbuild/freebsd-arm64": "0.23.1", - "@esbuild/freebsd-x64": "0.23.1", - "@esbuild/linux-arm": "0.23.1", - "@esbuild/linux-arm64": "0.23.1", - "@esbuild/linux-ia32": "0.23.1", - "@esbuild/linux-loong64": "0.23.1", - "@esbuild/linux-mips64el": "0.23.1", - "@esbuild/linux-ppc64": "0.23.1", - "@esbuild/linux-riscv64": "0.23.1", - "@esbuild/linux-s390x": "0.23.1", - "@esbuild/linux-x64": "0.23.1", - "@esbuild/netbsd-x64": "0.23.1", - "@esbuild/openbsd-arm64": "0.23.1", - "@esbuild/openbsd-x64": "0.23.1", - "@esbuild/sunos-x64": "0.23.1", - "@esbuild/win32-arm64": "0.23.1", - "@esbuild/win32-ia32": "0.23.1", - "@esbuild/win32-x64": "0.23.1" + "@esbuild/aix-ppc64": "0.25.1", + "@esbuild/android-arm": "0.25.1", + "@esbuild/android-arm64": "0.25.1", + "@esbuild/android-x64": "0.25.1", + "@esbuild/darwin-arm64": "0.25.1", + "@esbuild/darwin-x64": "0.25.1", + "@esbuild/freebsd-arm64": "0.25.1", + "@esbuild/freebsd-x64": "0.25.1", + "@esbuild/linux-arm": "0.25.1", + "@esbuild/linux-arm64": "0.25.1", + "@esbuild/linux-ia32": "0.25.1", + "@esbuild/linux-loong64": "0.25.1", + "@esbuild/linux-mips64el": "0.25.1", + "@esbuild/linux-ppc64": "0.25.1", + "@esbuild/linux-riscv64": "0.25.1", + "@esbuild/linux-s390x": "0.25.1", + "@esbuild/linux-x64": "0.25.1", + "@esbuild/netbsd-arm64": "0.25.1", + "@esbuild/netbsd-x64": "0.25.1", + "@esbuild/openbsd-arm64": "0.25.1", + "@esbuild/openbsd-x64": "0.25.1", + "@esbuild/sunos-x64": "0.25.1", + "@esbuild/win32-arm64": "0.25.1", + "@esbuild/win32-ia32": "0.25.1", + "@esbuild/win32-x64": "0.25.1" } }, "node_modules/escalade": { @@ -5529,6 +5404,15 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/run-script-os": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/run-script-os/-/run-script-os-1.1.6.tgz", + "integrity": "sha512-ql6P2LzhBTTDfzKts+Qo4H94VUKpxKDFz6QxxwaUZN0mwvi7L3lpOI7BqPCq7lgDh3XLl0dpeXwfcVIitlrYrw==", + "bin": { + "run-os": "index.js", + "run-script-os": "index.js" + } + }, "node_modules/semver": { "version": "7.6.3", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", @@ -5800,14 +5684,6 @@ "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==" }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "engines": { - "node": ">=4" - } - }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -5930,12 +5806,11 @@ } }, "node_modules/tsx": { - "version": "4.19.2", - "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.19.2.tgz", - "integrity": "sha512-pOUl6Vo2LUq/bSa8S5q7b91cgNSjctn9ugq/+Mvow99qW6x/UZYwzxy/3NmqoT66eHYfCVvFvACC58UBPFf28g==", - "license": "MIT", + "version": "4.19.3", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.19.3.tgz", + "integrity": "sha512-4H8vUNGNjQ4V2EOoGw005+c+dGuPSnhpPBPHBtsZdGZBk/iJb4kguGlPWaZTZ3q5nMtFOEsY0nRDlh9PJyd6SQ==", "dependencies": { - "esbuild": "~0.23.0", + "esbuild": "~0.25.0", "get-tsconfig": "^4.7.5" }, "bin": { @@ -6168,58 +6043,13 @@ } }, "@babel/code-frame": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", - "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", + "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", "requires": { - "@babel/highlight": "^7.23.4", - "chalk": "^2.4.2" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" } }, "@babel/compat-data": { @@ -6363,14 +6193,14 @@ } }, "@babel/helper-string-parser": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", - "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==" + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", + "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==" }, "@babel/helper-validator-identifier": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", - "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==" + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==" }, "@babel/helper-validator-option": { "version": "7.22.15", @@ -6378,75 +6208,21 @@ "integrity": "sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA==" }, "@babel/helpers": { - "version": "7.23.1", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.1.tgz", - "integrity": "sha512-chNpneuK18yW5Oxsr+t553UZzzAs3aZnFm4bxhebsNTeshrC95yA7l5yl7GBAG+JG1rF0F7zzD2EixK9mWSDoA==", + "version": "7.26.10", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.10.tgz", + "integrity": "sha512-UPYc3SauzZ3JGgj87GgZ89JVdC5dj0AoetR5Bw6wj4niittNyFh6+eOGonYvJ1ao6B8lEa3Q3klS7ADZ53bc5g==", "requires": { - "@babel/template": "^7.22.15", - "@babel/traverse": "^7.23.0", - "@babel/types": "^7.23.0" - } - }, - "@babel/highlight": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", - "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", - "requires": { - "@babel/helper-validator-identifier": "^7.22.20", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } + "@babel/template": "^7.26.9", + "@babel/types": "^7.26.10" } }, "@babel/parser": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.5.tgz", - "integrity": "sha512-hOOqoiNXrmGdFbhgCzu6GiURxUgM27Xwd/aPuu8RfHEZPBzL1Z54okAHAQjXfcQNwvrlkAmAp4SlRTZ45vlthQ==" + "version": "7.26.10", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.10.tgz", + "integrity": "sha512-6aQR2zGE/QFi8JpDLjUZEPYOs7+mhKXm86VaKFiLP35JQwQb6bwUE+XbvkH0EptsYhbNBSUGaUBLKqxH1xSgsA==", + "requires": { + "@babel/types": "^7.26.10" + } }, "@babel/plugin-syntax-async-generators": { "version": "7.8.4", @@ -6561,13 +6337,13 @@ } }, "@babel/template": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", - "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.26.9.tgz", + "integrity": "sha512-qyRplbeIpNZhmzOysF/wFMuP9sctmh2cFzRAZOn1YapxBsE1i9bJIY586R/WBLfLcmcBlM8ROBiQURnnNy+zfA==", "requires": { - "@babel/code-frame": "^7.22.13", - "@babel/parser": "^7.22.15", - "@babel/types": "^7.22.15" + "@babel/code-frame": "^7.26.2", + "@babel/parser": "^7.26.9", + "@babel/types": "^7.26.9" } }, "@babel/traverse": { @@ -6595,13 +6371,12 @@ } }, "@babel/types": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.5.tgz", - "integrity": "sha512-ON5kSOJwVO6xXVRTvOI0eOnWe7VdUcIpsovGo9U/Br4Ie4UVFQTboO2cYnDhAGU6Fp+UxSiT+pMft0SMHfuq6w==", + "version": "7.26.10", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.10.tgz", + "integrity": "sha512-emqcG3vHrpxUKTrxcblR36dcrcoRDvKmnL/dCL6ZsHaShW80qxCAcNhzQZrpeM765VzEos+xOi4s+r4IXzTwdQ==", "requires": { - "@babel/helper-string-parser": "^7.23.4", - "@babel/helper-validator-identifier": "^7.22.20", - "to-fast-properties": "^2.0.0" + "@babel/helper-string-parser": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9" } }, "@bcoe/v8-coverage": { @@ -6633,147 +6408,153 @@ } }, "@esbuild/aix-ppc64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.23.1.tgz", - "integrity": "sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.1.tgz", + "integrity": "sha512-kfYGy8IdzTGy+z0vFGvExZtxkFlA4zAxgKEahG9KE1ScBjpQnFsNOX8KTU5ojNru5ed5CVoJYXFtoxaq5nFbjQ==", "optional": true }, "@esbuild/android-arm": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.23.1.tgz", - "integrity": "sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.1.tgz", + "integrity": "sha512-dp+MshLYux6j/JjdqVLnMglQlFu+MuVeNrmT5nk6q07wNhCdSnB7QZj+7G8VMUGh1q+vj2Bq8kRsuyA00I/k+Q==", "optional": true }, "@esbuild/android-arm64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.23.1.tgz", - "integrity": "sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.1.tgz", + "integrity": "sha512-50tM0zCJW5kGqgG7fQ7IHvQOcAn9TKiVRuQ/lN0xR+T2lzEFvAi1ZcS8DiksFcEpf1t/GYOeOfCAgDHFpkiSmA==", "optional": true }, "@esbuild/android-x64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.23.1.tgz", - "integrity": "sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.1.tgz", + "integrity": "sha512-GCj6WfUtNldqUzYkN/ITtlhwQqGWu9S45vUXs7EIYf+7rCiiqH9bCloatO9VhxsL0Pji+PF4Lz2XXCES+Q8hDw==", "optional": true }, "@esbuild/darwin-arm64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.23.1.tgz", - "integrity": "sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.1.tgz", + "integrity": "sha512-5hEZKPf+nQjYoSr/elb62U19/l1mZDdqidGfmFutVUjjUZrOazAtwK+Kr+3y0C/oeJfLlxo9fXb1w7L+P7E4FQ==", "optional": true }, "@esbuild/darwin-x64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.23.1.tgz", - "integrity": "sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.1.tgz", + "integrity": "sha512-hxVnwL2Dqs3fM1IWq8Iezh0cX7ZGdVhbTfnOy5uURtao5OIVCEyj9xIzemDi7sRvKsuSdtCAhMKarxqtlyVyfA==", "optional": true }, "@esbuild/freebsd-arm64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.23.1.tgz", - "integrity": "sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.1.tgz", + "integrity": "sha512-1MrCZs0fZa2g8E+FUo2ipw6jw5qqQiH+tERoS5fAfKnRx6NXH31tXBKI3VpmLijLH6yriMZsxJtaXUyFt/8Y4A==", "optional": true }, "@esbuild/freebsd-x64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.23.1.tgz", - "integrity": "sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.1.tgz", + "integrity": "sha512-0IZWLiTyz7nm0xuIs0q1Y3QWJC52R8aSXxe40VUxm6BB1RNmkODtW6LHvWRrGiICulcX7ZvyH6h5fqdLu4gkww==", "optional": true }, "@esbuild/linux-arm": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.23.1.tgz", - "integrity": "sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.1.tgz", + "integrity": "sha512-NdKOhS4u7JhDKw9G3cY6sWqFcnLITn6SqivVArbzIaf3cemShqfLGHYMx8Xlm/lBit3/5d7kXvriTUGa5YViuQ==", "optional": true }, "@esbuild/linux-arm64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.23.1.tgz", - "integrity": "sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.1.tgz", + "integrity": "sha512-jaN3dHi0/DDPelk0nLcXRm1q7DNJpjXy7yWaWvbfkPvI+7XNSc/lDOnCLN7gzsyzgu6qSAmgSvP9oXAhP973uQ==", "optional": true }, "@esbuild/linux-ia32": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.23.1.tgz", - "integrity": "sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.1.tgz", + "integrity": "sha512-OJykPaF4v8JidKNGz8c/q1lBO44sQNUQtq1KktJXdBLn1hPod5rE/Hko5ugKKZd+D2+o1a9MFGUEIUwO2YfgkQ==", "optional": true }, "@esbuild/linux-loong64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.23.1.tgz", - "integrity": "sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.1.tgz", + "integrity": "sha512-nGfornQj4dzcq5Vp835oM/o21UMlXzn79KobKlcs3Wz9smwiifknLy4xDCLUU0BWp7b/houtdrgUz7nOGnfIYg==", "optional": true }, "@esbuild/linux-mips64el": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.23.1.tgz", - "integrity": "sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.1.tgz", + "integrity": "sha512-1osBbPEFYwIE5IVB/0g2X6i1qInZa1aIoj1TdL4AaAb55xIIgbg8Doq6a5BzYWgr+tEcDzYH67XVnTmUzL+nXg==", "optional": true }, "@esbuild/linux-ppc64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.23.1.tgz", - "integrity": "sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.1.tgz", + "integrity": "sha512-/6VBJOwUf3TdTvJZ82qF3tbLuWsscd7/1w+D9LH0W/SqUgM5/JJD0lrJ1fVIfZsqB6RFmLCe0Xz3fmZc3WtyVg==", "optional": true }, "@esbuild/linux-riscv64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.23.1.tgz", - "integrity": "sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.1.tgz", + "integrity": "sha512-nSut/Mx5gnilhcq2yIMLMe3Wl4FK5wx/o0QuuCLMtmJn+WeWYoEGDN1ipcN72g1WHsnIbxGXd4i/MF0gTcuAjQ==", "optional": true }, "@esbuild/linux-s390x": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.23.1.tgz", - "integrity": "sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.1.tgz", + "integrity": "sha512-cEECeLlJNfT8kZHqLarDBQso9a27o2Zd2AQ8USAEoGtejOrCYHNtKP8XQhMDJMtthdF4GBmjR2au3x1udADQQQ==", "optional": true }, "@esbuild/linux-x64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.23.1.tgz", - "integrity": "sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.1.tgz", + "integrity": "sha512-xbfUhu/gnvSEg+EGovRc+kjBAkrvtk38RlerAzQxvMzlB4fXpCFCeUAYzJvrnhFtdeyVCDANSjJvOvGYoeKzFA==", + "optional": true + }, + "@esbuild/netbsd-arm64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.1.tgz", + "integrity": "sha512-O96poM2XGhLtpTh+s4+nP7YCCAfb4tJNRVZHfIE7dgmax+yMP2WgMd2OecBuaATHKTHsLWHQeuaxMRnCsH8+5g==", "optional": true }, "@esbuild/netbsd-x64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.23.1.tgz", - "integrity": "sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.1.tgz", + "integrity": "sha512-X53z6uXip6KFXBQ+Krbx25XHV/NCbzryM6ehOAeAil7X7oa4XIq+394PWGnwaSQ2WRA0KI6PUO6hTO5zeF5ijA==", "optional": true }, "@esbuild/openbsd-arm64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.23.1.tgz", - "integrity": "sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.1.tgz", + "integrity": "sha512-Na9T3szbXezdzM/Kfs3GcRQNjHzM6GzFBeU1/6IV/npKP5ORtp9zbQjvkDJ47s6BCgaAZnnnu/cY1x342+MvZg==", "optional": true }, "@esbuild/openbsd-x64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.23.1.tgz", - "integrity": "sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.1.tgz", + "integrity": "sha512-T3H78X2h1tszfRSf+txbt5aOp/e7TAz3ptVKu9Oyir3IAOFPGV6O9c2naym5TOriy1l0nNf6a4X5UXRZSGX/dw==", "optional": true }, "@esbuild/sunos-x64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.23.1.tgz", - "integrity": "sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.1.tgz", + "integrity": "sha512-2H3RUvcmULO7dIE5EWJH8eubZAI4xw54H1ilJnRNZdeo8dTADEZ21w6J22XBkXqGJbe0+wnNJtw3UXRoLJnFEg==", "optional": true }, "@esbuild/win32-arm64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.23.1.tgz", - "integrity": "sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.1.tgz", + "integrity": "sha512-GE7XvrdOzrb+yVKB9KsRMq+7a2U/K5Cf/8grVFRAGJmfADr/e/ODQ134RK2/eeHqYV5eQRFxb1hY7Nr15fv1NQ==", "optional": true }, "@esbuild/win32-ia32": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.23.1.tgz", - "integrity": "sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.1.tgz", + "integrity": "sha512-uOxSJCIcavSiT6UnBhBzE8wy3n0hOkJsBOzy7HDAuTDE++1DJMRRVCPGisULScHL+a/ZwdXPpXD3IyFKjA7K8A==", "optional": true }, "@esbuild/win32-x64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.23.1.tgz", - "integrity": "sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.1.tgz", + "integrity": "sha512-Y1EQdcfwMSeQN/ujR5VayLOJ1BHaK+ssyk0AEzPjC+t1lITgsnccPqFjb6V+LsTp/9Iov4ysfjxLaGJ9RPtkVg==", "optional": true }, "@eslint-community/eslint-utils": { @@ -6850,9 +6631,9 @@ } }, "@freearhey/core": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/@freearhey/core/-/core-0.2.2.tgz", - "integrity": "sha512-8eikSh+alXohY/0Qv8lls+6BG738vOqxGuLvMjwBasbwuz8S/Abr7fUAH65dGjPAsB3HMaDhjK5c6kcVz5GrcA==", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@freearhey/core/-/core-0.6.0.tgz", + "integrity": "sha512-RuMQPQhduhWbPx8raB8Nlr8FLd65HLhQxpKSRvnrVzQWw2lDZ9pJ3ANkYOOdwKy7gDZ63WDhF3lwMTJwnwWiSw==", "requires": { "@types/fs-extra": "^11.0.2", "@types/lodash": "^4.14.198", @@ -6865,6 +6646,7 @@ "node-gzip": "^1.1.2", "normalize-url": "^6.1.0", "object-treeify": "^2.1.1", + "run-script-os": "^1.1.6", "signale": "^1.4.0" }, "dependencies": { @@ -7400,9 +7182,9 @@ } }, "@octokit/core": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@octokit/core/-/core-4.2.0.tgz", - "integrity": "sha512-AgvDRUg3COpR82P7PBdGZF/NNqGmtMq2NiPqeSsDIeCfYFOZ9gddqWNQHnFdEUf+YwOj4aZYmJnlPp7OXmDIDg==", + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-4.2.4.tgz", + "integrity": "sha512-rYKilwgzQ7/imScn3M9/pFfUf4I1AZEH3KhyJmtPdE2zfaXAn2mFfUy4FbKewzc2We5y/LlKLj36fWJLKC2SIQ==", "requires": { "@octokit/auth-token": "^3.0.0", "@octokit/graphql": "^5.0.0", @@ -7424,9 +7206,9 @@ } }, "@octokit/graphql": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-5.0.5.tgz", - "integrity": "sha512-Qwfvh3xdqKtIznjX9lz2D458r7dJPP8l6r4GQkIdWQouZwHQK0mVT88uwiU2bdTU2OtT1uOlKpRciUWldpG0yQ==", + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-5.0.6.tgz", + "integrity": "sha512-Fxyxdy/JH0MnIB5h+UQ3yCoh1FG4kWXfFKkpWqjZHw/p+Kc8Y44Hu/kCgNBT6nU1shNumEchmW/sUO1JuQnPcw==", "requires": { "@octokit/request": "^6.0.0", "@octokit/types": "^9.0.0", @@ -7439,11 +7221,12 @@ "integrity": "sha512-VRaeH8nCDtF5aXWnjPuEMIYf1itK/s3JYyJcWFJT8X9pSNnBtriDf7wlEWsGuhPLl4QIH4xM8fqTXDwJ3Mu6sw==" }, "@octokit/plugin-paginate-rest": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-6.0.0.tgz", - "integrity": "sha512-Sq5VU1PfT6/JyuXPyt04KZNVsFOSBaYOAq2QRZUwzVlI10KFvcbUo8lR258AAQL1Et60b0WuVik+zOWKLuDZxw==", + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-6.1.2.tgz", + "integrity": "sha512-qhrmtQeHU/IivxucOV1bbI/xZyC/iOBhclokv7Sut5vnejAIAEXVcGQeRpQlU39E0WwK9lNvJHphHri/DB6lbQ==", "requires": { - "@octokit/types": "^9.0.0" + "@octokit/tsconfig": "^1.0.2", + "@octokit/types": "^9.2.3" } }, "@octokit/plugin-rest-endpoint-methods": { @@ -7455,9 +7238,9 @@ } }, "@octokit/request": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/@octokit/request/-/request-6.2.3.tgz", - "integrity": "sha512-TNAodj5yNzrrZ/VxP+H5HiYaZep0H3GU0O7PaF+fhDrt8FPrnkei9Aal/txsN/1P7V3CPiThG0tIvpPDYUsyAA==", + "version": "6.2.8", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-6.2.8.tgz", + "integrity": "sha512-ow4+pkVQ+6XVVsekSYBzJC0VTVvh/FCTUUgTsboGq+DTeWdyIFV8WSCdo0RIxk6wSkBTHqIK1mYuY7nOBXOchw==", "requires": { "@octokit/endpoint": "^7.0.0", "@octokit/request-error": "^3.0.0", @@ -7477,6 +7260,11 @@ "once": "^1.4.0" } }, + "@octokit/tsconfig": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@octokit/tsconfig/-/tsconfig-1.0.2.tgz", + "integrity": "sha512-I0vDR0rdtP8p2lGMzvsJzbhdOWy405HcGovrspJ8RRibHnyRgggUSNO5AIox5LmqiwmatHKYsvj6VGFHkqS7lA==" + }, "@octokit/types": { "version": "9.3.2", "resolved": "https://registry.npmjs.org/@octokit/types/-/types-9.3.2.tgz", @@ -8224,34 +8012,35 @@ } }, "esbuild": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.23.1.tgz", - "integrity": "sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.1.tgz", + "integrity": "sha512-BGO5LtrGC7vxnqucAe/rmvKdJllfGaYWdyABvyMoXQlfYMb2bbRuReWR5tEGE//4LcNJj9XrkovTqNYRFZHAMQ==", "requires": { - "@esbuild/aix-ppc64": "0.23.1", - "@esbuild/android-arm": "0.23.1", - "@esbuild/android-arm64": "0.23.1", - "@esbuild/android-x64": "0.23.1", - "@esbuild/darwin-arm64": "0.23.1", - "@esbuild/darwin-x64": "0.23.1", - "@esbuild/freebsd-arm64": "0.23.1", - "@esbuild/freebsd-x64": "0.23.1", - "@esbuild/linux-arm": "0.23.1", - "@esbuild/linux-arm64": "0.23.1", - "@esbuild/linux-ia32": "0.23.1", - "@esbuild/linux-loong64": "0.23.1", - "@esbuild/linux-mips64el": "0.23.1", - "@esbuild/linux-ppc64": "0.23.1", - "@esbuild/linux-riscv64": "0.23.1", - "@esbuild/linux-s390x": "0.23.1", - "@esbuild/linux-x64": "0.23.1", - "@esbuild/netbsd-x64": "0.23.1", - "@esbuild/openbsd-arm64": "0.23.1", - "@esbuild/openbsd-x64": "0.23.1", - "@esbuild/sunos-x64": "0.23.1", - "@esbuild/win32-arm64": "0.23.1", - "@esbuild/win32-ia32": "0.23.1", - "@esbuild/win32-x64": "0.23.1" + "@esbuild/aix-ppc64": "0.25.1", + "@esbuild/android-arm": "0.25.1", + "@esbuild/android-arm64": "0.25.1", + "@esbuild/android-x64": "0.25.1", + "@esbuild/darwin-arm64": "0.25.1", + "@esbuild/darwin-x64": "0.25.1", + "@esbuild/freebsd-arm64": "0.25.1", + "@esbuild/freebsd-x64": "0.25.1", + "@esbuild/linux-arm": "0.25.1", + "@esbuild/linux-arm64": "0.25.1", + "@esbuild/linux-ia32": "0.25.1", + "@esbuild/linux-loong64": "0.25.1", + "@esbuild/linux-mips64el": "0.25.1", + "@esbuild/linux-ppc64": "0.25.1", + "@esbuild/linux-riscv64": "0.25.1", + "@esbuild/linux-s390x": "0.25.1", + "@esbuild/linux-x64": "0.25.1", + "@esbuild/netbsd-arm64": "0.25.1", + "@esbuild/netbsd-x64": "0.25.1", + "@esbuild/openbsd-arm64": "0.25.1", + "@esbuild/openbsd-x64": "0.25.1", + "@esbuild/sunos-x64": "0.25.1", + "@esbuild/win32-arm64": "0.25.1", + "@esbuild/win32-ia32": "0.25.1", + "@esbuild/win32-x64": "0.25.1" } }, "escalade": { @@ -9992,6 +9781,11 @@ "queue-microtask": "^1.2.2" } }, + "run-script-os": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/run-script-os/-/run-script-os-1.1.6.tgz", + "integrity": "sha512-ql6P2LzhBTTDfzKts+Qo4H94VUKpxKDFz6QxxwaUZN0mwvi7L3lpOI7BqPCq7lgDh3XLl0dpeXwfcVIitlrYrw==" + }, "semver": { "version": "7.6.3", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", @@ -10193,11 +9987,6 @@ "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==" }, - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==" - }, "to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -10262,11 +10051,11 @@ } }, "tsx": { - "version": "4.19.2", - "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.19.2.tgz", - "integrity": "sha512-pOUl6Vo2LUq/bSa8S5q7b91cgNSjctn9ugq/+Mvow99qW6x/UZYwzxy/3NmqoT66eHYfCVvFvACC58UBPFf28g==", + "version": "4.19.3", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.19.3.tgz", + "integrity": "sha512-4H8vUNGNjQ4V2EOoGw005+c+dGuPSnhpPBPHBtsZdGZBk/iJb4kguGlPWaZTZ3q5nMtFOEsY0nRDlh9PJyd6SQ==", "requires": { - "esbuild": "~0.23.0", + "esbuild": "~0.25.0", "fsevents": "~2.3.3", "get-tsconfig": "^4.7.5" } diff --git a/package.json b/package.json index 593ea260..418edd45 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ }, "dependencies": { "@eslint/js": "^9.16.0", - "@freearhey/core": "^0.2.2", + "@freearhey/core": "^0.6.0", "@joi/date": "^2.1.0", "@json2csv/formatters": "^7.0.3", "@json2csv/node": "^7.0.3", diff --git a/scripts/core/csvParser.ts b/scripts/core/csvParser.ts index 15451a06..27aa70cc 100644 --- a/scripts/core/csvParser.ts +++ b/scripts/core/csvParser.ts @@ -21,7 +21,10 @@ const opts = { replaced_by: nullable, website: nullable, logo: nullable, - countries: listParser + countries: listParser, + timezones: listParser, + is_main: boolParser, + video_format: nullable } } diff --git a/scripts/core/idCreator.ts b/scripts/core/idCreator.ts deleted file mode 100644 index e547f83e..00000000 --- a/scripts/core/idCreator.ts +++ /dev/null @@ -1,17 +0,0 @@ -export class IDCreator { - create(name: string, country: string): string { - const slug = normalize(name) - const code = country.toLowerCase() - - return `${slug}.${code}` - } -} - -function normalize(name: string) { - return name - .replace(/^@/gi, 'At') - .replace(/^&/i, 'And') - .replace(/\+/gi, 'Plus') - .replace(/\s-(\d)/gi, ' Minus$1') - .replace(/[^a-z\d]+/gi, '') -} diff --git a/scripts/core/index.ts b/scripts/core/index.ts index 387d00ea..11090373 100644 --- a/scripts/core/index.ts +++ b/scripts/core/index.ts @@ -2,6 +2,5 @@ export * from './csv' export * from './issueParser' export * from './issueLoader' export * from './csvParser' -export * from './idCreator' export * from './issueData' export * from './issue' diff --git a/scripts/core/issueLoader.ts b/scripts/core/issueLoader.ts index 8d588f12..a514fea0 100644 --- a/scripts/core/issueLoader.ts +++ b/scripts/core/issueLoader.ts @@ -9,32 +9,15 @@ const CustomOctokit = Octokit.plugin(paginateRest, restEndpointMethods) const octokit = new CustomOctokit() export class IssueLoader { - async load({ labels }: { labels: string[] | string }) { - labels = Array.isArray(labels) ? labels.join(',') : labels + async load(props?: { labels: string[] | string }) { + let labels = '' + if (props && props.labels) { + labels = Array.isArray(props.labels) ? props.labels.join(',') : props.labels + } + let issues: object[] = [] if (TESTING) { - switch (labels) { - case 'channels:add,approved': - issues = (await import('../../tests/__data__/input/issues/channels_add_approved.js')) - .default - break - case 'channels:edit,approved': - issues = (await import('../../tests/__data__/input/issues/channels_edit_approved.js')) - .default - break - case 'channels:remove,approved': - issues = (await import('../../tests/__data__/input/issues/channels_remove_approved.js')) - .default - break - case 'blocklist:add,approved': - issues = (await import('../../tests/__data__/input/issues/blocklist_add_approved.js')) - .default - break - case 'blocklist:remove,approved': - issues = (await import('../../tests/__data__/input/issues/blocklist_remove_approved.js')) - .default - break - } + issues = (await import('../../tests/__data__/input/update/issues.js')).default } else { issues = await octokit.paginate(octokit.rest.issues.listForRepo, { owner: OWNER, diff --git a/scripts/core/issueParser.ts b/scripts/core/issueParser.ts index ac74649c..b051b5a1 100644 --- a/scripts/core/issueParser.ts +++ b/scripts/core/issueParser.ts @@ -3,40 +3,30 @@ import { IssueData, Issue } from '../core' const FIELDS = new Dictionary({ 'Channel ID': 'channel_id', - 'Channel ID (required)': 'channel_id', - 'Channel ID (optional)': 'channel_id', - 'Channel Name': 'name', + 'Channel Name': 'channel_name', + 'Feed Name': 'feed_name', + 'Feed ID': 'feed_id', + 'Main Feed': 'is_main', 'Alternative Names': 'alt_names', - 'Alternative Names (optional)': 'alt_names', Network: 'network', - 'Network (optional)': 'network', Owners: 'owners', - 'Owners (optional)': 'owners', Country: 'country', Subdivision: 'subdivision', - 'Subdivision (optional)': 'subdivision', City: 'city', - 'City (optional)': 'city', 'Broadcast Area': 'broadcast_area', + Timezones: 'timezones', + Format: 'video_format', Languages: 'languages', Categories: 'categories', - 'Categories (optional)': 'categories', NSFW: 'is_nsfw', Launched: 'launched', - 'Launched (optional)': 'launched', Closed: 'closed', - 'Closed (optional)': 'closed', 'Replaced By': 'replaced_by', - 'Replaced By (optional)': 'replaced_by', Website: 'website', - 'Website (optional)': 'website', Logo: 'logo', Reason: 'reason', Notes: 'notes', - 'Notes (optional)': 'notes', - Reference: 'ref', - 'Reference (optional)': 'ref', - 'Reference (required)': 'ref' + Reference: 'ref' }) export class IssueParser { @@ -46,7 +36,7 @@ export class IssueParser { const data = new Dictionary() fields.forEach((field: string) => { let [_label, , _value] = field.split(/\r?\n/) - _label = _label ? _label.trim() : '' + _label = _label ? _label.replace(/ \(optional\)| \(required\)/, '').trim() : '' _value = _value ? _value.trim() : '' if (!_label || !_value) return data diff --git a/scripts/db/update.ts b/scripts/db/update.ts index d8234736..4f632348 100644 --- a/scripts/db/update.ts +++ b/scripts/db/update.ts @@ -1,36 +1,49 @@ -import { CSV, IssueLoader, CSVParser, IDCreator, Issue, IssueData } from '../core' -import { Channel, Blocked } from '../models' +import { CSV, IssueLoader, CSVParser, Issue, IssueData } from '../core' +import { Channel, Blocked, Feed } from '../models' import { DATA_DIR } from '../constants' import { Storage, Collection } from '@freearhey/core' +import { createChannelId, createFeedId } from '../utils' let blocklist = new Collection() let channels = new Collection() +let feeds = new Collection() +let issues = new Collection() const processedIssues = new Collection() async function main() { - const idCreator = new IDCreator() const dataStorage = new Storage(DATA_DIR) const parser = new CSVParser() - - const _channels = await dataStorage.load('channels.csv') - channels = (await parser.parse(_channels)).map(data => new Channel(data)) - - const _blocklist = await dataStorage.load('blocklist.csv') - blocklist = (await parser.parse(_blocklist)).map(data => new Blocked(data)) - const loader = new IssueLoader() - await removeChannels({ loader }) - await editChannels({ loader, idCreator }) - await addChannels({ loader, idCreator }) - await blockChannels({ loader }) - await unblockChannels({ loader }) + issues = await loader.load() - channels = sortBy(channels, 'id') + const channelsCSV = await dataStorage.load('channels.csv') + channels = (await parser.parse(channelsCSV)).map(data => new Channel(data)) + + const feedsCSV = await dataStorage.load('feeds.csv') + feeds = (await parser.parse(feedsCSV)).map(data => new Feed(data)) + + const blocklistCSV = await dataStorage.load('blocklist.csv') + blocklist = (await parser.parse(blocklistCSV)).map(data => new Blocked(data)) + + await removeFeeds() + await removeChannels() + await editFeeds() + await editChannels() + await addFeeds() + await addChannels() + await blockChannels() + await unblockChannels() + + channels = channels.sortBy(channel => channel.id.toLowerCase()) const channelsOutput = new CSV({ items: channels }).toString() await dataStorage.save('channels.csv', channelsOutput) - blocklist = sortBy(blocklist, 'channel') + feeds = feeds.sortBy(feed => `${feed.channel}@${feed.id}`.toLowerCase()) + const feedsOutput = new CSV({ items: feeds }).toString() + await dataStorage.save('feeds.csv', feedsOutput) + + blocklist = blocklist.sortBy(blocked => blocked.channel.toLowerCase()) const blocklistOutput = new CSV({ items: blocklist }).toString() await dataStorage.save('blocklist.csv', blocklistOutput) @@ -40,21 +53,139 @@ async function main() { main() -function sortBy(channels: Collection, key: string) { - const items = channels.all().sort((a, b) => { - const normA = a[key].toLowerCase() - const normB = b[key].toLowerCase() - if (normA < normB) return -1 - if (normA > normB) return 1 - return 0 - }) +async function removeFeeds() { + const requests = issues.filter( + issue => issue.labels.includes('feeds:remove') && issue.labels.includes('approved') + ) - return new Collection(items) + requests.forEach((issue: Issue) => { + if (issue.data.missing('channel_id') || issue.data.missing('feed_id')) return + + const found = feeds.first( + (feed: Feed) => + feed.channel === issue.data.getString('channel_id') && + feed.id === issue.data.getString('feed_id') + ) + if (!found) return + + feeds.remove((feed: Feed) => feed.channel === found.channel && feed.id === found.id) + + onFeedRemoval(found.channel, found.id) + + processedIssues.push(issue) + }) } -async function removeChannels({ loader }: { loader: IssueLoader }) { - const issues = await loader.load({ labels: ['channels:remove,approved'] }) - issues.forEach((issue: Issue) => { +async function editFeeds() { + const requests = issues.filter( + issue => issue.labels.includes('feeds:edit') && issue.labels.includes('approved') + ) + + requests.forEach((issue: Issue) => { + const data: IssueData = issue.data + if (data.missing('channel_id') || data.missing('feed_id')) return + + const found: Feed = feeds.first( + (feed: Feed) => + feed.channel === data.getString('channel_id') && feed.id === data.getString('feed_id') + ) + if (!found) return + + let channelId: string | undefined = found.channel + let feedId: string | undefined = found.id + if (data.has('feed_name')) { + const name = data.getString('feed_name') || found.name + if (name) { + feedId = createFeedId(name) + if (feedId) onFeedIdChange(found.channel, found.id, feedId) + } + } + + if (data.has('is_main')) { + const isMain = data.getBoolean('is_main') || false + if (isMain) onFeedNewMain(channelId, feedId) + } + + if (!feedId || !channelId) return + + const updated = new Feed({ + channel: channelId, + id: feedId, + name: data.getString('feed_name'), + is_main: data.getBoolean('is_main'), + broadcast_area: data.getArray('broadcast_area'), + timezones: data.getArray('timezones'), + languages: data.getArray('languages'), + video_format: data.getString('video_format'), + launched: data.getString('launched'), + closed: data.getString('closed'), + replaced_by: data.getString('replaced_by') + }) + + found.merge(updated) + + processedIssues.push(issue) + }) +} + +async function addFeeds() { + const requests = issues.filter( + issue => issue.labels.includes('feeds:add') && issue.labels.includes('approved') + ) + + requests.forEach((issue: Issue) => { + const data: IssueData = issue.data + + if ( + data.missing('channel_id') || + data.missing('feed_name') || + data.missing('is_main') || + data.missing('broadcast_area') || + data.missing('timezones') || + data.missing('languages') || + data.missing('video_format') + ) + return + + const channelId = data.getString('channel_id') + const feedName = data.getString('feed_name') || 'SD' + const feedId = createFeedId(feedName) + if (!channelId || !feedId) return + + const found: Feed = feeds.first( + (feed: Feed) => feed.channel === channelId && feed.id === feedId + ) + if (found) return + + const isMain = data.getBoolean('is_main') || false + if (isMain) onFeedNewMain(channelId, feedId) + + feeds.push( + new Feed({ + channel: channelId, + id: feedId, + name: feedName, + is_main: data.getBoolean('is_main'), + broadcast_area: data.getArray('broadcast_area'), + timezones: data.getArray('timezones'), + languages: data.getArray('languages'), + video_format: data.getString('video_format'), + launched: data.getString('launched'), + closed: data.getString('closed'), + replaced_by: data.getString('replaced_by') + }) + ) + + processedIssues.push(issue) + }) +} + +async function removeChannels() { + const requests = issues.filter( + issue => issue.labels.includes('channels:remove') && issue.labels.includes('approved') + ) + + requests.forEach((issue: Issue) => { if (issue.data.missing('channel_id')) return const found = channels.first( @@ -64,13 +195,18 @@ async function removeChannels({ loader }: { loader: IssueLoader }) { channels.remove((channel: Channel) => channel.id === found.id) + onChannelRemoval(found.id) + processedIssues.push(issue) }) } -async function editChannels({ loader, idCreator }: { loader: IssueLoader; idCreator: IDCreator }) { - const issues = await loader.load({ labels: ['channels:edit,approved'] }) - issues.forEach((issue: Issue) => { +async function editChannels() { + const requests = issues.filter( + issue => issue.labels.includes('channels:edit') && issue.labels.includes('approved') + ) + + requests.forEach((issue: Issue) => { const data: IssueData = issue.data if (data.missing('channel_id')) return @@ -79,20 +215,21 @@ async function editChannels({ loader, idCreator }: { loader: IssueLoader; idCrea ) if (!found) return - let channelId = found.id - if (data.has('name') || data.has('country')) { - const name = data.getString('name') || found.name + let channelId: string | undefined = found.id + if (data.has('channel_name') || data.has('country')) { + const name = data.getString('channel_name') || found.name const country = data.getString('country') || found.country if (name && country) { - channelId = idCreator.create(name, country) - updateBlocklistId(found.id, channelId) - updateChannelReplacedBy(found.id, channelId) + channelId = createChannelId(name, country) + if (channelId) onChannelIdChange(found.id, channelId) } } + if (!channelId) return + const updated = new Channel({ id: channelId, - name: data.getString('name'), + name: data.getString('channel_name'), alt_names: data.getArray('alt_names'), network: data.getString('network'), owners: data.getArray('owners'), @@ -116,16 +253,29 @@ async function editChannels({ loader, idCreator }: { loader: IssueLoader; idCrea }) } -async function addChannels({ loader, idCreator }: { loader: IssueLoader; idCreator: IDCreator }) { - const issues = await loader.load({ labels: ['channels:add,approved'] }) - issues.forEach((issue: Issue) => { +async function addChannels() { + const requests = issues.filter( + issue => issue.labels.includes('channels:add') && issue.labels.includes('approved') + ) + + requests.forEach((issue: Issue) => { const data: IssueData = issue.data - const name = data.getString('name') - const country = data.getString('country') - if (!name || !country) return + if ( + data.missing('channel_name') || + data.missing('country') || + data.missing('is_nsfw') || + data.missing('logo') || + data.missing('feed_name') || + data.missing('broadcast_area') || + data.missing('timezones') || + data.missing('languages') || + data.missing('video_format') + ) + return - const channelId = idCreator.create(name, country) + const channelId = createChannelId(data.getString('channel_name'), data.getString('country')) + if (!channelId) return const found: Channel = channels.first((channel: Channel) => channel.id === channelId) if (found) return @@ -133,7 +283,7 @@ async function addChannels({ loader, idCreator }: { loader: IssueLoader; idCreat channels.push( new Channel({ id: channelId, - name: data.getString('name'), + name: data.getString('channel_name'), alt_names: data.getArray('alt_names'), network: data.getString('network'), owners: data.getArray('owners'), @@ -152,13 +302,34 @@ async function addChannels({ loader, idCreator }: { loader: IssueLoader; idCreat }) ) + const feedName = data.getString('feed_name') || 'SD' + + feeds.push( + new Feed({ + channel: channelId, + id: createFeedId(feedName), + name: feedName, + is_main: true, + broadcast_area: data.getArray('broadcast_area'), + timezones: data.getArray('timezones'), + languages: data.getArray('languages'), + video_format: data.getString('video_format'), + launched: data.getString('launched'), + closed: data.getString('closed'), + replaced_by: data.getString('replaced_by') + }) + ) + processedIssues.push(issue) }) } -async function unblockChannels({ loader }: { loader: IssueLoader }) { - const issues = await loader.load({ labels: ['blocklist:remove,approved'] }) - issues.forEach((issue: Issue) => { +async function unblockChannels() { + const requests = issues.filter( + issue => issue.labels.includes('blocklist:remove') && issue.labels.includes('approved') + ) + + requests.forEach((issue: Issue) => { const data = issue.data if (data.missing('channel_id')) return @@ -173,9 +344,12 @@ async function unblockChannels({ loader }: { loader: IssueLoader }) { }) } -async function blockChannels({ loader }: { loader: IssueLoader }) { - const issues = await loader.load({ labels: ['blocklist:add,approved'] }) - issues.forEach((issue: Issue) => { +async function blockChannels() { + const requests = issues.filter( + issue => issue.labels.includes('blocklist:add') && issue.labels.includes('approved') + ) + + requests.forEach((issue: Issue) => { const data = issue.data if (data.missing('channel_id')) return @@ -201,22 +375,77 @@ async function blockChannels({ loader }: { loader: IssueLoader }) { }) } -function updateBlocklistId(oldId: string, newId: string) { - const filtered: Collection = blocklist.filter((blocked: Blocked) => blocked.channel === oldId) - if (filtered.isEmpty()) return +function onFeedIdChange(channelId: string, feedId: string, newFeedId: string) { + channels.forEach((channel: Channel) => { + if (channel.replaced_by && channel.replaced_by === `${channelId}@${feedId}`) { + channel.replaced_by = `${channelId}@${newFeedId}` + } + }) - filtered.forEach(item => { - item.channel = newId + feeds.forEach((feed: Feed) => { + if (feed.replaced_by && feed.replaced_by === `${channelId}@${feedId}`) { + feed.replaced_by = `${channelId}@${newFeedId}` + } }) } -function updateChannelReplacedBy(channelId: string, newReplacedBy: string) { - const filtered: Collection = channels.filter( - (channel: Channel) => channel.replaced_by === channelId - ) - if (filtered.isEmpty()) return - - filtered.forEach(item => { - item.replaced_by = newReplacedBy +function onFeedNewMain(channelId: string, feedId: string) { + feeds.forEach((feed: Feed) => { + if (feed.channel === channelId && feed.id !== feedId && feed.is_main === true) { + feed.is_main = false + } + }) +} + +function onFeedRemoval(channelId: string, feedId: string) { + channels.forEach((channel: Channel) => { + if (channel.replaced_by && channel.replaced_by === `${channelId}@${feedId}`) { + channel.replaced_by = '' + } + }) + + feeds.forEach((feed: Feed) => { + if (feed.replaced_by && feed.replaced_by === `${channelId}@${feedId}`) { + feed.replaced_by = '' + } + }) +} + +function onChannelIdChange(channelId: string, newChannelId: string) { + channels.forEach((channel: Channel) => { + if (channel.replaced_by && channel.replaced_by.includes(channelId)) { + channel.replaced_by = channel.replaced_by.replace(channelId, newChannelId) + } + }) + + feeds.forEach((feed: Feed) => { + if (feed.channel === channelId) { + feed.channel = newChannelId + } + + if (feed.replaced_by && feed.replaced_by.includes(channelId)) { + feed.replaced_by = feed.replaced_by.replace(channelId, newChannelId) + } + }) + + blocklist.forEach((blocked: Blocked) => { + if (blocked.channel === channelId) { + blocked.channel = newChannelId + } + }) +} + +function onChannelRemoval(channelId: string) { + channels.forEach((channel: Channel) => { + if (channel.replaced_by && channel.replaced_by.includes(channelId)) { + channel.replaced_by = '' + } + }) + + feeds.remove((feed: Feed) => feed.channel === channelId) + feeds.forEach((feed: Feed) => { + if (feed.replaced_by && feed.replaced_by.includes(channelId)) { + feed.replaced_by = '' + } }) } diff --git a/scripts/db/validate.ts b/scripts/db/validate.ts index afb61ab8..78b2e87b 100644 --- a/scripts/db/validate.ts +++ b/scripts/db/validate.ts @@ -3,8 +3,9 @@ import { DATA_DIR } from '../constants' import schemesData from '../schemes' import { program } from 'commander' import Joi from 'joi' -import { CSVParser, IDCreator } from '../core' +import { CSVParser } from '../core' import chalk from 'chalk' +import { createChannelId } from '../utils' program.argument('[filepath]', 'Path to file to validate').parse(process.argv) @@ -42,11 +43,15 @@ async function main() { let grouped switch (filename) { + case 'feeds': + grouped = data.keyBy(item => item.channel + item.id) + break case 'blocklist': grouped = data.keyBy(item => item.channel + item.ref) break case 'categories': case 'channels': + case 'timezones': grouped = data.keyBy(item => item.id) break default: @@ -74,15 +79,13 @@ async function main() { for (const [i, row] of rowsCopy.entries()) { fileErrors = fileErrors.concat(validateChannelId(row, i)) fileErrors = fileErrors.concat(validateChannelBroadcastArea(row, i)) + fileErrors = fileErrors.concat(validateReplacedBy(row, i)) fileErrors = fileErrors.concat( checkValue(i, row, 'id', 'subdivision', buffer.get('subdivisions')) ) fileErrors = fileErrors.concat( checkValue(i, row, 'id', 'categories', buffer.get('categories')) ) - fileErrors = fileErrors.concat( - checkValue(i, row, 'id', 'replaced_by', buffer.get('channels')) - ) fileErrors = fileErrors.concat( checkValue(i, row, 'id', 'languages', buffer.get('languages')) ) @@ -91,6 +94,15 @@ async function main() { ) } break + case 'feeds': + fileErrors = fileErrors.concat(findDuplicatesBy(rowsCopy, ['channel', 'id'])) + fileErrors = fileErrors.concat(validateMainFeeds(rowsCopy)) + for (const [i, row] of rowsCopy.entries()) { + fileErrors = fileErrors.concat(validateChannel(row.channel, i)) + fileErrors = fileErrors.concat(validateTimezones(row, i)) + fileErrors = fileErrors.concat(validateReplacedBy(row, i)) + } + break case 'blocklist': fileErrors = fileErrors.concat(findDuplicatesBy(rowsCopy, ['channel', 'ref'])) for (const [i, row] of rowsCopy.entries()) { @@ -182,6 +194,30 @@ function checkValue( return errors } +function validateReplacedBy(row: { [key: string]: string }, i: number) { + const errors = new Collection() + + if (!row.replaced_by) return errors + + const channels = buffer.get('channels') + const feeds = buffer.get('feeds') + const [channelId, feedId] = row.replaced_by.split('@') + + if (channels.missing(channelId)) { + errors.push({ + line: i + 2, + message: `"${row.id}" has an invalid replaced_by "${row.replaced_by}"` + }) + } else if (feedId && feeds.missing(channelId + feedId)) { + errors.push({ + line: i + 2, + message: `"${row.id}" has an invalid replaced_by "${row.replaced_by}"` + }) + } + + return errors +} + function validateChannel(channelId: string, i: number) { const errors = new Collection() const channels = buffer.get('channels') @@ -201,7 +237,7 @@ function findDuplicatesBy(rows: { [key: string]: string }[], keys: string[]) { const buffer = new Dictionary() rows.forEach((row, i) => { - const normId = keys.map(key => row[key].toLowerCase()).join() + const normId = keys.map(key => row[key].toString().toLowerCase()).join() if (buffer.has(normId)) { const fieldsList = keys.map(key => `${key} "${row[key]}"`).join(' and ') errors.push({ @@ -216,10 +252,31 @@ function findDuplicatesBy(rows: { [key: string]: string }[], keys: string[]) { return errors } +function validateMainFeeds(rows: { [key: string]: string }[]) { + const errors = new Collection() + const buffer = new Dictionary() + + rows.forEach((row, i) => { + const normId = `${row.channel}${row.is_main}` + if (buffer.has(normId)) { + errors.push({ + line: i + 2, + message: `entry with the channel "${row.channel}" and is_main "true" already exists` + }) + } + + if (row.is_main) { + buffer.set(normId, true) + } + }) + + return errors +} + function validateChannelId(row: { [key: string]: string }, i: number) { const errors = new Collection() - const expectedId = new IDCreator().create(row.name, row.country) + const expectedId = createChannelId(row.name, row.country) if (expectedId !== row.id) { errors.push({ @@ -254,6 +311,22 @@ function validateChannelBroadcastArea(row: { [key: string]: string[] }, i: numbe return errors } +function validateTimezones(row: { [key: string]: string[] }, i: number) { + const errors = new Collection() + const timezones = buffer.get('timezones') + + row.timezones.forEach((timezone: string) => { + if (timezones.missing(timezone)) { + errors.push({ + line: i + 2, + message: `"${row.channel}@${row.id}" has the wrong timezone "${timezone}"` + }) + } + }) + + return errors +} + function handleError(message: string) { logger.error(chalk.red(message)) process.exit(1) diff --git a/scripts/models/feed.ts b/scripts/models/feed.ts new file mode 100644 index 00000000..1f524c8a --- /dev/null +++ b/scripts/models/feed.ts @@ -0,0 +1,67 @@ +type FeedProps = { + channel: string + id: string + name?: string + is_main?: boolean + broadcast_area?: string[] + timezones?: string[] + languages?: string[] + video_format?: string + launched?: string + closed?: string + replaced_by?: string +} + +export class Feed { + channel: string + id: string + name?: string + is_main?: boolean + broadcast_area: string[] + timezones: string[] + languages: string[] + video_format?: string + launched?: string + closed?: string + replaced_by?: string + + constructor({ + channel, + id, + name, + is_main, + broadcast_area, + timezones, + languages, + video_format, + launched, + closed, + replaced_by + }: FeedProps) { + this.channel = channel + 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 + this.launched = launched + this.closed = closed + this.replaced_by = replaced_by + } + + data() { + const { ...object } = this + + return object + } + + 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] + } + } +} diff --git a/scripts/models/index.ts b/scripts/models/index.ts index 2e6c7027..614b5a24 100644 --- a/scripts/models/index.ts +++ b/scripts/models/index.ts @@ -1,2 +1,3 @@ export * from './channel' export * from './blocked' +export * from './feed' diff --git a/scripts/schemes/channels.ts b/scripts/schemes/channels.ts index 25481753..026798b8 100644 --- a/scripts/schemes/channels.ts +++ b/scripts/schemes/channels.ts @@ -46,7 +46,7 @@ export default { 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}$/) + .regex(/^[A-Za-z0-9]+\.[a-z]{2}($|@[A-Za-z0-9]+$)/) .allow(null), website: Joi.string() .regex(/,/, { invert: true }) diff --git a/scripts/schemes/feeds.ts b/scripts/schemes/feeds.ts new file mode 100644 index 00000000..c1cc340f --- /dev/null +++ b/scripts/schemes/feeds.ts @@ -0,0 +1,41 @@ +import BaseJoi from 'joi' +import JoiDate from '@joi/date' + +const Joi = BaseJoi.extend(JoiDate) + +export default { + 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), + 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) +} diff --git a/scripts/schemes/index.ts b/scripts/schemes/index.ts index b01922fb..10a96e92 100644 --- a/scripts/schemes/index.ts +++ b/scripts/schemes/index.ts @@ -5,6 +5,8 @@ import { default as languages } from './languages' import { default as regions } from './regions' import { default as subdivisions } from './subdivisions' import { default as blocklist } from './blocklist' +import { default as feeds } from './feeds' +import { default as timezones } from './timezones' export default { channels, @@ -13,5 +15,7 @@ export default { languages, regions, subdivisions, - blocklist + blocklist, + feeds, + timezones } diff --git a/scripts/schemes/timezones.ts b/scripts/schemes/timezones.ts new file mode 100644 index 00000000..d8da6043 --- /dev/null +++ b/scripts/schemes/timezones.ts @@ -0,0 +1,11 @@ +import Joi from 'joi' + +export default { + 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}$/)) +} diff --git a/scripts/utils.ts b/scripts/utils.ts new file mode 100644 index 00000000..84c76c90 --- /dev/null +++ b/scripts/utils.ts @@ -0,0 +1,24 @@ +export function createChannelId( + name: string | undefined, + country: string | undefined +): string | undefined { + if (!name || !country) return undefined + + const slug = normalize(name) + const code = country.toLowerCase() + + return `${slug}.${code}` +} + +export function createFeedId(name: string) { + return normalize(name) +} + +function normalize(string: string) { + return string + .replace(/^@/gi, 'At') + .replace(/^&/i, 'And') + .replace(/\+/gi, 'Plus') + .replace(/\s-(\d)/gi, ' Minus$1') + .replace(/[^a-z\d]+/gi, '') +} diff --git a/tests/__data__/expected/api/channels.json b/tests/__data__/expected/api/channels.json index 0b513021..52d0a793 100644 --- a/tests/__data__/expected/api/channels.json +++ b/tests/__data__/expected/api/channels.json @@ -1 +1 @@ -[{"id":"002RadioTV.do","name":"002 Radio TV","alt_names":[],"network":null,"owners":[],"country":"DO","subdivision":null,"city":null,"broadcast_area":["c/DO"],"languages":["spa"],"categories":["general"],"is_nsfw":false,"launched":null,"closed":null,"replaced_by":null,"website":"https://www.002radio.com/","logo":"https://i.imgur.com/7oNe8xj.png"},{"id":"BeijingSatelliteTV.cn","name":"Beijing Satellite TV","alt_names":["北京卫视"],"network":null,"owners":[],"country":"CN","subdivision":null,"city":"Beijing","broadcast_area":["c/CN"],"languages":["zho"],"categories":["general"],"is_nsfw":false,"launched":"1979-05-16","closed":null,"replaced_by":null,"website":"https://www.brtn.cn/btv/","logo":"https://i.imgur.com/vsktAez.png"},{"id":"M5.hu","name":"M5","alt_names":[],"network":null,"owners":[],"country":"HU","subdivision":null,"city":null,"broadcast_area":["c/HU"],"languages":["hun"],"categories":["auto"],"is_nsfw":true,"launched":null,"closed":"2001-01-01","replaced_by":"BeijingSatelliteTV.cn","website":"https://www.mediaklikk.hu/m5/","logo":"https://i.imgur.com/y21wFd0.png"}] \ No newline at end of file +[{"id":"002RadioTV.do","name":"002 Radio TV","alt_names":[],"network":null,"owners":[],"country":"DO","subdivision":null,"city":null,"broadcast_area":["c/DO"],"languages":["spa"],"categories":["general"],"is_nsfw":false,"launched":null,"closed":null,"replaced_by":null,"website":"https://www.002radio.com/","logo":"https://i.imgur.com/7oNe8xj.png"},{"id":"BeijingSatelliteTV.cn","name":"Beijing Satellite TV","alt_names":["北京卫视"],"network":null,"owners":[],"country":"CN","subdivision":null,"city":"Beijing","broadcast_area":["c/CN"],"languages":["zho"],"categories":["general"],"is_nsfw":false,"launched":"1979-05-16","closed":null,"replaced_by":"002RadioTV.do@SD","website":"https://www.brtn.cn/btv/","logo":"https://i.imgur.com/vsktAez.png"},{"id":"M5.hu","name":"M5","alt_names":[],"network":null,"owners":[],"country":"HU","subdivision":null,"city":null,"broadcast_area":["c/HU"],"languages":["hun"],"categories":["auto"],"is_nsfw":true,"launched":null,"closed":"2001-01-01","replaced_by":"BeijingSatelliteTV.cn","website":"https://www.mediaklikk.hu/m5/","logo":"https://i.imgur.com/y21wFd0.png"}] \ No newline at end of file diff --git a/tests/__data__/expected/api/feeds.json b/tests/__data__/expected/api/feeds.json new file mode 100644 index 00000000..7ccf4ad8 --- /dev/null +++ b/tests/__data__/expected/api/feeds.json @@ -0,0 +1 @@ +[{"channel":"002RadioTV.do","id":"SD","name":"SD","is_main":true,"broadcast_area":["c/DO"],"timezones":["America/Santo_Domingo"],"languages":["spa"],"video_format":"480i","launched":null,"closed":null,"replaced_by":null},{"channel":"M5.hu","id":"SD","name":"SD","is_main":false,"broadcast_area":["c/DO"],"timezones":["America/Santo_Domingo"],"languages":["spa"],"video_format":"480i","launched":null,"closed":"2021-01-01","replaced_by":"002RadioTV.do@SD"}] \ No newline at end of file diff --git a/tests/__data__/expected/api/timezones.json b/tests/__data__/expected/api/timezones.json new file mode 100644 index 00000000..826da751 --- /dev/null +++ b/tests/__data__/expected/api/timezones.json @@ -0,0 +1 @@ +[{"id":"Africa/Abidjan","utc_offset":"+00:00","countries":["CI","BF","GH","GM","GN","IS","ML","MR","SH","SL","SN","TG"]}] \ No newline at end of file diff --git a/tests/__data__/expected/data/channels.csv b/tests/__data__/expected/data/channels.csv index 494f3030..f82ffc51 100644 --- a/tests/__data__/expected/data/channels.csv +++ b/tests/__data__/expected/data/channels.csv @@ -1,4 +1,6 @@ id,name,alt_names,network,owners,country,subdivision,city,broadcast_area,languages,categories,is_nsfw,launched,closed,replaced_by,website,logo +0TV.dk,0-TV,,,,DK,,København,c/DK,dan,general,FALSE,,,,https://0-tv.dk/,https://i.imgur.com/aR5q6mA.png +1000xHoraTV.uy,1000xHora TV,,,,UY,,Montevideo,c/UY,spa,auto,FALSE,,,M5.hu@HD,https://www.1000xhoratv.com/,https://i.imgur.com/wP3bbYr.png beINMoviesTurk.tr,beIN Movies Turk,beIN Movies Türk,BBC,Gazprom Media,TR,US-CA,London,c/TR,tur,movies,FALSE,1979-05-16,1980-05-16,M5.hu,http://www.digiturk.com.tr/,https://i.imgur.com/nw8Sa2z.png M5.hu,M5,,,Duna Médiaszolgáltató Nonprofit Zrt.,HU,,,c/HU,hun,,TRUE,,,beINMoviesTurk.tr,https://www.mediaklikk.hu/m5/,https://i.imgur.com/y21wFd0.png WenzhouEconomicandEducation.cn,Wenzhou Economic and Education,,,,CN,,Wenzhou,c/CN,zho,science,FALSE,,,,,https://www.tvchinese.net/uploads/tv/wzjjkj.jpg diff --git a/tests/__data__/expected/data/feeds.csv b/tests/__data__/expected/data/feeds.csv new file mode 100644 index 00000000..1fc623ec --- /dev/null +++ b/tests/__data__/expected/data/feeds.csv @@ -0,0 +1,10 @@ +channel,id,name,is_main,broadcast_area,timezones,languages,video_format,launched,closed,replaced_by +0TV.dk,SD,SD,TRUE,c/DK,Europe/Copenhagen,dan,576i,,, +1000xHoraTV.uy,HD,HD,TRUE,c/CN,Africa/Johannesburg;Africa/Kigali,zho,576i,2020-01-01,2021-01-01,M5.hu@HD +1000xHoraTV.uy,SD,SD,FALSE,c/UY,America/Montevideo,spa,576i,,,M5.hu@HD +beINMoviesTurk.tr,SD,SD,TRUE,c/DO,America/Santo_Domingo,spa,480i,,, +M5.hu,HD,HD,TRUE,c/BR,Africa/Dakar;Africa/El_Aaiun,por;spa,1080i,2020-01-01,,0TV.dk@SD +M5.hu,West,West,FALSE,c/DO,America/Santo_Domingo,spa,480i,,2021-01-01, +WenzhouEconomicandEducation.cn,SD,SD,TRUE,c/CN,Africa/Johannesburg;Africa/Kigali,zho,576i,,, +YiwuBusinessChannel.cn,SD,SD,TRUE,c/CN,Africa/Johannesburg;Africa/Kigali,zho,576i,,, +YiwuNewsIntegratedChannel.cn,SD,SD,TRUE,c/CN,Africa/Johannesburg;Africa/Kigali,zho,576i,,, \ No newline at end of file diff --git a/tests/__data__/input/data/blocklist.csv b/tests/__data__/input/export/data/blocklist.csv similarity index 100% rename from tests/__data__/input/data/blocklist.csv rename to tests/__data__/input/export/data/blocklist.csv diff --git a/tests/__data__/input/data/channels.csv b/tests/__data__/input/export/data/channels.csv similarity index 79% rename from tests/__data__/input/data/channels.csv rename to tests/__data__/input/export/data/channels.csv index 9625a3a6..6a3938ef 100644 --- a/tests/__data__/input/data/channels.csv +++ b/tests/__data__/input/export/data/channels.csv @@ -1,4 +1,4 @@ id,name,alt_names,network,owners,country,subdivision,city,broadcast_area,languages,categories,is_nsfw,launched,closed,replaced_by,website,logo 002RadioTV.do,002 Radio TV,,,,DO,,,c/DO,spa,general,FALSE,,,,https://www.002radio.com/,https://i.imgur.com/7oNe8xj.png -BeijingSatelliteTV.cn,Beijing Satellite TV,北京卫视,,,CN,,Beijing,c/CN,zho,general,FALSE,1979-05-16,,,https://www.brtn.cn/btv/,https://i.imgur.com/vsktAez.png +BeijingSatelliteTV.cn,Beijing Satellite TV,北京卫视,,,CN,,Beijing,c/CN,zho,general,FALSE,1979-05-16,,002RadioTV.do@SD,https://www.brtn.cn/btv/,https://i.imgur.com/vsktAez.png M5.hu,M5,,,,HU,,,c/HU,hun,auto,TRUE,,2001-01-01,BeijingSatelliteTV.cn,https://www.mediaklikk.hu/m5/,https://i.imgur.com/y21wFd0.png \ No newline at end of file diff --git a/tests/__data__/input/export/data/feeds.csv b/tests/__data__/input/export/data/feeds.csv new file mode 100644 index 00000000..7e00d7c9 --- /dev/null +++ b/tests/__data__/input/export/data/feeds.csv @@ -0,0 +1,3 @@ +channel,id,name,is_main,broadcast_area,timezones,languages,video_format,launched,closed,replaced_by +002RadioTV.do,SD,SD,TRUE,c/DO,America/Santo_Domingo,spa,480i,,, +M5.hu,SD,SD,FALSE,c/DO,America/Santo_Domingo,spa,480i,,2021-01-01,002RadioTV.do@SD \ No newline at end of file diff --git a/tests/__data__/input/export/data/timezones.csv b/tests/__data__/input/export/data/timezones.csv new file mode 100644 index 00000000..727bf547 --- /dev/null +++ b/tests/__data__/input/export/data/timezones.csv @@ -0,0 +1,2 @@ +id,utc_offset,countries +Africa/Abidjan,+00:00,CI;BF;GH;GM;GN;IS;ML;MR;SH;SL;SN;TG \ No newline at end of file diff --git a/tests/__data__/input/issues/blocklist_add_approved.js b/tests/__data__/input/issues/blocklist_add_approved.js deleted file mode 100644 index a13f3bb2..00000000 --- a/tests/__data__/input/issues/blocklist_add_approved.js +++ /dev/null @@ -1,81 +0,0 @@ -module.exports = [ - { - url: 'https://api.github.com/repos/iptv-org/database/issues/5897', - repository_url: 'https://api.github.com/repos/iptv-org/database', - labels_url: 'https://api.github.com/repos/iptv-org/database/issues/5897/labels{/name}', - comments_url: 'https://api.github.com/repos/iptv-org/database/issues/5897/comments', - events_url: 'https://api.github.com/repos/iptv-org/database/issues/5897/events', - html_url: 'https://github.com/iptv-org/database/issues/5897', - id: 1929261634, - node_id: 'I_kwDOG1Kwp85y_jJC', - number: 5897, - title: 'Block: HGTV Hungary', - user: { - login: 'freearhey', - id: 7253922, - node_id: 'MDQ6VXNlcjcyNTM5MjI=', - avatar_url: 'https://avatars.githubusercontent.com/u/7253922?v=4', - gravatar_id: '', - url: 'https://api.github.com/users/freearhey', - html_url: 'https://github.com/freearhey', - followers_url: 'https://api.github.com/users/freearhey/followers', - following_url: 'https://api.github.com/users/freearhey/following{/other_user}', - gists_url: 'https://api.github.com/users/freearhey/gists{/gist_id}', - starred_url: 'https://api.github.com/users/freearhey/starred{/owner}{/repo}', - subscriptions_url: 'https://api.github.com/users/freearhey/subscriptions', - organizations_url: 'https://api.github.com/users/freearhey/orgs', - repos_url: 'https://api.github.com/users/freearhey/repos', - events_url: 'https://api.github.com/users/freearhey/events{/privacy}', - received_events_url: 'https://api.github.com/users/freearhey/received_events', - type: 'User', - site_admin: false - }, - labels: [ - { - id: 5366738347, - node_id: 'LA_kwDOG1Kwp88AAAABP-Htqw', - url: 'https://api.github.com/repos/iptv-org/database/labels/approved', - name: 'approved', - color: '85DDDE', - default: false, - description: '' - }, - { - id: 6049155772, - node_id: 'LA_kwDOG1Kwp88AAAABaI7KvA', - url: 'https://api.github.com/repos/iptv-org/database/labels/blocklist:add', - name: 'blocklist:add', - color: 'e99695', - default: false, - description: 'Request to add a channel to the blocklist' - } - ], - state: 'open', - locked: false, - assignee: null, - assignees: [], - milestone: null, - comments: 0, - created_at: '2023-10-06T00:35:32Z', - updated_at: '2023-10-06T00:35:32Z', - closed_at: null, - author_association: 'CONTRIBUTOR', - active_lock_reason: null, - body: '### Channel ID\n\nHGTVHungary.hu\n\n### Reason\n\nNSFW\n\n### Reference\n\nhttps://github.com/iptv-org/iptv/issues/1831\n\n### Notes (optional)\n\n_No response_', - reactions: { - url: 'https://api.github.com/repos/iptv-org/database/issues/5897/reactions', - total_count: 0, - '+1': 0, - '-1': 0, - laugh: 0, - hooray: 0, - confused: 0, - heart: 0, - rocket: 0, - eyes: 0 - }, - timeline_url: 'https://api.github.com/repos/iptv-org/database/issues/5897/timeline', - performed_via_github_app: null, - state_reason: null - } -] diff --git a/tests/__data__/input/issues/blocklist_remove_approved.js b/tests/__data__/input/issues/blocklist_remove_approved.js deleted file mode 100644 index 3644c21e..00000000 --- a/tests/__data__/input/issues/blocklist_remove_approved.js +++ /dev/null @@ -1,81 +0,0 @@ -module.exports = [ - { - url: 'https://api.github.com/repos/iptv-org/database/issues/5891', - repository_url: 'https://api.github.com/repos/iptv-org/database', - labels_url: 'https://api.github.com/repos/iptv-org/database/issues/5891/labels{/name}', - comments_url: 'https://api.github.com/repos/iptv-org/database/issues/5891/comments', - events_url: 'https://api.github.com/repos/iptv-org/database/issues/5891/events', - html_url: 'https://github.com/iptv-org/database/issues/5891', - id: 1929261634, - node_id: 'I_kwDOG1Kwp85y_jJC', - number: 5891, - title: 'Unblock: Animal Planet Africa', - user: { - login: 'freearhey', - id: 7253922, - node_id: 'MDQ6VXNlcjcyNTM5MjI=', - avatar_url: 'https://avatars.githubusercontent.com/u/7253922?v=4', - gravatar_id: '', - url: 'https://api.github.com/users/freearhey', - html_url: 'https://github.com/freearhey', - followers_url: 'https://api.github.com/users/freearhey/followers', - following_url: 'https://api.github.com/users/freearhey/following{/other_user}', - gists_url: 'https://api.github.com/users/freearhey/gists{/gist_id}', - starred_url: 'https://api.github.com/users/freearhey/starred{/owner}{/repo}', - subscriptions_url: 'https://api.github.com/users/freearhey/subscriptions', - organizations_url: 'https://api.github.com/users/freearhey/orgs', - repos_url: 'https://api.github.com/users/freearhey/repos', - events_url: 'https://api.github.com/users/freearhey/events{/privacy}', - received_events_url: 'https://api.github.com/users/freearhey/received_events', - type: 'User', - site_admin: false - }, - labels: [ - { - id: 5366738347, - node_id: 'LA_kwDOG1Kwp88AAAABP-Htqw', - url: 'https://api.github.com/repos/iptv-org/database/labels/approved', - name: 'approved', - color: '85DDDE', - default: false, - description: '' - }, - { - id: 6049155772, - node_id: 'LA_kwDOG1Kwp88AAAABaI7KvA', - url: 'https://api.github.com/repos/iptv-org/database/labels/blocklist:add', - name: 'blocklist:remove', - color: 'e99695', - default: false, - description: 'Request to remove a channel from the blocklist' - } - ], - state: 'open', - locked: false, - assignee: null, - assignees: [], - milestone: null, - comments: 0, - created_at: '2023-10-06T00:35:32Z', - updated_at: '2023-10-06T00:35:32Z', - closed_at: null, - author_association: 'CONTRIBUTOR', - active_lock_reason: null, - body: '### Channel ID\n\nAnimalPlanetAfrica.za\n\n### Reason\n\nOther\n\n### Notes (optional)\n\n_No response_', - reactions: { - url: 'https://api.github.com/repos/iptv-org/database/issues/5891/reactions', - total_count: 0, - '+1': 0, - '-1': 0, - laugh: 0, - hooray: 0, - confused: 0, - heart: 0, - rocket: 0, - eyes: 0 - }, - timeline_url: 'https://api.github.com/repos/iptv-org/database/issues/5891/timeline', - performed_via_github_app: null, - state_reason: null - } -] diff --git a/tests/__data__/input/issues/channels_add_approved.js b/tests/__data__/input/issues/channels_add_approved.js deleted file mode 100644 index 12472861..00000000 --- a/tests/__data__/input/issues/channels_add_approved.js +++ /dev/null @@ -1,239 +0,0 @@ -module.exports = [ - { - url: 'https://api.github.com/repos/iptv-org/database/issues/5900', - repository_url: 'https://api.github.com/repos/iptv-org/database', - labels_url: 'https://api.github.com/repos/iptv-org/database/issues/5900/labels{/name}', - comments_url: 'https://api.github.com/repos/iptv-org/database/issues/5900/comments', - events_url: 'https://api.github.com/repos/iptv-org/database/issues/5900/events', - html_url: 'https://github.com/iptv-org/database/issues/5900', - id: 1929321995, - node_id: 'I_kwDOG1Kwp85y_x4L', - number: 5900, - title: 'Add: Yiwu News Integrated Channel', - user: { - login: 'AntiPontifex', - id: 81566772, - node_id: 'MDQ6VXNlcjgxNTY2Nzcy', - avatar_url: 'https://avatars.githubusercontent.com/u/81566772?v=4', - gravatar_id: '', - url: 'https://api.github.com/users/AntiPontifex', - html_url: 'https://github.com/AntiPontifex', - followers_url: 'https://api.github.com/users/AntiPontifex/followers', - following_url: 'https://api.github.com/users/AntiPontifex/following{/other_user}', - gists_url: 'https://api.github.com/users/AntiPontifex/gists{/gist_id}', - starred_url: 'https://api.github.com/users/AntiPontifex/starred{/owner}{/repo}', - subscriptions_url: 'https://api.github.com/users/AntiPontifex/subscriptions', - organizations_url: 'https://api.github.com/users/AntiPontifex/orgs', - repos_url: 'https://api.github.com/users/AntiPontifex/repos', - events_url: 'https://api.github.com/users/AntiPontifex/events{/privacy}', - received_events_url: 'https://api.github.com/users/AntiPontifex/received_events', - type: 'User', - site_admin: false - }, - labels: [ - { - id: 5303575699, - node_id: 'LA_kwDOG1Kwp88AAAABPB4kkw', - url: 'https://api.github.com/repos/iptv-org/database/labels/channels:add', - name: 'channels:add', - color: '017ff8', - default: false, - description: 'Request to add a channel into the database' - }, - { - id: 5366738347, - node_id: 'LA_kwDOG1Kwp88AAAABP-Htqw', - url: 'https://api.github.com/repos/iptv-org/database/labels/approved', - name: 'approved', - color: '85DDDE', - default: false, - description: '' - } - ], - state: 'open', - locked: false, - assignee: null, - assignees: [], - milestone: null, - comments: 0, - created_at: '2023-10-06T02:10:41Z', - updated_at: '2023-10-06T02:52:02Z', - closed_at: null, - author_association: 'CONTRIBUTOR', - active_lock_reason: null, - body: '### Channel Name\n\nYiwu News Integrated Channel\n\n### Alternative Names (optional)\n\n_No response_\n\n### Network (optional)\n\n_No response_\n\n### Owners (optional)\n\n_No response_\n\n### Country\n\nCN\n\n### Subdivision (optional)\n\n_No response_\n\n### City (optional)\n\n_No response_\n\n### Broadcast Area\n\nc/CN\n\n### Languages\n\nzho\n\n### Categories (optional)\n\nnews\n\n### NSFW\n\nFALSE\n\n### Launched (optional)\n\n_No response_\n\n### Closed (optional)\n\n_No response_\n\n### Replaced By (optional)\n\n_No response_\n\n### Website (optional)\n\n_No response_\n\n### Logo\n\nhttps://www.tvchinese.net/uploads/tv/yiwutv.jpg\n\n### Notes\n\n_No response_', - reactions: { - url: 'https://api.github.com/repos/iptv-org/database/issues/5900/reactions', - total_count: 0, - '+1': 0, - '-1': 0, - laugh: 0, - hooray: 0, - confused: 0, - heart: 0, - rocket: 0, - eyes: 0 - }, - timeline_url: 'https://api.github.com/repos/iptv-org/database/issues/5900/timeline', - performed_via_github_app: null, - state_reason: null - }, - { - url: 'https://api.github.com/repos/iptv-org/database/issues/5899', - repository_url: 'https://api.github.com/repos/iptv-org/database', - labels_url: 'https://api.github.com/repos/iptv-org/database/issues/5899/labels{/name}', - comments_url: 'https://api.github.com/repos/iptv-org/database/issues/5899/comments', - events_url: 'https://api.github.com/repos/iptv-org/database/issues/5899/events', - html_url: 'https://github.com/iptv-org/database/issues/5899', - id: 1929318573, - node_id: 'I_kwDOG1Kwp85y_xCt', - number: 5899, - title: 'Add: Yiwu Business Channel', - user: { - login: 'AntiPontifex', - id: 81566772, - node_id: 'MDQ6VXNlcjgxNTY2Nzcy', - avatar_url: 'https://avatars.githubusercontent.com/u/81566772?v=4', - gravatar_id: '', - url: 'https://api.github.com/users/AntiPontifex', - html_url: 'https://github.com/AntiPontifex', - followers_url: 'https://api.github.com/users/AntiPontifex/followers', - following_url: 'https://api.github.com/users/AntiPontifex/following{/other_user}', - gists_url: 'https://api.github.com/users/AntiPontifex/gists{/gist_id}', - starred_url: 'https://api.github.com/users/AntiPontifex/starred{/owner}{/repo}', - subscriptions_url: 'https://api.github.com/users/AntiPontifex/subscriptions', - organizations_url: 'https://api.github.com/users/AntiPontifex/orgs', - repos_url: 'https://api.github.com/users/AntiPontifex/repos', - events_url: 'https://api.github.com/users/AntiPontifex/events{/privacy}', - received_events_url: 'https://api.github.com/users/AntiPontifex/received_events', - type: 'User', - site_admin: false - }, - labels: [ - { - id: 5303575699, - node_id: 'LA_kwDOG1Kwp88AAAABPB4kkw', - url: 'https://api.github.com/repos/iptv-org/database/labels/channels:add', - name: 'channels:add', - color: '017ff8', - default: false, - description: 'Request to add a channel into the database' - }, - { - id: 5366738347, - node_id: 'LA_kwDOG1Kwp88AAAABP-Htqw', - url: 'https://api.github.com/repos/iptv-org/database/labels/approved', - name: 'approved', - color: '85DDDE', - default: false, - description: '' - } - ], - state: 'open', - locked: false, - assignee: null, - assignees: [], - milestone: null, - comments: 0, - created_at: '2023-10-06T02:05:11Z', - updated_at: '2023-10-06T02:51:46Z', - closed_at: null, - author_association: 'CONTRIBUTOR', - active_lock_reason: null, - body: '### Channel Name\n\nYiwu Business Channel\n\n### Alternative Names (optional)\n\n_No response_\n\n### Network (optional)\n\n_No response_\n\n### Owners (optional)\n\n_No response_\n\n### Country\n\nCN\n\n### Subdivision (optional)\n\n_No response_\n\n### City (optional)\n\n_No response_\n\n### Broadcast Area\n\nc/CN\n\n### Languages\n\nzho\n\n### Categories (optional)\n\nbusiness\n\n### NSFW\n\nFALSE\n\n### Launched (optional)\n\n_No response_\n\n### Closed (optional)\n\n_No response_\n\n### Replaced By (optional)\n\n_No response_\n\n### Website (optional)\n\n_No response_\n\n### Logo\n\nhttps://www.tvchinese.net/uploads/tv/yiwutv.jpg\n\n### Notes\n\n_No response_', - reactions: { - url: 'https://api.github.com/repos/iptv-org/database/issues/5899/reactions', - total_count: 0, - '+1': 0, - '-1': 0, - laugh: 0, - hooray: 0, - confused: 0, - heart: 0, - rocket: 0, - eyes: 0 - }, - timeline_url: 'https://api.github.com/repos/iptv-org/database/issues/5899/timeline', - performed_via_github_app: null, - state_reason: null - }, - { - url: 'https://api.github.com/repos/iptv-org/database/issues/5898', - repository_url: 'https://api.github.com/repos/iptv-org/database', - labels_url: 'https://api.github.com/repos/iptv-org/database/issues/5898/labels{/name}', - comments_url: 'https://api.github.com/repos/iptv-org/database/issues/5898/comments', - events_url: 'https://api.github.com/repos/iptv-org/database/issues/5898/events', - html_url: 'https://github.com/iptv-org/database/issues/5898', - id: 1929313117, - node_id: 'I_kwDOG1Kwp85y_vtd', - number: 5898, - title: 'Add: Wenzhou Economic and Education', - user: { - login: 'AntiPontifex', - id: 81566772, - node_id: 'MDQ6VXNlcjgxNTY2Nzcy', - avatar_url: 'https://avatars.githubusercontent.com/u/81566772?v=4', - gravatar_id: '', - url: 'https://api.github.com/users/AntiPontifex', - html_url: 'https://github.com/AntiPontifex', - followers_url: 'https://api.github.com/users/AntiPontifex/followers', - following_url: 'https://api.github.com/users/AntiPontifex/following{/other_user}', - gists_url: 'https://api.github.com/users/AntiPontifex/gists{/gist_id}', - starred_url: 'https://api.github.com/users/AntiPontifex/starred{/owner}{/repo}', - subscriptions_url: 'https://api.github.com/users/AntiPontifex/subscriptions', - organizations_url: 'https://api.github.com/users/AntiPontifex/orgs', - repos_url: 'https://api.github.com/users/AntiPontifex/repos', - events_url: 'https://api.github.com/users/AntiPontifex/events{/privacy}', - received_events_url: 'https://api.github.com/users/AntiPontifex/received_events', - type: 'User', - site_admin: false - }, - labels: [ - { - id: 5303575699, - node_id: 'LA_kwDOG1Kwp88AAAABPB4kkw', - url: 'https://api.github.com/repos/iptv-org/database/labels/channels:add', - name: 'channels:add', - color: '017ff8', - default: false, - description: 'Request to add a channel into the database' - }, - { - id: 5366738347, - node_id: 'LA_kwDOG1Kwp88AAAABP-Htqw', - url: 'https://api.github.com/repos/iptv-org/database/labels/approved', - name: 'approved', - color: '85DDDE', - default: false, - description: '' - } - ], - state: 'open', - locked: false, - assignee: null, - assignees: [], - milestone: null, - comments: 0, - created_at: '2023-10-06T01:56:32Z', - updated_at: '2023-10-06T02:51:22Z', - closed_at: null, - author_association: 'CONTRIBUTOR', - active_lock_reason: null, - body: '### Channel Name\n\nWenzhou Economic and Education\n\n### Alternative Names (optional)\n\n_No response_\n\n### Network (optional)\n\n_No response_\n\n### Owners (optional)\n\n_No response_\n\n### Country\n\nCN\n\n### Subdivision (optional)\n\n_No response_\n\n### City (optional)\n\nWenzhou\n\n### Broadcast Area\n\nc/CN\n\n### Languages\n\nzho\n\n### Categories (optional)\n\nscience\n\n### NSFW\n\nFALSE\n\n### Launched (optional)\n\n_No response_\n\n### Closed (optional)\n\n_No response_\n\n### Replaced By (optional)\n\n_No response_\n\n### Website (optional)\n\n_No response_\n\n### Logo\n\nhttps://www.tvchinese.net/uploads/tv/wzjjkj.jpg\n\n### Notes\n\n_No response_', - reactions: { - url: 'https://api.github.com/repos/iptv-org/database/issues/5898/reactions', - total_count: 0, - '+1': 0, - '-1': 0, - laugh: 0, - hooray: 0, - confused: 0, - heart: 0, - rocket: 0, - eyes: 0 - }, - timeline_url: 'https://api.github.com/repos/iptv-org/database/issues/5898/timeline', - performed_via_github_app: null, - state_reason: null - } -] diff --git a/tests/__data__/input/issues/channels_edit_approved.js b/tests/__data__/input/issues/channels_edit_approved.js deleted file mode 100644 index 5370c326..00000000 --- a/tests/__data__/input/issues/channels_edit_approved.js +++ /dev/null @@ -1,160 +0,0 @@ -module.exports = [ - { - url: 'https://api.github.com/repos/iptv-org/database/issues/5901', - repository_url: 'https://api.github.com/repos/iptv-org/database', - labels_url: 'https://api.github.com/repos/iptv-org/database/issues/5901/labels{/name}', - comments_url: 'https://api.github.com/repos/iptv-org/database/issues/5901/comments', - events_url: 'https://api.github.com/repos/iptv-org/database/issues/5901/events', - html_url: 'https://github.com/iptv-org/database/issues/5901', - id: 1929459171, - node_id: 'I_kwDOG1Kwp85zATXj', - number: 5901, - title: 'Edit: M5', - user: { - login: 'freearhey', - id: 7253922, - node_id: 'MDQ6VXNlcjcyNTM5MjI=', - avatar_url: 'https://avatars.githubusercontent.com/u/7253922?v=4', - gravatar_id: '', - url: 'https://api.github.com/users/freearhey', - html_url: 'https://github.com/freearhey', - followers_url: 'https://api.github.com/users/freearhey/followers', - following_url: 'https://api.github.com/users/freearhey/following{/other_user}', - gists_url: 'https://api.github.com/users/freearhey/gists{/gist_id}', - starred_url: 'https://api.github.com/users/freearhey/starred{/owner}{/repo}', - subscriptions_url: 'https://api.github.com/users/freearhey/subscriptions', - organizations_url: 'https://api.github.com/users/freearhey/orgs', - repos_url: 'https://api.github.com/users/freearhey/repos', - events_url: 'https://api.github.com/users/freearhey/events{/privacy}', - received_events_url: 'https://api.github.com/users/freearhey/received_events', - type: 'User', - site_admin: false - }, - labels: [ - { - id: 5303574335, - node_id: 'LA_kwDOG1Kwp88AAAABPB4fPw', - url: 'https://api.github.com/repos/iptv-org/database/labels/channels:edit', - name: 'channels:edit', - color: 'E12977', - default: false, - description: 'Request to edit channel description' - }, - { - id: 5366738347, - node_id: 'LA_kwDOG1Kwp88AAAABP-Htqw', - url: 'https://api.github.com/repos/iptv-org/database/labels/approved', - name: 'approved', - color: '85DDDE', - default: false, - description: '' - } - ], - state: 'open', - locked: false, - assignee: null, - assignees: [], - milestone: null, - comments: 0, - created_at: '2023-10-06T05:25:44Z', - updated_at: '2023-10-06T05:25:44Z', - closed_at: null, - author_association: 'CONTRIBUTOR', - active_lock_reason: null, - body: '### Channel ID (required)\n\nM5.hu\n\n### Channel Name\n\n_No response_\n\n### Alternative Names\n\n_No response_\n\n### Network\n\n_No response_\n\n### Owners\n\nDuna Médiaszolgáltató Nonprofit Zrt.\n\n### Country\n\n_No response_\n\n### Subdivision\n\n_No response_\n\n### City\n\n_No response_\n\n### Broadcast Area\n\n_No response_\n\n### Languages\n\n_No response_\n\n### Categories\n\n~\n\n### NSFW\n\nNone\n\n### Launched\n\n_No response_\n\n### Closed\n\n~\n\n### Replaced By\n\n_No response_\n\n### Website\n\n_No response_\n\n### Logo\n\n_No response_\n\n### Notes\n\n_No response_', - reactions: { - url: 'https://api.github.com/repos/iptv-org/database/issues/5901/reactions', - total_count: 0, - '+1': 0, - '-1': 0, - laugh: 0, - hooray: 0, - confused: 0, - heart: 0, - rocket: 0, - eyes: 0 - }, - timeline_url: 'https://api.github.com/repos/iptv-org/database/issues/5901/timeline', - performed_via_github_app: null, - state_reason: null - }, - { - url: 'https://api.github.com/repos/iptv-org/database/issues/5701', - repository_url: 'https://api.github.com/repos/iptv-org/database', - labels_url: 'https://api.github.com/repos/iptv-org/database/issues/5701/labels{/name}', - comments_url: 'https://api.github.com/repos/iptv-org/database/issues/5701/comments', - events_url: 'https://api.github.com/repos/iptv-org/database/issues/5701/events', - html_url: 'https://github.com/iptv-org/database/issues/5701', - id: 1929459171, - node_id: 'I_kwDOG1Kwp85zATXj', - number: 5701, - title: 'Edit: M5', - user: { - login: 'freearhey', - id: 7253922, - node_id: 'MDQ6VXNlcjcyNTM5MjI=', - avatar_url: 'https://avatars.githubusercontent.com/u/7253922?v=4', - gravatar_id: '', - url: 'https://api.github.com/users/freearhey', - html_url: 'https://github.com/freearhey', - followers_url: 'https://api.github.com/users/freearhey/followers', - following_url: 'https://api.github.com/users/freearhey/following{/other_user}', - gists_url: 'https://api.github.com/users/freearhey/gists{/gist_id}', - starred_url: 'https://api.github.com/users/freearhey/starred{/owner}{/repo}', - subscriptions_url: 'https://api.github.com/users/freearhey/subscriptions', - organizations_url: 'https://api.github.com/users/freearhey/orgs', - repos_url: 'https://api.github.com/users/freearhey/repos', - events_url: 'https://api.github.com/users/freearhey/events{/privacy}', - received_events_url: 'https://api.github.com/users/freearhey/received_events', - type: 'User', - site_admin: false - }, - labels: [ - { - id: 5303574335, - node_id: 'LA_kwDOG1Kwp88AAAABPB4fPw', - url: 'https://api.github.com/repos/iptv-org/database/labels/channels:edit', - name: 'channels:edit', - color: 'E12977', - default: false, - description: 'Request to edit channel description' - }, - { - id: 5366738347, - node_id: 'LA_kwDOG1Kwp88AAAABP-Htqw', - url: 'https://api.github.com/repos/iptv-org/database/labels/approved', - name: 'approved', - color: '85DDDE', - default: false, - description: '' - } - ], - state: 'open', - locked: false, - assignee: null, - assignees: [], - milestone: null, - comments: 0, - created_at: '2023-10-06T05:25:44Z', - updated_at: '2023-10-06T05:25:44Z', - closed_at: null, - author_association: 'CONTRIBUTOR', - active_lock_reason: null, - body: '### Channel ID (required)\n\nBeijingSatelliteTV.cn\n\n### Channel Name\n\nbeIN Movies Turk\n\n### Alternative Names\n\nbeIN Movies Türk\n\n### Network\n\nBBC\n\n### Owners\n\nGazprom Media\n\n### Country\n\nTR\n\n### Subdivision\n\nUS-CA\n\n### City\n\nLondon\n\n### Broadcast Area\n\nc/TR\n\n### Languages\n\ntur\n\n### Categories\n\nmovies\n\n### NSFW\nTRUE\n\n### Launched\n\n1979-05-16\n\n### Closed\n\n1980-05-16\n\n### Replaced By\n\nM5.hu\n\n### Website\n\nhttp://www.digiturk.com.tr/\n\n### Logo\n\nhttps://i.imgur.com/nw8Sa2z.png\n\n### Notes\n\n_No response_', - reactions: { - url: 'https://api.github.com/repos/iptv-org/database/issues/5701/reactions', - total_count: 0, - '+1': 0, - '-1': 0, - laugh: 0, - hooray: 0, - confused: 0, - heart: 0, - rocket: 0, - eyes: 0 - }, - timeline_url: 'https://api.github.com/repos/iptv-org/database/issues/5701/timeline', - performed_via_github_app: null, - state_reason: null - } -] diff --git a/tests/__data__/input/issues/channels_remove_approved.js b/tests/__data__/input/issues/channels_remove_approved.js deleted file mode 100644 index 96ff8cad..00000000 --- a/tests/__data__/input/issues/channels_remove_approved.js +++ /dev/null @@ -1,81 +0,0 @@ -module.exports = [ - { - url: 'https://api.github.com/repos/iptv-org/database/issues/5871', - repository_url: 'https://api.github.com/repos/iptv-org/database', - labels_url: 'https://api.github.com/repos/iptv-org/database/issues/5871/labels{/name}', - comments_url: 'https://api.github.com/repos/iptv-org/database/issues/5871/comments', - events_url: 'https://api.github.com/repos/iptv-org/database/issues/5871/events', - html_url: 'https://github.com/iptv-org/database/issues/5871', - id: 1929261634, - node_id: 'I_kwDOG1Kwp85y_jJC', - number: 5871, - title: 'Remove: 002 Radio TV', - user: { - login: 'freearhey', - id: 7253922, - node_id: 'MDQ6VXNlcjcyNTM5MjI=', - avatar_url: 'https://avatars.githubusercontent.com/u/7253922?v=4', - gravatar_id: '', - url: 'https://api.github.com/users/freearhey', - html_url: 'https://github.com/freearhey', - followers_url: 'https://api.github.com/users/freearhey/followers', - following_url: 'https://api.github.com/users/freearhey/following{/other_user}', - gists_url: 'https://api.github.com/users/freearhey/gists{/gist_id}', - starred_url: 'https://api.github.com/users/freearhey/starred{/owner}{/repo}', - subscriptions_url: 'https://api.github.com/users/freearhey/subscriptions', - organizations_url: 'https://api.github.com/users/freearhey/orgs', - repos_url: 'https://api.github.com/users/freearhey/repos', - events_url: 'https://api.github.com/users/freearhey/events{/privacy}', - received_events_url: 'https://api.github.com/users/freearhey/received_events', - type: 'User', - site_admin: false - }, - labels: [ - { - id: 5366738347, - node_id: 'LA_kwDOG1Kwp88AAAABP-Htqw', - url: 'https://api.github.com/repos/iptv-org/database/labels/approved', - name: 'approved', - color: '85DDDE', - default: false, - description: '' - }, - { - id: 6049155772, - node_id: 'LA_kwDOG1Kwp88AAAABaI7KvA', - url: 'https://api.github.com/repos/iptv-org/database/labels/blocklist:add', - name: 'channels:remove', - color: 'e99695', - default: false, - description: 'Request to remove a channel' - } - ], - state: 'open', - locked: false, - assignee: null, - assignees: [], - milestone: null, - comments: 0, - created_at: '2023-10-06T00:35:32Z', - updated_at: '2023-10-06T00:35:32Z', - closed_at: null, - author_association: 'CONTRIBUTOR', - active_lock_reason: null, - body: '### Channel ID\n\n002RadioTV.do\n\n### Reason\n\nOther\n\n### Notes (optional)\n\n_No response_', - reactions: { - url: 'https://api.github.com/repos/iptv-org/database/issues/5871/reactions', - total_count: 0, - '+1': 0, - '-1': 0, - laugh: 0, - hooray: 0, - confused: 0, - heart: 0, - rocket: 0, - eyes: 0 - }, - timeline_url: 'https://api.github.com/repos/iptv-org/database/issues/5871/timeline', - performed_via_github_app: null, - state_reason: null - } -] diff --git a/tests/__data__/input/update/data/blocklist.csv b/tests/__data__/input/update/data/blocklist.csv new file mode 100644 index 00000000..a0e89ff7 --- /dev/null +++ b/tests/__data__/input/update/data/blocklist.csv @@ -0,0 +1,3 @@ +channel,reason,ref +AnimalPlanetAfrica.za,dmca,https://github.com/iptv-org/iptv/issues/1831 +BeijingSatelliteTV.cn,dmca,https://github.com/iptv-org/iptv/issues/1831 \ No newline at end of file diff --git a/tests/__data__/input/update/data/channels.csv b/tests/__data__/input/update/data/channels.csv new file mode 100644 index 00000000..187e395b --- /dev/null +++ b/tests/__data__/input/update/data/channels.csv @@ -0,0 +1,6 @@ +id,name,alt_names,network,owners,country,subdivision,city,broadcast_area,languages,categories,is_nsfw,launched,closed,replaced_by,website,logo +002RadioTV.do,002 Radio TV,,,,DO,,,c/DO,spa,general,FALSE,,,,https://www.002radio.com/,https://i.imgur.com/7oNe8xj.png +0TV.dk,0-TV,,,,DK,,København,c/DK,dan,general,FALSE,,,01TV.fr@SD,https://0-tv.dk/,https://i.imgur.com/aR5q6mA.png +1000xHoraTV.uy,1000xHora TV,,,,UY,,Montevideo,c/UY,spa,auto,FALSE,,,M5.hu@SD,https://www.1000xhoratv.com/,https://i.imgur.com/wP3bbYr.png +BeijingSatelliteTV.cn,Beijing Satellite TV,北京卫视,,,CN,,Beijing,c/CN,zho,general,FALSE,1979-05-16,,002RadioTV.do@SD,https://www.brtn.cn/btv/,https://i.imgur.com/vsktAez.png +M5.hu,M5,,,,HU,,,c/HU,hun,auto,TRUE,,2001-01-01,BeijingSatelliteTV.cn,https://www.mediaklikk.hu/m5/,https://i.imgur.com/y21wFd0.png \ No newline at end of file diff --git a/tests/__data__/input/update/data/feeds.csv b/tests/__data__/input/update/data/feeds.csv new file mode 100644 index 00000000..fa3fbf5a --- /dev/null +++ b/tests/__data__/input/update/data/feeds.csv @@ -0,0 +1,8 @@ +channel,id,name,is_main,broadcast_area,timezones,languages,video_format,launched,closed,replaced_by +002RadioTV.do,SD,SD,TRUE,c/DO,America/Santo_Domingo,spa,480i,,, +01TV.fr,SD,SD,TRUE,c/FR,Europe/Paris,fra,576i,,, +0TV.dk,SD,SD,TRUE,c/DK,Europe/Copenhagen,dan,576i,,,01TV.fr@SD +1000xHoraTV.uy,SD,SD,TRUE,c/UY,America/Montevideo,spa,576i,,,M5.hu@SD +BeijingSatelliteTV.cn,SD,SD,TRUE,c/DO,America/Santo_Domingo,spa,480i,,,002RadioTV.do@SD +M5.hu,SD,SD,FALSE,c/DO,America/Santo_Domingo,spa,480i,,2021-01-01,002RadioTV.do@SD +M5.hu,West,West,TRUE,c/DO,America/Santo_Domingo,spa,480i,,2021-01-01, \ No newline at end of file diff --git a/tests/__data__/input/update/data/timezones.csv b/tests/__data__/input/update/data/timezones.csv new file mode 100644 index 00000000..727bf547 --- /dev/null +++ b/tests/__data__/input/update/data/timezones.csv @@ -0,0 +1,2 @@ +id,utc_offset,countries +Africa/Abidjan,+00:00,CI;BF;GH;GM;GN;IS;ML;MR;SH;SL;SN;TG \ No newline at end of file diff --git a/tests/__data__/input/update/issues.js b/tests/__data__/input/update/issues.js new file mode 100644 index 00000000..b49cee64 --- /dev/null +++ b/tests/__data__/input/update/issues.js @@ -0,0 +1,871 @@ +module.exports = [ + { + url: 'https://api.github.com/repos/iptv-org/database/issues/5897', + repository_url: 'https://api.github.com/repos/iptv-org/database', + labels_url: 'https://api.github.com/repos/iptv-org/database/issues/5897/labels{/name}', + comments_url: 'https://api.github.com/repos/iptv-org/database/issues/5897/comments', + events_url: 'https://api.github.com/repos/iptv-org/database/issues/5897/events', + html_url: 'https://github.com/iptv-org/database/issues/5897', + id: 1929261634, + node_id: 'I_kwDOG1Kwp85y_jJC', + number: 5897, + title: 'Block: HGTV Hungary', + user: { + login: 'freearhey', + id: 7253922, + node_id: 'MDQ6VXNlcjcyNTM5MjI=', + avatar_url: 'https://avatars.githubusercontent.com/u/7253922?v=4', + gravatar_id: '', + url: 'https://api.github.com/users/freearhey', + html_url: 'https://github.com/freearhey', + followers_url: 'https://api.github.com/users/freearhey/followers', + following_url: 'https://api.github.com/users/freearhey/following{/other_user}', + gists_url: 'https://api.github.com/users/freearhey/gists{/gist_id}', + starred_url: 'https://api.github.com/users/freearhey/starred{/owner}{/repo}', + subscriptions_url: 'https://api.github.com/users/freearhey/subscriptions', + organizations_url: 'https://api.github.com/users/freearhey/orgs', + repos_url: 'https://api.github.com/users/freearhey/repos', + events_url: 'https://api.github.com/users/freearhey/events{/privacy}', + received_events_url: 'https://api.github.com/users/freearhey/received_events', + type: 'User', + site_admin: false + }, + labels: [ + { + id: 5366738347, + node_id: 'LA_kwDOG1Kwp88AAAABP-Htqw', + url: 'https://api.github.com/repos/iptv-org/database/labels/approved', + name: 'approved', + color: '85DDDE', + default: false, + description: '' + }, + { + id: 6049155772, + node_id: 'LA_kwDOG1Kwp88AAAABaI7KvA', + url: 'https://api.github.com/repos/iptv-org/database/labels/blocklist:add', + name: 'blocklist:add', + color: 'e99695', + default: false, + description: 'Request to add a channel to the blocklist' + } + ], + state: 'open', + locked: false, + assignee: null, + assignees: [], + milestone: null, + comments: 0, + created_at: '2023-10-06T00:35:32Z', + updated_at: '2023-10-06T00:35:32Z', + closed_at: null, + author_association: 'CONTRIBUTOR', + active_lock_reason: null, + body: '### Channel ID\n\nHGTVHungary.hu\n\n### Reason\n\nNSFW\n\n### Reference\n\nhttps://github.com/iptv-org/iptv/issues/1831\n\n### Notes (optional)\n\n_No response_', + reactions: { + url: 'https://api.github.com/repos/iptv-org/database/issues/5897/reactions', + total_count: 0, + '+1': 0, + '-1': 0, + laugh: 0, + hooray: 0, + confused: 0, + heart: 0, + rocket: 0, + eyes: 0 + }, + timeline_url: 'https://api.github.com/repos/iptv-org/database/issues/5897/timeline', + performed_via_github_app: null, + state_reason: null + }, + { + url: 'https://api.github.com/repos/iptv-org/database/issues/5891', + repository_url: 'https://api.github.com/repos/iptv-org/database', + labels_url: 'https://api.github.com/repos/iptv-org/database/issues/5891/labels{/name}', + comments_url: 'https://api.github.com/repos/iptv-org/database/issues/5891/comments', + events_url: 'https://api.github.com/repos/iptv-org/database/issues/5891/events', + html_url: 'https://github.com/iptv-org/database/issues/5891', + id: 1929261634, + node_id: 'I_kwDOG1Kwp85y_jJC', + number: 5891, + title: 'Unblock: Animal Planet Africa', + user: { + login: 'freearhey', + id: 7253922, + node_id: 'MDQ6VXNlcjcyNTM5MjI=', + avatar_url: 'https://avatars.githubusercontent.com/u/7253922?v=4', + gravatar_id: '', + url: 'https://api.github.com/users/freearhey', + html_url: 'https://github.com/freearhey', + followers_url: 'https://api.github.com/users/freearhey/followers', + following_url: 'https://api.github.com/users/freearhey/following{/other_user}', + gists_url: 'https://api.github.com/users/freearhey/gists{/gist_id}', + starred_url: 'https://api.github.com/users/freearhey/starred{/owner}{/repo}', + subscriptions_url: 'https://api.github.com/users/freearhey/subscriptions', + organizations_url: 'https://api.github.com/users/freearhey/orgs', + repos_url: 'https://api.github.com/users/freearhey/repos', + events_url: 'https://api.github.com/users/freearhey/events{/privacy}', + received_events_url: 'https://api.github.com/users/freearhey/received_events', + type: 'User', + site_admin: false + }, + labels: [ + { + id: 5366738347, + node_id: 'LA_kwDOG1Kwp88AAAABP-Htqw', + url: 'https://api.github.com/repos/iptv-org/database/labels/approved', + name: 'approved', + color: '85DDDE', + default: false, + description: '' + }, + { + id: 6049155772, + node_id: 'LA_kwDOG1Kwp88AAAABaI7KvA', + url: 'https://api.github.com/repos/iptv-org/database/labels/blocklist:add', + name: 'blocklist:remove', + color: 'e99695', + default: false, + description: 'Request to remove a channel from the blocklist' + } + ], + state: 'open', + locked: false, + assignee: null, + assignees: [], + milestone: null, + comments: 0, + created_at: '2023-10-06T00:35:32Z', + updated_at: '2023-10-06T00:35:32Z', + closed_at: null, + author_association: 'CONTRIBUTOR', + active_lock_reason: null, + body: '### Channel ID\n\nAnimalPlanetAfrica.za\n\n### Reason\n\nOther\n\n### Notes (optional)\n\n_No response_', + reactions: { + url: 'https://api.github.com/repos/iptv-org/database/issues/5891/reactions', + total_count: 0, + '+1': 0, + '-1': 0, + laugh: 0, + hooray: 0, + confused: 0, + heart: 0, + rocket: 0, + eyes: 0 + }, + timeline_url: 'https://api.github.com/repos/iptv-org/database/issues/5891/timeline', + performed_via_github_app: null, + state_reason: null + }, + { + url: 'https://api.github.com/repos/iptv-org/database/issues/5900', + repository_url: 'https://api.github.com/repos/iptv-org/database', + labels_url: 'https://api.github.com/repos/iptv-org/database/issues/5900/labels{/name}', + comments_url: 'https://api.github.com/repos/iptv-org/database/issues/5900/comments', + events_url: 'https://api.github.com/repos/iptv-org/database/issues/5900/events', + html_url: 'https://github.com/iptv-org/database/issues/5900', + id: 1929321995, + node_id: 'I_kwDOG1Kwp85y_x4L', + number: 5900, + title: 'Add: Yiwu News Integrated Channel', + user: { + login: 'AntiPontifex', + id: 81566772, + node_id: 'MDQ6VXNlcjgxNTY2Nzcy', + avatar_url: 'https://avatars.githubusercontent.com/u/81566772?v=4', + gravatar_id: '', + url: 'https://api.github.com/users/AntiPontifex', + html_url: 'https://github.com/AntiPontifex', + followers_url: 'https://api.github.com/users/AntiPontifex/followers', + following_url: 'https://api.github.com/users/AntiPontifex/following{/other_user}', + gists_url: 'https://api.github.com/users/AntiPontifex/gists{/gist_id}', + starred_url: 'https://api.github.com/users/AntiPontifex/starred{/owner}{/repo}', + subscriptions_url: 'https://api.github.com/users/AntiPontifex/subscriptions', + organizations_url: 'https://api.github.com/users/AntiPontifex/orgs', + repos_url: 'https://api.github.com/users/AntiPontifex/repos', + events_url: 'https://api.github.com/users/AntiPontifex/events{/privacy}', + received_events_url: 'https://api.github.com/users/AntiPontifex/received_events', + type: 'User', + site_admin: false + }, + labels: [ + { + id: 5303575699, + node_id: 'LA_kwDOG1Kwp88AAAABPB4kkw', + url: 'https://api.github.com/repos/iptv-org/database/labels/channels:add', + name: 'channels:add', + color: '017ff8', + default: false, + description: 'Request to add a channel into the database' + }, + { + id: 5366738347, + node_id: 'LA_kwDOG1Kwp88AAAABP-Htqw', + url: 'https://api.github.com/repos/iptv-org/database/labels/approved', + name: 'approved', + color: '85DDDE', + default: false, + description: '' + } + ], + state: 'open', + locked: false, + assignee: null, + assignees: [], + milestone: null, + comments: 0, + created_at: '2023-10-06T02:10:41Z', + updated_at: '2023-10-06T02:52:02Z', + closed_at: null, + author_association: 'CONTRIBUTOR', + active_lock_reason: null, + body: '### Channel Name\n\nYiwu News Integrated Channel\n\n### Alternative Names (optional)\n\n_No response_\n\n### Network (optional)\n\n_No response_\n\n### Owners (optional)\n\n_No response_\n\n### Country\n\nCN\n\n### Subdivision (optional)\n\n_No response_\n\n### City (optional)\n\n_No response_\n\n### Categories (optional)\n\nnews\n\n### NSFW\n\nFALSE\n\n### Website (optional)\n\n_No response_\n\n### Logo\n\nhttps://www.tvchinese.net/uploads/tv/yiwutv.jpg\n\n### Feed Name\n\nSD\n\n### Broadcast Area\n\nc/CN\n\n### Languages\n\nzho\n\n### Timezones\n\nAfrica/Johannesburg;Africa/Kigali\n\n### Format\n\n576i\n\n### Launched (optional)\n\n_No response_\n\n### Closed (optional)\n\n_No response_\n\n### Replaced By (optional)\n\n_No response_\n\n### Notes\n\n_No response_', + reactions: { + url: 'https://api.github.com/repos/iptv-org/database/issues/5900/reactions', + total_count: 0, + '+1': 0, + '-1': 0, + laugh: 0, + hooray: 0, + confused: 0, + heart: 0, + rocket: 0, + eyes: 0 + }, + timeline_url: 'https://api.github.com/repos/iptv-org/database/issues/5900/timeline', + performed_via_github_app: null, + state_reason: null + }, + { + url: 'https://api.github.com/repos/iptv-org/database/issues/5899', + repository_url: 'https://api.github.com/repos/iptv-org/database', + labels_url: 'https://api.github.com/repos/iptv-org/database/issues/5899/labels{/name}', + comments_url: 'https://api.github.com/repos/iptv-org/database/issues/5899/comments', + events_url: 'https://api.github.com/repos/iptv-org/database/issues/5899/events', + html_url: 'https://github.com/iptv-org/database/issues/5899', + id: 1929318573, + node_id: 'I_kwDOG1Kwp85y_xCt', + number: 5899, + title: 'Add: Yiwu Business Channel', + user: { + login: 'AntiPontifex', + id: 81566772, + node_id: 'MDQ6VXNlcjgxNTY2Nzcy', + avatar_url: 'https://avatars.githubusercontent.com/u/81566772?v=4', + gravatar_id: '', + url: 'https://api.github.com/users/AntiPontifex', + html_url: 'https://github.com/AntiPontifex', + followers_url: 'https://api.github.com/users/AntiPontifex/followers', + following_url: 'https://api.github.com/users/AntiPontifex/following{/other_user}', + gists_url: 'https://api.github.com/users/AntiPontifex/gists{/gist_id}', + starred_url: 'https://api.github.com/users/AntiPontifex/starred{/owner}{/repo}', + subscriptions_url: 'https://api.github.com/users/AntiPontifex/subscriptions', + organizations_url: 'https://api.github.com/users/AntiPontifex/orgs', + repos_url: 'https://api.github.com/users/AntiPontifex/repos', + events_url: 'https://api.github.com/users/AntiPontifex/events{/privacy}', + received_events_url: 'https://api.github.com/users/AntiPontifex/received_events', + type: 'User', + site_admin: false + }, + labels: [ + { + id: 5303575699, + node_id: 'LA_kwDOG1Kwp88AAAABPB4kkw', + url: 'https://api.github.com/repos/iptv-org/database/labels/channels:add', + name: 'channels:add', + color: '017ff8', + default: false, + description: 'Request to add a channel into the database' + }, + { + id: 5366738347, + node_id: 'LA_kwDOG1Kwp88AAAABP-Htqw', + url: 'https://api.github.com/repos/iptv-org/database/labels/approved', + name: 'approved', + color: '85DDDE', + default: false, + description: '' + } + ], + state: 'open', + locked: false, + assignee: null, + assignees: [], + milestone: null, + comments: 0, + created_at: '2023-10-06T02:05:11Z', + updated_at: '2023-10-06T02:51:46Z', + closed_at: null, + author_association: 'CONTRIBUTOR', + active_lock_reason: null, + body: '### Channel Name\n\nYiwu Business Channel\n\n### Alternative Names (optional)\n\n_No response_\n\n### Network (optional)\n\n_No response_\n\n### Owners (optional)\n\n_No response_\n\n### Country\n\nCN\n\n### Subdivision (optional)\n\n_No response_\n\n### City (optional)\n\n_No response_\n\n### Categories (optional)\n\nbusiness\n\n### NSFW\n\nFALSE\n\n### Website (optional)\n\n_No response_\n\n### Logo\n\nhttps://www.tvchinese.net/uploads/tv/yiwutv.jpg\n\n### Feed Name\n\nSD\n\n### Broadcast Area\n\nc/CN\n\n### Languages\n\nzho\n\n### Timezones\n\nAfrica/Johannesburg;Africa/Kigali\n\n### Format\n\n576i\n\n### Launched (optional)\n\n_No response_\n\n### Closed (optional)\n\n_No response_\n\n### Replaced By (optional)\n\n_No response_\n\n### Notes\n\n_No response_', + reactions: { + url: 'https://api.github.com/repos/iptv-org/database/issues/5899/reactions', + total_count: 0, + '+1': 0, + '-1': 0, + laugh: 0, + hooray: 0, + confused: 0, + heart: 0, + rocket: 0, + eyes: 0 + }, + timeline_url: 'https://api.github.com/repos/iptv-org/database/issues/5899/timeline', + performed_via_github_app: null, + state_reason: null + }, + { + url: 'https://api.github.com/repos/iptv-org/database/issues/5898', + repository_url: 'https://api.github.com/repos/iptv-org/database', + labels_url: 'https://api.github.com/repos/iptv-org/database/issues/5898/labels{/name}', + comments_url: 'https://api.github.com/repos/iptv-org/database/issues/5898/comments', + events_url: 'https://api.github.com/repos/iptv-org/database/issues/5898/events', + html_url: 'https://github.com/iptv-org/database/issues/5898', + id: 1929313117, + node_id: 'I_kwDOG1Kwp85y_vtd', + number: 5898, + title: 'Add: Wenzhou Economic and Education', + user: { + login: 'AntiPontifex', + id: 81566772, + node_id: 'MDQ6VXNlcjgxNTY2Nzcy', + avatar_url: 'https://avatars.githubusercontent.com/u/81566772?v=4', + gravatar_id: '', + url: 'https://api.github.com/users/AntiPontifex', + html_url: 'https://github.com/AntiPontifex', + followers_url: 'https://api.github.com/users/AntiPontifex/followers', + following_url: 'https://api.github.com/users/AntiPontifex/following{/other_user}', + gists_url: 'https://api.github.com/users/AntiPontifex/gists{/gist_id}', + starred_url: 'https://api.github.com/users/AntiPontifex/starred{/owner}{/repo}', + subscriptions_url: 'https://api.github.com/users/AntiPontifex/subscriptions', + organizations_url: 'https://api.github.com/users/AntiPontifex/orgs', + repos_url: 'https://api.github.com/users/AntiPontifex/repos', + events_url: 'https://api.github.com/users/AntiPontifex/events{/privacy}', + received_events_url: 'https://api.github.com/users/AntiPontifex/received_events', + type: 'User', + site_admin: false + }, + labels: [ + { + id: 5303575699, + node_id: 'LA_kwDOG1Kwp88AAAABPB4kkw', + url: 'https://api.github.com/repos/iptv-org/database/labels/channels:add', + name: 'channels:add', + color: '017ff8', + default: false, + description: 'Request to add a channel into the database' + }, + { + id: 5366738347, + node_id: 'LA_kwDOG1Kwp88AAAABP-Htqw', + url: 'https://api.github.com/repos/iptv-org/database/labels/approved', + name: 'approved', + color: '85DDDE', + default: false, + description: '' + } + ], + state: 'open', + locked: false, + assignee: null, + assignees: [], + milestone: null, + comments: 0, + created_at: '2023-10-06T01:56:32Z', + updated_at: '2023-10-06T02:51:22Z', + closed_at: null, + author_association: 'CONTRIBUTOR', + active_lock_reason: null, + body: '### Channel Name\n\nWenzhou Economic and Education\n\n### Alternative Names (optional)\n\n_No response_\n\n### Network (optional)\n\n_No response_\n\n### Owners (optional)\n\n_No response_\n\n### Country\n\nCN\n\n### Subdivision (optional)\n\n_No response_\n\n### City (optional)\n\nWenzhou\n\n### Categories (optional)\n\nscience\n\n### NSFW\n\nFALSE\n\n### Website (optional)\n\n_No response_\n\n### Logo\n\nhttps://www.tvchinese.net/uploads/tv/wzjjkj.jpg\n\n### Feed Name\n\nSD\n\n### Broadcast Area\n\nc/CN\n\n### Languages\n\nzho\n\n### Timezones\n\nAfrica/Johannesburg;Africa/Kigali\n\n### Format\n\n576i\n\n### Launched (optional)\n\n_No response_\n\n### Closed (optional)\n\n_No response_\n\n### Replaced By (optional)\n\n_No response_\n\n### Notes\n\n_No response_', + reactions: { + url: 'https://api.github.com/repos/iptv-org/database/issues/5898/reactions', + total_count: 0, + '+1': 0, + '-1': 0, + laugh: 0, + hooray: 0, + confused: 0, + heart: 0, + rocket: 0, + eyes: 0 + }, + timeline_url: 'https://api.github.com/repos/iptv-org/database/issues/5898/timeline', + performed_via_github_app: null, + state_reason: null + }, + { + url: 'https://api.github.com/repos/iptv-org/database/issues/5901', + repository_url: 'https://api.github.com/repos/iptv-org/database', + labels_url: 'https://api.github.com/repos/iptv-org/database/issues/5901/labels{/name}', + comments_url: 'https://api.github.com/repos/iptv-org/database/issues/5901/comments', + events_url: 'https://api.github.com/repos/iptv-org/database/issues/5901/events', + html_url: 'https://github.com/iptv-org/database/issues/5901', + id: 1929459171, + node_id: 'I_kwDOG1Kwp85zATXj', + number: 5901, + title: 'Edit: M5', + user: { + login: 'freearhey', + id: 7253922, + node_id: 'MDQ6VXNlcjcyNTM5MjI=', + avatar_url: 'https://avatars.githubusercontent.com/u/7253922?v=4', + gravatar_id: '', + url: 'https://api.github.com/users/freearhey', + html_url: 'https://github.com/freearhey', + followers_url: 'https://api.github.com/users/freearhey/followers', + following_url: 'https://api.github.com/users/freearhey/following{/other_user}', + gists_url: 'https://api.github.com/users/freearhey/gists{/gist_id}', + starred_url: 'https://api.github.com/users/freearhey/starred{/owner}{/repo}', + subscriptions_url: 'https://api.github.com/users/freearhey/subscriptions', + organizations_url: 'https://api.github.com/users/freearhey/orgs', + repos_url: 'https://api.github.com/users/freearhey/repos', + events_url: 'https://api.github.com/users/freearhey/events{/privacy}', + received_events_url: 'https://api.github.com/users/freearhey/received_events', + type: 'User', + site_admin: false + }, + labels: [ + { + id: 5303574335, + node_id: 'LA_kwDOG1Kwp88AAAABPB4fPw', + url: 'https://api.github.com/repos/iptv-org/database/labels/channels:edit', + name: 'channels:edit', + color: 'E12977', + default: false, + description: 'Request to edit channel description' + }, + { + id: 5366738347, + node_id: 'LA_kwDOG1Kwp88AAAABP-Htqw', + url: 'https://api.github.com/repos/iptv-org/database/labels/approved', + name: 'approved', + color: '85DDDE', + default: false, + description: '' + } + ], + state: 'open', + locked: false, + assignee: null, + assignees: [], + milestone: null, + comments: 0, + created_at: '2023-10-06T05:25:44Z', + updated_at: '2023-10-06T05:25:44Z', + closed_at: null, + author_association: 'CONTRIBUTOR', + active_lock_reason: null, + body: '### Channel ID (required)\n\nM5.hu\n\n### Channel Name\n\n_No response_\n\n### Alternative Names\n\n_No response_\n\n### Network\n\n_No response_\n\n### Owners\n\nDuna Médiaszolgáltató Nonprofit Zrt.\n\n### Country\n\n_No response_\n\n### Subdivision\n\n_No response_\n\n### City\n\n_No response_\n\n### Broadcast Area\n\n_No response_\n\n### Languages\n\n_No response_\n\n### Categories\n\n~\n\n### NSFW\n\nNone\n\n### Launched\n\n_No response_\n\n### Closed\n\n~\n\n### Replaced By\n\n_No response_\n\n### Website\n\n_No response_\n\n### Logo\n\n_No response_\n\n### Notes\n\n_No response_', + reactions: { + url: 'https://api.github.com/repos/iptv-org/database/issues/5901/reactions', + total_count: 0, + '+1': 0, + '-1': 0, + laugh: 0, + hooray: 0, + confused: 0, + heart: 0, + rocket: 0, + eyes: 0 + }, + timeline_url: 'https://api.github.com/repos/iptv-org/database/issues/5901/timeline', + performed_via_github_app: null, + state_reason: null + }, + { + url: 'https://api.github.com/repos/iptv-org/database/issues/5701', + repository_url: 'https://api.github.com/repos/iptv-org/database', + labels_url: 'https://api.github.com/repos/iptv-org/database/issues/5701/labels{/name}', + comments_url: 'https://api.github.com/repos/iptv-org/database/issues/5701/comments', + events_url: 'https://api.github.com/repos/iptv-org/database/issues/5701/events', + html_url: 'https://github.com/iptv-org/database/issues/5701', + id: 1929459171, + node_id: 'I_kwDOG1Kwp85zATXj', + number: 5701, + title: 'Edit: M5', + user: { + login: 'freearhey', + id: 7253922, + node_id: 'MDQ6VXNlcjcyNTM5MjI=', + avatar_url: 'https://avatars.githubusercontent.com/u/7253922?v=4', + gravatar_id: '', + url: 'https://api.github.com/users/freearhey', + html_url: 'https://github.com/freearhey', + followers_url: 'https://api.github.com/users/freearhey/followers', + following_url: 'https://api.github.com/users/freearhey/following{/other_user}', + gists_url: 'https://api.github.com/users/freearhey/gists{/gist_id}', + starred_url: 'https://api.github.com/users/freearhey/starred{/owner}{/repo}', + subscriptions_url: 'https://api.github.com/users/freearhey/subscriptions', + organizations_url: 'https://api.github.com/users/freearhey/orgs', + repos_url: 'https://api.github.com/users/freearhey/repos', + events_url: 'https://api.github.com/users/freearhey/events{/privacy}', + received_events_url: 'https://api.github.com/users/freearhey/received_events', + type: 'User', + site_admin: false + }, + labels: [ + { + id: 5303574335, + node_id: 'LA_kwDOG1Kwp88AAAABPB4fPw', + url: 'https://api.github.com/repos/iptv-org/database/labels/channels:edit', + name: 'channels:edit', + color: 'E12977', + default: false, + description: 'Request to edit channel description' + }, + { + id: 5366738347, + node_id: 'LA_kwDOG1Kwp88AAAABP-Htqw', + url: 'https://api.github.com/repos/iptv-org/database/labels/approved', + name: 'approved', + color: '85DDDE', + default: false, + description: '' + } + ], + state: 'open', + locked: false, + assignee: null, + assignees: [], + milestone: null, + comments: 0, + created_at: '2023-10-06T05:25:44Z', + updated_at: '2023-10-06T05:25:44Z', + closed_at: null, + author_association: 'CONTRIBUTOR', + active_lock_reason: null, + body: '### Channel ID (required)\n\nBeijingSatelliteTV.cn\n\n### Channel Name\n\nbeIN Movies Turk\n\n### Alternative Names\n\nbeIN Movies Türk\n\n### Network\n\nBBC\n\n### Owners\n\nGazprom Media\n\n### Country\n\nTR\n\n### Subdivision\n\nUS-CA\n\n### City\n\nLondon\n\n### Broadcast Area\n\nc/TR\n\n### Languages\n\ntur\n\n### Categories\n\nmovies\n\n### NSFW\nTRUE\n\n### Launched\n\n1979-05-16\n\n### Closed\n\n1980-05-16\n\n### Replaced By\n\nM5.hu\n\n### Website\n\nhttp://www.digiturk.com.tr/\n\n### Logo\n\nhttps://i.imgur.com/nw8Sa2z.png\n\n### Notes\n\n_No response_', + reactions: { + url: 'https://api.github.com/repos/iptv-org/database/issues/5701/reactions', + total_count: 0, + '+1': 0, + '-1': 0, + laugh: 0, + hooray: 0, + confused: 0, + heart: 0, + rocket: 0, + eyes: 0 + }, + timeline_url: 'https://api.github.com/repos/iptv-org/database/issues/5701/timeline', + performed_via_github_app: null, + state_reason: null + }, + { + url: 'https://api.github.com/repos/iptv-org/database/issues/5871', + repository_url: 'https://api.github.com/repos/iptv-org/database', + labels_url: 'https://api.github.com/repos/iptv-org/database/issues/5871/labels{/name}', + comments_url: 'https://api.github.com/repos/iptv-org/database/issues/5871/comments', + events_url: 'https://api.github.com/repos/iptv-org/database/issues/5871/events', + html_url: 'https://github.com/iptv-org/database/issues/5871', + id: 1929261634, + node_id: 'I_kwDOG1Kwp85y_jJC', + number: 5871, + title: 'Remove: 002 Radio TV', + user: { + login: 'freearhey', + id: 7253922, + node_id: 'MDQ6VXNlcjcyNTM5MjI=', + avatar_url: 'https://avatars.githubusercontent.com/u/7253922?v=4', + gravatar_id: '', + url: 'https://api.github.com/users/freearhey', + html_url: 'https://github.com/freearhey', + followers_url: 'https://api.github.com/users/freearhey/followers', + following_url: 'https://api.github.com/users/freearhey/following{/other_user}', + gists_url: 'https://api.github.com/users/freearhey/gists{/gist_id}', + starred_url: 'https://api.github.com/users/freearhey/starred{/owner}{/repo}', + subscriptions_url: 'https://api.github.com/users/freearhey/subscriptions', + organizations_url: 'https://api.github.com/users/freearhey/orgs', + repos_url: 'https://api.github.com/users/freearhey/repos', + events_url: 'https://api.github.com/users/freearhey/events{/privacy}', + received_events_url: 'https://api.github.com/users/freearhey/received_events', + type: 'User', + site_admin: false + }, + labels: [ + { + id: 5366738347, + node_id: 'LA_kwDOG1Kwp88AAAABP-Htqw', + url: 'https://api.github.com/repos/iptv-org/database/labels/approved', + name: 'approved', + color: '85DDDE', + default: false, + description: '' + }, + { + id: 6049155772, + node_id: 'LA_kwDOG1Kwp88AAAABaI7KvA', + url: 'https://api.github.com/repos/iptv-org/database/labels/blocklist:add', + name: 'channels:remove', + color: 'e99695', + default: false, + description: 'Request to remove a channel' + } + ], + state: 'open', + locked: false, + assignee: null, + assignees: [], + milestone: null, + comments: 0, + created_at: '2023-10-06T00:35:32Z', + updated_at: '2023-10-06T00:35:32Z', + closed_at: null, + author_association: 'CONTRIBUTOR', + active_lock_reason: null, + body: '### Channel ID\n\n002RadioTV.do\n\n### Reason\n\nOther\n\n### Notes (optional)\n\n_No response_', + reactions: { + url: 'https://api.github.com/repos/iptv-org/database/issues/5871/reactions', + total_count: 0, + '+1': 0, + '-1': 0, + laugh: 0, + hooray: 0, + confused: 0, + heart: 0, + rocket: 0, + eyes: 0 + }, + timeline_url: 'https://api.github.com/repos/iptv-org/database/issues/5871/timeline', + performed_via_github_app: null, + state_reason: null + }, + { + url: 'https://api.github.com/repos/iptv-org/database/issues/8900', + repository_url: 'https://api.github.com/repos/iptv-org/database', + labels_url: 'https://api.github.com/repos/iptv-org/database/issues/8900/labels{/name}', + comments_url: 'https://api.github.com/repos/iptv-org/database/issues/8900/comments', + events_url: 'https://api.github.com/repos/iptv-org/database/issues/8900/events', + html_url: 'https://github.com/iptv-org/database/issues/8900', + id: 2129321995, + node_id: 'I_kwDOG1Kwp85y_x4L', + number: 8900, + title: 'Add: Yiwu News Integrated Channel', + user: { + login: 'AntiPontifex', + id: 81566772, + node_id: 'MDQ6VXNlcjgxNTY2Nzcy', + avatar_url: 'https://avatars.githubusercontent.com/u/81566772?v=4', + gravatar_id: '', + url: 'https://api.github.com/users/AntiPontifex', + html_url: 'https://github.com/AntiPontifex', + followers_url: 'https://api.github.com/users/AntiPontifex/followers', + following_url: 'https://api.github.com/users/AntiPontifex/following{/other_user}', + gists_url: 'https://api.github.com/users/AntiPontifex/gists{/gist_id}', + starred_url: 'https://api.github.com/users/AntiPontifex/starred{/owner}{/repo}', + subscriptions_url: 'https://api.github.com/users/AntiPontifex/subscriptions', + organizations_url: 'https://api.github.com/users/AntiPontifex/orgs', + repos_url: 'https://api.github.com/users/AntiPontifex/repos', + events_url: 'https://api.github.com/users/AntiPontifex/events{/privacy}', + received_events_url: 'https://api.github.com/users/AntiPontifex/received_events', + type: 'User', + site_admin: false + }, + labels: [ + { + id: 5303575699, + node_id: 'LA_kwDOG1Kwp88AAAABPB4kkw', + url: 'https://api.github.com/repos/iptv-org/database/labels/channels:add', + name: 'feeds:add', + color: '017ff8', + default: false, + description: 'Request to add a channel into the database' + }, + { + id: 5366738347, + node_id: 'LA_kwDOG1Kwp88AAAABP-Htqw', + url: 'https://api.github.com/repos/iptv-org/database/labels/approved', + name: 'approved', + color: '85DDDE', + default: false, + description: '' + } + ], + state: 'open', + locked: false, + assignee: null, + assignees: [], + milestone: null, + comments: 0, + created_at: '2023-10-06T02:10:41Z', + updated_at: '2023-10-06T02:52:02Z', + closed_at: null, + author_association: 'CONTRIBUTOR', + active_lock_reason: null, + body: '### Channel ID\n\n1000xHoraTV.uy\n\n### Feed Name\n\nHD\n\n### Main Feed\n\nTRUE\n\n### Broadcast Area\n\nc/CN\n\n### Languages\n\nzho\n\n### Timezones\n\nAfrica/Johannesburg;Africa/Kigali\n\n### Format\n\n576i\n\n### Launched (optional)\n\n2020-01-01\n\n### Closed (optional)\n\n2021-01-01\n\n### Replaced By (optional)\n\nM5.hu@HD\n\n### Notes\n\n_No response_', + reactions: { + url: 'https://api.github.com/repos/iptv-org/database/issues/8900/reactions', + total_count: 0, + '+1': 0, + '-1': 0, + laugh: 0, + hooray: 0, + confused: 0, + heart: 0, + rocket: 0, + eyes: 0 + }, + timeline_url: 'https://api.github.com/repos/iptv-org/database/issues/8900/timeline', + performed_via_github_app: null, + state_reason: null + }, + { + url: 'https://api.github.com/repos/iptv-org/database/issues/7901', + repository_url: 'https://api.github.com/repos/iptv-org/database', + labels_url: 'https://api.github.com/repos/iptv-org/database/issues/7901/labels{/name}', + comments_url: 'https://api.github.com/repos/iptv-org/database/issues/7901/comments', + events_url: 'https://api.github.com/repos/iptv-org/database/issues/7901/events', + html_url: 'https://github.com/iptv-org/database/issues/7901', + id: 2129459171, + node_id: 'I_kwDOG1Kwp85zATXj', + number: 7901, + title: 'Edit: M5@SD', + user: { + login: 'freearhey', + id: 7253922, + node_id: 'MDQ6VXNlcjcyNTM5MjI=', + avatar_url: 'https://avatars.githubusercontent.com/u/7253922?v=4', + gravatar_id: '', + url: 'https://api.github.com/users/freearhey', + html_url: 'https://github.com/freearhey', + followers_url: 'https://api.github.com/users/freearhey/followers', + following_url: 'https://api.github.com/users/freearhey/following{/other_user}', + gists_url: 'https://api.github.com/users/freearhey/gists{/gist_id}', + starred_url: 'https://api.github.com/users/freearhey/starred{/owner}{/repo}', + subscriptions_url: 'https://api.github.com/users/freearhey/subscriptions', + organizations_url: 'https://api.github.com/users/freearhey/orgs', + repos_url: 'https://api.github.com/users/freearhey/repos', + events_url: 'https://api.github.com/users/freearhey/events{/privacy}', + received_events_url: 'https://api.github.com/users/freearhey/received_events', + type: 'User', + site_admin: false + }, + labels: [ + { + id: 5303574335, + node_id: 'LA_kwDOG1Kwp88AAAABPB4fPw', + url: 'https://api.github.com/repos/iptv-org/database/labels/channels:edit', + name: 'feeds:edit', + color: 'E12977', + default: false, + description: 'Request to edit channel description' + }, + { + id: 5366738347, + node_id: 'LA_kwDOG1Kwp88AAAABP-Htqw', + url: 'https://api.github.com/repos/iptv-org/database/labels/approved', + name: 'approved', + color: '85DDDE', + default: false, + description: '' + } + ], + state: 'open', + locked: false, + assignee: null, + assignees: [], + milestone: null, + comments: 0, + created_at: '2023-10-06T05:25:44Z', + updated_at: '2023-10-06T05:25:44Z', + closed_at: null, + author_association: 'CONTRIBUTOR', + active_lock_reason: null, + body: '### Channel ID (required)\n\nM5.hu\n\n### Feed ID (required)\n\nSD\n\n### Feed Name\n\nHD\n\n### Main Feed\n\nTRUE\n\n### Broadcast Area\n\nc/BR\n\n### Timezones\n\nAfrica/Dakar;Africa/El_Aaiun\n\n### Languages\n\npor;spa\n\n### Format\n\n1080i\n\n### Launched\n\n2020-01-01\n\n### Closed\n\n~\n\n### Replaced By\n\n0TV.dk@SD\n\n### Notes\n\n_No response_', + reactions: { + url: 'https://api.github.com/repos/iptv-org/database/issues/7901/reactions', + total_count: 0, + '+1': 0, + '-1': 0, + laugh: 0, + hooray: 0, + confused: 0, + heart: 0, + rocket: 0, + eyes: 0 + }, + timeline_url: 'https://api.github.com/repos/iptv-org/database/issues/7901/timeline', + performed_via_github_app: null, + state_reason: null + }, + { + url: 'https://api.github.com/repos/iptv-org/database/issues/6871', + repository_url: 'https://api.github.com/repos/iptv-org/database', + labels_url: 'https://api.github.com/repos/iptv-org/database/issues/6871/labels{/name}', + comments_url: 'https://api.github.com/repos/iptv-org/database/issues/6871/comments', + events_url: 'https://api.github.com/repos/iptv-org/database/issues/6871/events', + html_url: 'https://github.com/iptv-org/database/issues/6871', + id: 2029261634, + node_id: 'I_kwDOG1Kwp85y_jJC', + number: 6871, + title: 'Remove: 01TV.fr@SD', + user: { + login: 'freearhey', + id: 7253922, + node_id: 'MDQ6VXNlcjcyNTM5MjI=', + avatar_url: 'https://avatars.githubusercontent.com/u/7253922?v=4', + gravatar_id: '', + url: 'https://api.github.com/users/freearhey', + html_url: 'https://github.com/freearhey', + followers_url: 'https://api.github.com/users/freearhey/followers', + following_url: 'https://api.github.com/users/freearhey/following{/other_user}', + gists_url: 'https://api.github.com/users/freearhey/gists{/gist_id}', + starred_url: 'https://api.github.com/users/freearhey/starred{/owner}{/repo}', + subscriptions_url: 'https://api.github.com/users/freearhey/subscriptions', + organizations_url: 'https://api.github.com/users/freearhey/orgs', + repos_url: 'https://api.github.com/users/freearhey/repos', + events_url: 'https://api.github.com/users/freearhey/events{/privacy}', + received_events_url: 'https://api.github.com/users/freearhey/received_events', + type: 'User', + site_admin: false + }, + labels: [ + { + id: 5366738347, + node_id: 'LA_kwDOG1Kwp88AAAABP-Htqw', + url: 'https://api.github.com/repos/iptv-org/database/labels/approved', + name: 'approved', + color: '85DDDE', + default: false, + description: '' + }, + { + id: 6049155772, + node_id: 'LA_kwDOG1Kwp88AAAABaI7KvA', + url: 'https://api.github.com/repos/iptv-org/database/labels/blocklist:add', + name: 'feeds:remove', + color: 'e99695', + default: false, + description: 'Request to remove a feed' + } + ], + state: 'open', + locked: false, + assignee: null, + assignees: [], + milestone: null, + comments: 0, + created_at: '2023-10-06T00:35:32Z', + updated_at: '2023-10-06T00:35:32Z', + closed_at: null, + author_association: 'CONTRIBUTOR', + active_lock_reason: null, + body: '### Channel ID\n\n01TV.fr\n\n### Feed ID\n\nSD\n\n### Reason\n\nOther\n\n### Notes (optional)\n\n_No response_', + reactions: { + url: 'https://api.github.com/repos/iptv-org/database/issues/6871/reactions', + total_count: 0, + '+1': 0, + '-1': 0, + laugh: 0, + hooray: 0, + confused: 0, + heart: 0, + rocket: 0, + eyes: 0 + }, + timeline_url: 'https://api.github.com/repos/iptv-org/database/issues/6871/timeline', + performed_via_github_app: null, + state_reason: null + } +] diff --git a/tests/__data__/input/validate/duplicate/feeds.csv b/tests/__data__/input/validate/duplicate/feeds.csv new file mode 100644 index 00000000..bf4567e7 --- /dev/null +++ b/tests/__data__/input/validate/duplicate/feeds.csv @@ -0,0 +1,3 @@ +channel,id,name,is_main,broadcast_area,timezones,languages,video_format,launched,closed,replaced_by +002RadioTV.do,SD,SD,TRUE,c/DO,America/Santo_Domingo,spa,480i,,, +002RadioTV.do,SD,HD,FALSE,c/DO,America/Santo_Domingo,spa,1080i,,, \ No newline at end of file diff --git a/tests/__data__/input/validate/duplicate/timezones.csv b/tests/__data__/input/validate/duplicate/timezones.csv new file mode 100644 index 00000000..5ebde14f --- /dev/null +++ b/tests/__data__/input/validate/duplicate/timezones.csv @@ -0,0 +1,2 @@ +id,utc_offset,countries +America/Santo_Domingo,-04:00,DO \ No newline at end of file diff --git a/tests/__data__/input/validate/invalid_value/channels.csv b/tests/__data__/input/validate/invalid_value/channels.csv index 80a8fa02..95ecacb7 100644 --- a/tests/__data__/input/validate/invalid_value/channels.csv +++ b/tests/__data__/input/validate/invalid_value/channels.csv @@ -1,2 +1,2 @@ id,name,alt_names,network,owners,country,subdivision,city,broadcast_area,languages,categories,is_nsfw,launched,closed,replaced_by,website,logo -002RadioTV.do,002 Radio TV,,,,DO,,,c/DO,spa,,FALSE,,,,ttps://www.002radio.com/,https://i.imgur.com/7oNe8xj.png \ No newline at end of file +002RadioTV.do,002 Radio TV,,,,DO,,,c/DO,spa,,FALSE,,,002RadioTV.do@4K,ttps://www.002radio.com/,https://i.imgur.com/7oNe8xj.png \ No newline at end of file diff --git a/tests/__data__/input/validate/invalid_value/feeds.csv b/tests/__data__/input/validate/invalid_value/feeds.csv new file mode 100644 index 00000000..8e25a69e --- /dev/null +++ b/tests/__data__/input/validate/invalid_value/feeds.csv @@ -0,0 +1,4 @@ +channel,id,name,is_main,broadcast_area,timezones,languages,video_format,launched,closed,replaced_by +0TV.dk,SD,SD,TRUE,c/DK,Europe/Copenhagen,dan,576I,,,M5.hu@HD +002RadioTV.do,SD,SD,TRUE,c/DK,Africa/Accra,dan,576i,,, +002RadioTV.do,HD,HD,TRUE,c/DK,Africa/Accra,dan,576i,,, \ No newline at end of file diff --git a/tests/__data__/input/validate/invalid_value/timezones.csv b/tests/__data__/input/validate/invalid_value/timezones.csv new file mode 100644 index 00000000..0ce74c35 --- /dev/null +++ b/tests/__data__/input/validate/invalid_value/timezones.csv @@ -0,0 +1,2 @@ +id,utc_offset,countries +Africa/Accra,+00:00,GH \ No newline at end of file diff --git a/tests/__data__/input/validate/valid_data/feeds.csv b/tests/__data__/input/validate/valid_data/feeds.csv new file mode 100644 index 00000000..476e3f00 --- /dev/null +++ b/tests/__data__/input/validate/valid_data/feeds.csv @@ -0,0 +1,5 @@ +channel,id,name,is_main,broadcast_area,timezones,languages,video_format,launched,closed,replaced_by +KSTVKids.ua,HD,HD,TRUE,c/UA,America/Santo_Domingo,ukr,480i,,, +PeoplesWeather.do,SD,SD,TRUE,c/DO,America/Santo_Domingo,spa,480i,,, +PeoplesWeather.do,HD,HD,FALSE,c/DO,America/Santo_Domingo,spa,1080i,,,KSTVKids.ua@HD +PeoplesWeather.do,West,West,FALSE,c/DO,America/Santo_Domingo,spa,1080i,,, \ No newline at end of file diff --git a/tests/__data__/input/validate/valid_data/timezones.csv b/tests/__data__/input/validate/valid_data/timezones.csv new file mode 100644 index 00000000..5ebde14f --- /dev/null +++ b/tests/__data__/input/validate/valid_data/timezones.csv @@ -0,0 +1,2 @@ +id,utc_offset,countries +America/Santo_Domingo,-04:00,DO \ No newline at end of file diff --git a/tests/db/export.test.ts b/tests/db/export.test.ts index e807de52..f7534dcd 100644 --- a/tests/db/export.test.ts +++ b/tests/db/export.test.ts @@ -7,7 +7,7 @@ beforeEach(() => { it('can export data as json', () => { execSync( - 'DATA_DIR=tests/__data__/input/data API_DIR=tests/__data__/output/api npm run db:export', + 'DATA_DIR=tests/__data__/input/export/data API_DIR=tests/__data__/output/api npm run db:export', { encoding: 'utf8' } @@ -15,6 +15,8 @@ it('can export data as json', () => { expect(content('output/api/blocklist.json')).toEqual(content('expected/api/blocklist.json')) expect(content('output/api/channels.json')).toEqual(content('expected/api/channels.json')) + expect(content('output/api/timezones.json')).toEqual(content('expected/api/timezones.json')) + expect(content('output/api/feeds.json')).toEqual(content('expected/api/feeds.json')) }) function content(filepath: string) { diff --git a/tests/db/update.test.ts b/tests/db/update.test.ts index 255bbaeb..11bdf72a 100644 --- a/tests/db/update.test.ts +++ b/tests/db/update.test.ts @@ -3,7 +3,7 @@ import * as fs from 'fs-extra' beforeEach(() => { fs.emptyDirSync('tests/__data__/output') - fs.copySync('tests/__data__/input/data', 'tests/__data__/output/data') + fs.copySync('tests/__data__/input/update/data', 'tests/__data__/output/data') }) it('can update db with data from issues', () => { @@ -13,8 +13,9 @@ it('can update db with data from issues', () => { expect(content('output/data/blocklist.csv')).toEqual(content('expected/data/blocklist.csv')) expect(content('output/data/channels.csv')).toEqual(content('expected/data/channels.csv')) + expect(content('output/data/feeds.csv')).toEqual(content('expected/data/feeds.csv')) expect(stdout).toEqual( - 'OUTPUT=closes #5871, closes #5901, closes #5701, closes #5900, closes #5899, closes #5898, closes #5897, closes #5891' + 'OUTPUT=closes #6871, closes #5871, closes #7901, closes #5901, closes #5701, closes #8900, closes #5900, closes #5899, closes #5898, closes #5897, closes #5891' ) }) diff --git a/tests/db/validate.test.ts b/tests/db/validate.test.ts index f60d3eda..7453fc50 100644 --- a/tests/db/validate.test.ts +++ b/tests/db/validate.test.ts @@ -46,10 +46,13 @@ describe('db:validate', () => { expect((error as ExecError).stdout).toContain( 'entry with the channel "002RadioTV.do" and ref "eee" already exists' ) + expect((error as ExecError).stdout).toContain( + 'entry with the channel "002RadioTV.do" and id "SD" already exists' + ) } }) - it('shows an error if an invalid value is specified', () => { + it('shows an error if the data contains an error', () => { try { execSync('DATA_DIR=tests/__data__/input/validate/invalid_value npm run db:validate', { encoding: 'utf8' @@ -57,13 +60,25 @@ describe('db:validate', () => { process.exit(1) } catch (error) { expect((error as ExecError).status).toBe(1) + expect((error as ExecError).stdout).toContain('"aaa.us" is missing in the channels.csv') expect((error as ExecError).stdout).toContain( - '2 "aaa.us" is missing in the channels.csv' + '"002RadioTV.do" has an invalid replaced_by "002RadioTV.do@4K"' ) expect((error as ExecError).stdout).toContain( - '2 002RadioTV.do: "website" must be a valid uri with a scheme matching the http|https pattern' + '002RadioTV.do: "website" must be a valid uri with a scheme matching the http|https pattern' ) - expect((error as ExecError).stdout).toContain('2 error(s)') + expect((error as ExecError).stdout).toContain( + 'entry with the channel "002RadioTV.do" and is_main "true" already exists' + ) + expect((error as ExecError).stdout).toContain('"0TV.dk" is missing in the channels.csv') + expect((error as ExecError).stdout).toContain('"SD" has an invalid replaced_by "M5.hu@HD"') + expect((error as ExecError).stdout).toContain( + '"0TV.dk@SD" has the wrong timezone "Europe/Copenhagen"' + ) + expect((error as ExecError).stdout).toContain( + 'SD: "video_format" with value "576I" fails to match the required pattern' + ) + expect((error as ExecError).stdout).toContain('8 error(s)') } }) diff --git a/yarn.lock b/yarn.lock index 4d2c1598..d8bdb3c5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -15,13 +15,14 @@ "@jridgewell/gen-mapping" "^0.3.0" "@jridgewell/trace-mapping" "^0.3.9" -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.22.13", "@babel/code-frame@^7.23.5": - version "7.23.5" - resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz" - integrity sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA== +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.22.13", "@babel/code-frame@^7.23.5", "@babel/code-frame@^7.26.2": + version "7.26.2" + resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz" + integrity sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ== dependencies: - "@babel/highlight" "^7.23.4" - chalk "^2.4.2" + "@babel/helper-validator-identifier" "^7.25.9" + js-tokens "^4.0.0" + picocolors "^1.0.0" "@babel/compat-data@^7.22.9": version "7.22.20" @@ -127,15 +128,15 @@ dependencies: "@babel/types" "^7.22.5" -"@babel/helper-string-parser@^7.23.4": - version "7.23.4" - resolved "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz" - integrity sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ== +"@babel/helper-string-parser@^7.25.9": + version "7.25.9" + resolved "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz" + integrity sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA== -"@babel/helper-validator-identifier@^7.22.20": - version "7.22.20" - resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz" - integrity sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A== +"@babel/helper-validator-identifier@^7.22.20", "@babel/helper-validator-identifier@^7.25.9": + version "7.25.9" + resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz" + integrity sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ== "@babel/helper-validator-option@^7.22.15": version "7.22.15" @@ -143,27 +144,19 @@ integrity sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA== "@babel/helpers@^7.23.0": - version "7.23.1" - resolved "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.1.tgz" - integrity sha512-chNpneuK18yW5Oxsr+t553UZzzAs3aZnFm4bxhebsNTeshrC95yA7l5yl7GBAG+JG1rF0F7zzD2EixK9mWSDoA== + version "7.26.10" + resolved "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.10.tgz" + integrity sha512-UPYc3SauzZ3JGgj87GgZ89JVdC5dj0AoetR5Bw6wj4niittNyFh6+eOGonYvJ1ao6B8lEa3Q3klS7ADZ53bc5g== dependencies: - "@babel/template" "^7.22.15" - "@babel/traverse" "^7.23.0" - "@babel/types" "^7.23.0" + "@babel/template" "^7.26.9" + "@babel/types" "^7.26.10" -"@babel/highlight@^7.23.4": - version "7.23.4" - resolved "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz" - integrity sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A== +"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.23.0", "@babel/parser@^7.23.5", "@babel/parser@^7.26.9": + version "7.26.10" + resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.26.10.tgz" + integrity sha512-6aQR2zGE/QFi8JpDLjUZEPYOs7+mhKXm86VaKFiLP35JQwQb6bwUE+XbvkH0EptsYhbNBSUGaUBLKqxH1xSgsA== dependencies: - "@babel/helper-validator-identifier" "^7.22.20" - chalk "^2.4.2" - js-tokens "^4.0.0" - -"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.22.15", "@babel/parser@^7.23.0", "@babel/parser@^7.23.5": - version "7.23.5" - resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.23.5.tgz" - integrity sha512-hOOqoiNXrmGdFbhgCzu6GiURxUgM27Xwd/aPuu8RfHEZPBzL1Z54okAHAQjXfcQNwvrlkAmAp4SlRTZ45vlthQ== + "@babel/types" "^7.26.10" "@babel/plugin-syntax-async-generators@^7.8.4": version "7.8.4" @@ -263,14 +256,14 @@ dependencies: "@babel/helper-plugin-utils" "^7.22.5" -"@babel/template@^7.22.15", "@babel/template@^7.3.3": - version "7.22.15" - resolved "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz" - integrity sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w== +"@babel/template@^7.22.15", "@babel/template@^7.26.9", "@babel/template@^7.3.3": + version "7.26.9" + resolved "https://registry.npmjs.org/@babel/template/-/template-7.26.9.tgz" + integrity sha512-qyRplbeIpNZhmzOysF/wFMuP9sctmh2cFzRAZOn1YapxBsE1i9bJIY586R/WBLfLcmcBlM8ROBiQURnnNy+zfA== dependencies: - "@babel/code-frame" "^7.22.13" - "@babel/parser" "^7.22.15" - "@babel/types" "^7.22.15" + "@babel/code-frame" "^7.26.2" + "@babel/parser" "^7.26.9" + "@babel/types" "^7.26.9" "@babel/traverse@^7.23.0": version "7.23.5" @@ -288,14 +281,13 @@ debug "^4.1.0" globals "^11.1.0" -"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.22.15", "@babel/types@^7.22.5", "@babel/types@^7.23.0", "@babel/types@^7.23.5", "@babel/types@^7.3.3": - version "7.23.5" - resolved "https://registry.npmjs.org/@babel/types/-/types-7.23.5.tgz" - integrity sha512-ON5kSOJwVO6xXVRTvOI0eOnWe7VdUcIpsovGo9U/Br4Ie4UVFQTboO2cYnDhAGU6Fp+UxSiT+pMft0SMHfuq6w== +"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.22.15", "@babel/types@^7.22.5", "@babel/types@^7.23.0", "@babel/types@^7.23.5", "@babel/types@^7.26.10", "@babel/types@^7.26.9", "@babel/types@^7.3.3": + version "7.26.10" + resolved "https://registry.npmjs.org/@babel/types/-/types-7.26.10.tgz" + integrity sha512-emqcG3vHrpxUKTrxcblR36dcrcoRDvKmnL/dCL6ZsHaShW80qxCAcNhzQZrpeM765VzEos+xOi4s+r4IXzTwdQ== dependencies: - "@babel/helper-string-parser" "^7.23.4" - "@babel/helper-validator-identifier" "^7.22.20" - to-fast-properties "^2.0.0" + "@babel/helper-string-parser" "^7.25.9" + "@babel/helper-validator-identifier" "^7.25.9" "@bcoe/v8-coverage@^0.2.3": version "0.2.3" @@ -309,10 +301,10 @@ dependencies: "@jridgewell/trace-mapping" "0.3.9" -"@esbuild/darwin-x64@0.23.1": - version "0.23.1" - resolved "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.23.1.tgz" - integrity sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw== +"@esbuild/darwin-x64@0.25.1": + version "0.25.1" + resolved "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.1.tgz" + integrity sha512-hxVnwL2Dqs3fM1IWq8Iezh0cX7ZGdVhbTfnOy5uURtao5OIVCEyj9xIzemDi7sRvKsuSdtCAhMKarxqtlyVyfA== "@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0": version "4.4.0" @@ -375,10 +367,10 @@ "@eslint/core" "^0.10.0" levn "^0.4.1" -"@freearhey/core@^0.2.2": - version "0.2.2" - resolved "https://registry.npmjs.org/@freearhey/core/-/core-0.2.2.tgz" - integrity sha512-8eikSh+alXohY/0Qv8lls+6BG738vOqxGuLvMjwBasbwuz8S/Abr7fUAH65dGjPAsB3HMaDhjK5c6kcVz5GrcA== +"@freearhey/core@^0.6.0": + version "0.6.0" + resolved "https://registry.npmjs.org/@freearhey/core/-/core-0.6.0.tgz" + integrity sha512-RuMQPQhduhWbPx8raB8Nlr8FLd65HLhQxpKSRvnrVzQWw2lDZ9pJ3ANkYOOdwKy7gDZ63WDhF3lwMTJwnwWiSw== dependencies: "@types/fs-extra" "^11.0.2" "@types/lodash" "^4.14.198" @@ -391,6 +383,7 @@ node-gzip "^1.1.2" normalize-url "^6.1.0" object-treeify "^2.1.1" + run-script-os "^1.1.6" signale "^1.4.0" "@hapi/hoek@^9.0.0", "@hapi/hoek@^9.3.0": @@ -757,9 +750,9 @@ "@octokit/types" "^9.0.0" "@octokit/core@^4.2.0", "@octokit/core@>=3", "@octokit/core@>=4": - version "4.2.0" - resolved "https://registry.npmjs.org/@octokit/core/-/core-4.2.0.tgz" - integrity sha512-AgvDRUg3COpR82P7PBdGZF/NNqGmtMq2NiPqeSsDIeCfYFOZ9gddqWNQHnFdEUf+YwOj4aZYmJnlPp7OXmDIDg== + version "4.2.4" + resolved "https://registry.npmjs.org/@octokit/core/-/core-4.2.4.tgz" + integrity sha512-rYKilwgzQ7/imScn3M9/pFfUf4I1AZEH3KhyJmtPdE2zfaXAn2mFfUy4FbKewzc2We5y/LlKLj36fWJLKC2SIQ== dependencies: "@octokit/auth-token" "^3.0.0" "@octokit/graphql" "^5.0.0" @@ -779,9 +772,9 @@ universal-user-agent "^6.0.0" "@octokit/graphql@^5.0.0": - version "5.0.5" - resolved "https://registry.npmjs.org/@octokit/graphql/-/graphql-5.0.5.tgz" - integrity sha512-Qwfvh3xdqKtIznjX9lz2D458r7dJPP8l6r4GQkIdWQouZwHQK0mVT88uwiU2bdTU2OtT1uOlKpRciUWldpG0yQ== + version "5.0.6" + resolved "https://registry.npmjs.org/@octokit/graphql/-/graphql-5.0.6.tgz" + integrity sha512-Fxyxdy/JH0MnIB5h+UQ3yCoh1FG4kWXfFKkpWqjZHw/p+Kc8Y44Hu/kCgNBT6nU1shNumEchmW/sUO1JuQnPcw== dependencies: "@octokit/request" "^6.0.0" "@octokit/types" "^9.0.0" @@ -793,11 +786,12 @@ integrity sha512-VRaeH8nCDtF5aXWnjPuEMIYf1itK/s3JYyJcWFJT8X9pSNnBtriDf7wlEWsGuhPLl4QIH4xM8fqTXDwJ3Mu6sw== "@octokit/plugin-paginate-rest@^6.0.0": - version "6.0.0" - resolved "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-6.0.0.tgz" - integrity sha512-Sq5VU1PfT6/JyuXPyt04KZNVsFOSBaYOAq2QRZUwzVlI10KFvcbUo8lR258AAQL1Et60b0WuVik+zOWKLuDZxw== + version "6.1.2" + resolved "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-6.1.2.tgz" + integrity sha512-qhrmtQeHU/IivxucOV1bbI/xZyC/iOBhclokv7Sut5vnejAIAEXVcGQeRpQlU39E0WwK9lNvJHphHri/DB6lbQ== dependencies: - "@octokit/types" "^9.0.0" + "@octokit/tsconfig" "^1.0.2" + "@octokit/types" "^9.2.3" "@octokit/plugin-rest-endpoint-methods@^7.1.3": version "7.1.3" @@ -816,9 +810,9 @@ once "^1.4.0" "@octokit/request@^6.0.0": - version "6.2.3" - resolved "https://registry.npmjs.org/@octokit/request/-/request-6.2.3.tgz" - integrity sha512-TNAodj5yNzrrZ/VxP+H5HiYaZep0H3GU0O7PaF+fhDrt8FPrnkei9Aal/txsN/1P7V3CPiThG0tIvpPDYUsyAA== + version "6.2.8" + resolved "https://registry.npmjs.org/@octokit/request/-/request-6.2.8.tgz" + integrity sha512-ow4+pkVQ+6XVVsekSYBzJC0VTVvh/FCTUUgTsboGq+DTeWdyIFV8WSCdo0RIxk6wSkBTHqIK1mYuY7nOBXOchw== dependencies: "@octokit/endpoint" "^7.0.0" "@octokit/request-error" "^3.0.0" @@ -827,6 +821,11 @@ node-fetch "^2.6.7" universal-user-agent "^6.0.0" +"@octokit/tsconfig@^1.0.2": + version "1.0.2" + resolved "https://registry.npmjs.org/@octokit/tsconfig/-/tsconfig-1.0.2.tgz" + integrity sha512-I0vDR0rdtP8p2lGMzvsJzbhdOWy405HcGovrspJ8RRibHnyRgggUSNO5AIox5LmqiwmatHKYsvj6VGFHkqS7lA== + "@octokit/types@^9.0.0", "@octokit/types@^9.2.3": version "9.3.2" resolved "https://registry.npmjs.org/@octokit/types/-/types-9.3.2.tgz" @@ -1358,15 +1357,6 @@ chalk@^2.3.2: escape-string-regexp "^1.0.5" supports-color "^5.3.0" -chalk@^2.4.2: - version "2.4.2" - resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz" - integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - chalk@^4.0.0, chalk@^4.1.2: version "4.1.2" resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" @@ -1431,7 +1421,7 @@ color-name@~1.1.4: color-name@1.1.3: version "1.1.3" resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz" - integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= commander@^9.0.0: version "9.0.0" @@ -1576,35 +1566,36 @@ error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" -esbuild@~0.23.0: - version "0.23.1" - resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.23.1.tgz" - integrity sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg== +esbuild@~0.25.0: + version "0.25.1" + resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.25.1.tgz" + integrity sha512-BGO5LtrGC7vxnqucAe/rmvKdJllfGaYWdyABvyMoXQlfYMb2bbRuReWR5tEGE//4LcNJj9XrkovTqNYRFZHAMQ== optionalDependencies: - "@esbuild/aix-ppc64" "0.23.1" - "@esbuild/android-arm" "0.23.1" - "@esbuild/android-arm64" "0.23.1" - "@esbuild/android-x64" "0.23.1" - "@esbuild/darwin-arm64" "0.23.1" - "@esbuild/darwin-x64" "0.23.1" - "@esbuild/freebsd-arm64" "0.23.1" - "@esbuild/freebsd-x64" "0.23.1" - "@esbuild/linux-arm" "0.23.1" - "@esbuild/linux-arm64" "0.23.1" - "@esbuild/linux-ia32" "0.23.1" - "@esbuild/linux-loong64" "0.23.1" - "@esbuild/linux-mips64el" "0.23.1" - "@esbuild/linux-ppc64" "0.23.1" - "@esbuild/linux-riscv64" "0.23.1" - "@esbuild/linux-s390x" "0.23.1" - "@esbuild/linux-x64" "0.23.1" - "@esbuild/netbsd-x64" "0.23.1" - "@esbuild/openbsd-arm64" "0.23.1" - "@esbuild/openbsd-x64" "0.23.1" - "@esbuild/sunos-x64" "0.23.1" - "@esbuild/win32-arm64" "0.23.1" - "@esbuild/win32-ia32" "0.23.1" - "@esbuild/win32-x64" "0.23.1" + "@esbuild/aix-ppc64" "0.25.1" + "@esbuild/android-arm" "0.25.1" + "@esbuild/android-arm64" "0.25.1" + "@esbuild/android-x64" "0.25.1" + "@esbuild/darwin-arm64" "0.25.1" + "@esbuild/darwin-x64" "0.25.1" + "@esbuild/freebsd-arm64" "0.25.1" + "@esbuild/freebsd-x64" "0.25.1" + "@esbuild/linux-arm" "0.25.1" + "@esbuild/linux-arm64" "0.25.1" + "@esbuild/linux-ia32" "0.25.1" + "@esbuild/linux-loong64" "0.25.1" + "@esbuild/linux-mips64el" "0.25.1" + "@esbuild/linux-ppc64" "0.25.1" + "@esbuild/linux-riscv64" "0.25.1" + "@esbuild/linux-s390x" "0.25.1" + "@esbuild/linux-x64" "0.25.1" + "@esbuild/netbsd-arm64" "0.25.1" + "@esbuild/netbsd-x64" "0.25.1" + "@esbuild/openbsd-arm64" "0.25.1" + "@esbuild/openbsd-x64" "0.25.1" + "@esbuild/sunos-x64" "0.25.1" + "@esbuild/win32-arm64" "0.25.1" + "@esbuild/win32-ia32" "0.25.1" + "@esbuild/win32-x64" "0.25.1" escalade@^3.1.1: version "3.1.1" @@ -1987,7 +1978,7 @@ graphemer@^1.4.0: has-flag@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz" - integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= has-flag@^4.0.0: version "4.0.0" @@ -3113,6 +3104,11 @@ run-parallel@^1.1.9: dependencies: queue-microtask "^1.2.2" +run-script-os@^1.1.6: + version "1.1.6" + resolved "https://registry.npmjs.org/run-script-os/-/run-script-os-1.1.6.tgz" + integrity sha512-ql6P2LzhBTTDfzKts+Qo4H94VUKpxKDFz6QxxwaUZN0mwvi7L3lpOI7BqPCq7lgDh3XLl0dpeXwfcVIitlrYrw== + semver@^6.3.0: version "6.3.1" resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz" @@ -3317,11 +3313,6 @@ tmpl@1.0.5: resolved "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz" integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw== -to-fast-properties@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz" - integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== - to-regex-range@^5.0.1: version "5.0.1" resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz" @@ -3373,11 +3364,11 @@ ts-node@>=9.0.0: yn "3.1.1" tsx@^4.10.5: - version "4.19.2" - resolved "https://registry.npmjs.org/tsx/-/tsx-4.19.2.tgz" - integrity sha512-pOUl6Vo2LUq/bSa8S5q7b91cgNSjctn9ugq/+Mvow99qW6x/UZYwzxy/3NmqoT66eHYfCVvFvACC58UBPFf28g== + version "4.19.3" + resolved "https://registry.npmjs.org/tsx/-/tsx-4.19.3.tgz" + integrity sha512-4H8vUNGNjQ4V2EOoGw005+c+dGuPSnhpPBPHBtsZdGZBk/iJb4kguGlPWaZTZ3q5nMtFOEsY0nRDlh9PJyd6SQ== dependencies: - esbuild "~0.23.0" + esbuild "~0.25.0" get-tsconfig "^4.7.5" optionalDependencies: fsevents "~2.3.3"