@krx3d/tizentube2 1.30.40 → 1.30.60
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@krx3d/tizentube2",
|
|
3
3
|
"appName": "TizenTube",
|
|
4
|
-
"version": "1.30.
|
|
4
|
+
"version": "1.30.60",
|
|
5
5
|
"description": "TizenTube is an ad-free and sponsor-free solution for your favourite streaming website on your Tizen (Samsung) TVs.",
|
|
6
6
|
"packageType": "mods",
|
|
7
7
|
"websiteURL": "https://youtube.com/tv?additionalDataUrl=http%3A%2F%2Flocalhost%3A8085%2Fdial%2Fapps%2FYouTube",
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
<#
|
|
2
|
+
.SYNOPSIS
|
|
3
|
+
Removes old @krx3d/tizentube2 versions from npm.
|
|
4
|
+
|
|
5
|
+
.DESCRIPTION
|
|
6
|
+
The publish workflow attempts this on every run and cannot succeed. npm
|
|
7
|
+
removed legacy tokens in November 2025, so a granular access token is the only
|
|
8
|
+
kind left, and since August 2026 one with bypass-2FA is refused for sensitive
|
|
9
|
+
actions — unpublish among them. CI has no way to answer a 2FA challenge, so
|
|
10
|
+
removal has to happen from a machine where someone can type a code.
|
|
11
|
+
|
|
12
|
+
This does that, with the guard rails the workflow learned the hard way:
|
|
13
|
+
|
|
14
|
+
- the version npm's `latest` tag points at is never touched, nor is any
|
|
15
|
+
other dist-tag target
|
|
16
|
+
- nothing is removed without showing the list and asking first
|
|
17
|
+
- one 2FA code covers the whole batch, since npm accepts --otp per command
|
|
18
|
+
and a code stays valid for its whole window
|
|
19
|
+
|
|
20
|
+
npm only allows unpublishing a version within 72 hours of its publication, so
|
|
21
|
+
anything older is listed and skipped rather than attempted. Those stay on the
|
|
22
|
+
registry as deprecated versions, which is all the workflow can do to them.
|
|
23
|
+
|
|
24
|
+
.PARAMETER Package
|
|
25
|
+
The npm package name. Defaults to this repo's package.
|
|
26
|
+
|
|
27
|
+
.PARAMETER Keep
|
|
28
|
+
Extra versions to leave alone, on top of every dist-tag target.
|
|
29
|
+
|
|
30
|
+
.PARAMETER IncludeOlder
|
|
31
|
+
Also attempt versions outside npm's 72-hour window. npm usually refuses
|
|
32
|
+
these, but a refused request changes nothing, so it costs only the
|
|
33
|
+
attempt — and it does sometimes go through for a package nothing depends
|
|
34
|
+
on. Off by default so the normal run stays quiet.
|
|
35
|
+
|
|
36
|
+
.PARAMETER WhatIf
|
|
37
|
+
List what would be removed and stop.
|
|
38
|
+
|
|
39
|
+
.EXAMPLE
|
|
40
|
+
.\unpublish-old-versions.ps1 -WhatIf
|
|
41
|
+
|
|
42
|
+
.EXAMPLE
|
|
43
|
+
.\unpublish-old-versions.ps1 -Keep 1.30.40
|
|
44
|
+
#>
|
|
45
|
+
param(
|
|
46
|
+
[string]$Package = '@krx3d/tizentube2',
|
|
47
|
+
[string[]]$Keep = @(),
|
|
48
|
+
[int]$WindowHours = 72,
|
|
49
|
+
[switch]$IncludeOlder,
|
|
50
|
+
[switch]$WhatIf
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
$ErrorActionPreference = 'Stop'
|
|
54
|
+
|
|
55
|
+
function Get-Packument {
|
|
56
|
+
param([string]$Name)
|
|
57
|
+
# Read the registry directly. `npm view` has its own HTTP cache, and a stale
|
|
58
|
+
# answer here means acting on a version list that is no longer true.
|
|
59
|
+
$url = "https://registry.npmjs.org/$Name"
|
|
60
|
+
try {
|
|
61
|
+
return Invoke-RestMethod -Uri $url -Method Get -Headers @{ Accept = 'application/json' }
|
|
62
|
+
} catch {
|
|
63
|
+
throw "Could not read $url : $($_.Exception.Message)"
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
Write-Host "Reading the registry for $Package ..."
|
|
68
|
+
$doc = Get-Packument -Name $Package
|
|
69
|
+
|
|
70
|
+
$live = @($doc.versions.PSObject.Properties.Name)
|
|
71
|
+
if (-not $live -or $live.Count -eq 0) { throw "No live versions found for $Package." }
|
|
72
|
+
|
|
73
|
+
# Every dist-tag target is protected, not just latest: installing a tag npm
|
|
74
|
+
# hands out must keep working.
|
|
75
|
+
$tagTargets = @($doc.'dist-tags'.PSObject.Properties | ForEach-Object { $_.Value })
|
|
76
|
+
$protected = @($tagTargets + $Keep) | Where-Object { $_ } | Sort-Object -Unique
|
|
77
|
+
|
|
78
|
+
Write-Host ""
|
|
79
|
+
Write-Host "Live versions: $($live.Count)"
|
|
80
|
+
Write-Host "Protected: $($protected -join ', ')"
|
|
81
|
+
Write-Host ""
|
|
82
|
+
|
|
83
|
+
$now = [DateTime]::UtcNow
|
|
84
|
+
$removable = @()
|
|
85
|
+
$tooOld = @()
|
|
86
|
+
|
|
87
|
+
foreach ($v in $live) {
|
|
88
|
+
if ($protected -contains $v) { continue }
|
|
89
|
+
$stamp = $doc.time.PSObject.Properties[$v]
|
|
90
|
+
if (-not $stamp) { $tooOld += $v; continue }
|
|
91
|
+
# Invoke-RestMethod converts an ISO timestamp into a DateTime on its own,
|
|
92
|
+
# but only sometimes — and re-parsing the result fails outright under a
|
|
93
|
+
# non-US culture, where it renders as MM/dd/yyyy and Parse then rejects it.
|
|
94
|
+
# So take a DateTime as-is and parse a string as invariant UTC.
|
|
95
|
+
$raw = $stamp.Value
|
|
96
|
+
if ($raw -is [DateTime]) {
|
|
97
|
+
$published = $raw.ToUniversalTime()
|
|
98
|
+
} else {
|
|
99
|
+
$styles = [System.Globalization.DateTimeStyles]::AdjustToUniversal -bor [System.Globalization.DateTimeStyles]::AssumeUniversal
|
|
100
|
+
$published = [DateTime]::Parse([string]$raw, [System.Globalization.CultureInfo]::InvariantCulture, $styles)
|
|
101
|
+
}
|
|
102
|
+
$age = ($now - $published).TotalHours
|
|
103
|
+
if ($age -le $WindowHours) {
|
|
104
|
+
$removable += [pscustomobject]@{ Version = $v; AgeHours = [math]::Round($age, 1) }
|
|
105
|
+
} elseif ($IncludeOlder) {
|
|
106
|
+
$removable += [pscustomobject]@{ Version = $v; AgeHours = [math]::Round($age, 1) }
|
|
107
|
+
} else {
|
|
108
|
+
$tooOld += $v
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if ($tooOld.Count -gt 0) {
|
|
113
|
+
Write-Host "Outside npm's $WindowHours-hour window, so they cannot be removed ($($tooOld.Count)):" -ForegroundColor DarkGray
|
|
114
|
+
Write-Host " $($tooOld -join ', ')" -ForegroundColor DarkGray
|
|
115
|
+
Write-Host " Pass -IncludeOlder to attempt them anyway." -ForegroundColor DarkGray
|
|
116
|
+
Write-Host ""
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if ($removable.Count -eq 0) {
|
|
120
|
+
Write-Host "Nothing to remove." -ForegroundColor Green
|
|
121
|
+
return
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if ($IncludeOlder) {
|
|
125
|
+
Write-Host "To attempt ($($removable.Count)), including versions npm will probably refuse:" -ForegroundColor Yellow
|
|
126
|
+
} else {
|
|
127
|
+
Write-Host "Can be removed ($($removable.Count)):" -ForegroundColor Yellow
|
|
128
|
+
}
|
|
129
|
+
$removable | Format-Table -AutoSize | Out-String | Write-Host
|
|
130
|
+
|
|
131
|
+
if ($WhatIf) {
|
|
132
|
+
Write-Host "-WhatIf given, so nothing was changed." -ForegroundColor Cyan
|
|
133
|
+
return
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
$answer = Read-Host "Remove these $($removable.Count) versions from npm? (type 'yes')"
|
|
137
|
+
if ($answer -ne 'yes') {
|
|
138
|
+
Write-Host "Cancelled; nothing was changed." -ForegroundColor Cyan
|
|
139
|
+
return
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
# One code for the batch. npm accepts --otp on each command and the code stays
|
|
143
|
+
# valid for its window, so this asks once rather than once per version.
|
|
144
|
+
$otp = Read-Host "Two-factor code from your authenticator"
|
|
145
|
+
if (-not $otp) {
|
|
146
|
+
Write-Host "No code given; nothing was changed." -ForegroundColor Cyan
|
|
147
|
+
return
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
$removed = 0
|
|
151
|
+
$failed = @()
|
|
152
|
+
|
|
153
|
+
foreach ($item in $removable) {
|
|
154
|
+
$spec = "$Package@$($item.Version)"
|
|
155
|
+
Write-Host ""
|
|
156
|
+
Write-Host "Unpublishing $spec ..."
|
|
157
|
+
$output = & npm unpublish $spec --otp $otp 2>&1
|
|
158
|
+
if ($LASTEXITCODE -eq 0) {
|
|
159
|
+
$removed++
|
|
160
|
+
Write-Host " removed" -ForegroundColor Green
|
|
161
|
+
} else {
|
|
162
|
+
$failed += $item.Version
|
|
163
|
+
Write-Host ($output | Out-String).Trim() -ForegroundColor Red
|
|
164
|
+
if (($output | Out-String) -match 'one-time pass|EOTP|invalid otp') {
|
|
165
|
+
# A stale code fails every remaining version the same way; stop and let
|
|
166
|
+
# the next run start from a fresh one rather than burning through the list.
|
|
167
|
+
Write-Host ""
|
|
168
|
+
Write-Host "The code was rejected. Run this again with a fresh one." -ForegroundColor Yellow
|
|
169
|
+
break
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
Write-Host ""
|
|
175
|
+
Write-Host "Removed $removed of $($removable.Count)."
|
|
176
|
+
if ($failed.Count -gt 0) {
|
|
177
|
+
Write-Host "Still present: $($failed -join ', ')" -ForegroundColor Yellow
|
|
178
|
+
}
|
|
179
|
+
Write-Host "A removed version number can never be published again, so the next" -ForegroundColor DarkGray
|
|
180
|
+
Write-Host "build continues from where the bump left off." -ForegroundColor DarkGray
|