openvibers/openvibe.sources Commits
Seed ovhcloud-domain-pricing: OVHcloud's public domain catalog (950 endings, first year, renewal and transfer in US dollars), a second registrar for OpenVibe.Host's domain comparison; robots and API schema read 2026-10-22, seeded disabled (#86)
Changes
@@@ -1207,6 +1207,38 @@"sensitivity": "none","default_indexability": "noindex"},++ {++ "key": "ovhcloud-domain-pricing",++ "name": "OVHcloud domain prices (every TLD its international store sells, in US dollars)",++ "type": "api",++ "category": "hosting",++ "homepage_url": "https://www.ovhcloud.com/en/domains/tld/",++ "endpoints": [{++ "url": "https://api.ca.ovhcloud.com/1.0/order/catalog/public/domain?ovhSubsidiary=WE",++ "format": "json",++ "items_path": "plans",++ "item_kind": "tld_price",++ "max_bytes": 33554432,++ "timeout_ms": 120000,++ "fields": { "identity": "planCode", "title": "invoiceName" },++ "extra": {++ "currency": "$root.locale.currencyCode",++ "register": "pricings[mode=create-default,phase=0].price",++ "renew": "pricings[mode=create-default,phase=1].price",++ "transfer": "pricings[mode=transfer-default,phase=0].price"++ }++ }],++ "robots_note": "robots.txt checked 2026-10-22 from the production host: https://api.ca.ovhcloud.com/robots.txt answers 404 (nginx), so the API host publishes no robots.txt rules; a 404 is treated as no restrictions (never guessed as a disallow). ca.api.ovh.com/robots.txt redirects there. The fetcher re-checks robots.txt on every run. (www.ovhcloud.com, the store, is a different host and is not fetched.)",++ "terms_note": "OVHcloud's own API schema (https://api.ca.ovhcloud.com/1.0/order.json, read 2026-10-22) marks GET /order/catalog/public/domain 'noAuthentication': true with apiStatus 'Stable production version' ('Retrieve domain catalog'): the public catalog is meant to be read without an account, as the VPS catalog OpenVibe.Host already reads (ovhcloud-vps) is. The WE subsidiary is OVHcloud's international English store, priced in US dollars with no tax; api.us.ovhcloud.com does not sell domains ('product not found'). The terms page (https://www.ovhcloud.com/en/terms-and-conditions/contracts/) lists the service contracts; none found states a right to, or a ban on, republishing catalog prices, the same finding as ovhcloud-vps. One file a day of about 30 MB (950 endings with every price variant). Prices are the catalog's integers in hundred-millionths of a dollar (920000000 is $9.20): create-default phase 0 is the first year, phase 1 the renewal, transfer-default phase 0 the transfer; premium and aftermarket modes are not read. A first-year price of 0 (an ending sold only with conditions) or the 999999 sentinel means not sold that way, and OpenVibe.Host leaves those out. Show each price as an observation 'checked on <date>' with a link to https://www.ovhcloud.com/en/domains/tld/, never a quote, and imply no endorsement.",++ "license_note": "Domain prices are OVHcloud's data (https://www.ovhcloud.com/en/domains/tld/). No licence to republish them was found beyond the public catalog being offered without authentication. Attribute OVHcloud and link its domain price page; no endorsement implied.",++ "min_interval_ms": 60000,++ "poll_interval_sec": 86400,++ "max_items": 1200,++ "enabled": false,++ "review_required": true,++ "sensitivity": "none",++ "default_indexability": "noindex"++ },{"key": "lowendtalk-offers","name": "LowEndTalk: the Offers board",nnew file mode 100644@@@ -0,0 +1,586 @@++{++ "catalogId": 9886,++ "locale": {++ "currencyCode": "USD",++ "subsidiary": "WE",++ "taxRate": 0++ },++ "plans": [++ {++ "planCode": "family",++ "invoiceName": ".family",++ "product": "family-product",++ "pricings": [++ {++ "capacities": [++ "installation",++ "renew"++ ],++ "commitment": 0,++ "description": "Creation of a .family domain name - 1 year",++ "interval": 12,++ "intervalUnit": "month",++ "mode": "create-default",++ "phase": 0,++ "price": 3069000000,++ "strategy": "tiered",++ "type": "rental"++ },++ {++ "capacities": [++ "renew"++ ],++ "commitment": 0,++ "description": "Renewal of a .family domain name - 1 year",++ "interval": 12,++ "intervalUnit": "month",++ "mode": "create-default",++ "phase": 1,++ "price": 3859000000,++ "strategy": "tiered",++ "type": "rental"++ },++ {++ "capacities": [++ "dynamic",++ "installation",++ "renew"++ ],++ "commitment": 0,++ "description": "Creation of a .family domain name - 1 year",++ "interval": 12,++ "intervalUnit": "month",++ "mode": "create-premium",++ "phase": 0,++ "price": 99999900000000,++ "strategy": "tiered",++ "type": "rental"++ },++ {++ "capacities": [++ "dynamic",++ "renew"++ ],++ "commitment": 0,++ "description": "Renewal of a .family domain name - 1 year",++ "interval": 12,++ "intervalUnit": "month",++ "mode": "create-premium",++ "phase": 1,++ "price": 99999900000000,++ "strategy": "tiered",++ "type": "rental"++ },++ {++ "capacities": [++ "installation",++ "renew"++ ],++ "commitment": 0,++ "description": "Transfer request of a .family domain name",++ "interval": 12,++ "intervalUnit": "month",++ "mode": "transfer-default",++ "phase": 0,++ "price": 3789000000,++ "strategy": "tiered",++ "type": "rental"++ },++ {++ "capacities": [++ "renew"++ ],++ "commitment": 0,++ "description": "Renewal of a .family domain name - 1 year",++ "interval": 12,++ "intervalUnit": "month",++ "mode": "transfer-default",++ "phase": 1,++ "price": 3859000000,++ "strategy": "tiered",++ "type": "rental"++ }++ ]++ },++ {++ "planCode": "io",++ "invoiceName": ".io",++ "product": "io-product",++ "pricings": [++ {++ "capacities": [++ "installation",++ "renew"++ ],++ "commitment": 0,++ "description": "Creation of a .io domain name - 1 year",++ "interval": 12,++ "intervalUnit": "month",++ "mode": "create-default",++ "phase": 0,++ "price": 6299000000,++ "strategy": "tiered",++ "type": "rental"++ },++ {++ "capacities": [++ "renew"++ ],++ "commitment": 0,++ "description": "Renewal of a .io domain name - 1 year",++ "interval": 12,++ "intervalUnit": "month",++ "mode": "create-default",++ "phase": 1,++ "price": 6269000000,++ "strategy": "tiered",++ "type": "rental"++ },++ {++ "capacities": [++ "dynamic",++ "installation",++ "renew"++ ],++ "commitment": 0,++ "description": "Creation of a .io domain name - 1 year",++ "interval": 12,++ "intervalUnit": "month",++ "mode": "create-premium",++ "phase": 0,++ "price": 99999900000000,++ "strategy": "tiered",++ "type": "rental"++ },++ {++ "capacities": [++ "dynamic",++ "renew"++ ],++ "commitment": 0,++ "description": "Renewal of a .io domain name - 1 year",++ "interval": 12,++ "intervalUnit": "month",++ "mode": "create-premium",++ "phase": 1,++ "price": 99999900000000,++ "strategy": "tiered",++ "type": "rental"++ },++ {++ "capacities": [++ "installation",++ "renew"++ ],++ "commitment": 0,++ "description": "Transfer request of a .io domain name",++ "interval": 12,++ "intervalUnit": "month",++ "mode": "transfer-default",++ "phase": 0,++ "price": 5069000000,++ "strategy": "tiered",++ "type": "rental"++ },++ {++ "capacities": [++ "renew"++ ],++ "commitment": 0,++ "description": "Renewal of a .io domain name - 1 year",++ "interval": 12,++ "intervalUnit": "month",++ "mode": "transfer-default",++ "phase": 1,++ "price": 6269000000,++ "strategy": "tiered",++ "type": "rental"++ }++ ]++ },++ {++ "planCode": "shop",++ "invoiceName": ".shop",++ "product": "shop-product",++ "pricings": [++ {++ "capacities": [++ "installation",++ "renew"++ ],++ "commitment": 0,++ "description": "Creation of a .shop domain name - 1 year",++ "interval": 12,++ "intervalUnit": "month",++ "mode": "create-default",++ "phase": 0,++ "price": 319000000,++ "strategy": "tiered",++ "type": "rental"++ },++ {++ "capacities": [++ "renew"++ ],++ "commitment": 0,++ "description": "Renewal of a .shop domain name - 1 year",++ "interval": 12,++ "intervalUnit": "month",++ "mode": "create-default",++ "phase": 1,++ "price": 4299000000,++ "strategy": "tiered",++ "type": "rental"++ },++ {++ "capacities": [++ "dynamic",++ "installation",++ "renew"++ ],++ "commitment": 0,++ "description": "Creation of a .shop domain name - 1 year",++ "interval": 12,++ "intervalUnit": "month",++ "mode": "create-premium",++ "phase": 0,++ "price": 99999900000000,++ "strategy": "tiered",++ "type": "rental"++ },++ {++ "capacities": [++ "dynamic",++ "renew"++ ],++ "commitment": 0,++ "description": "Renewal of a .shop domain name - 1 year",++ "interval": 12,++ "intervalUnit": "month",++ "mode": "create-premium",++ "phase": 1,++ "price": 99999900000000,++ "strategy": "tiered",++ "type": "rental"++ },++ {++ "capacities": [++ "installation",++ "renew"++ ],++ "commitment": 0,++ "description": "Transfer request of a .shop domain name",++ "interval": 12,++ "intervalUnit": "month",++ "mode": "transfer-default",++ "phase": 0,++ "price": 3429000000,++ "strategy": "tiered",++ "type": "rental"++ },++ {++ "capacities": [++ "renew"++ ],++ "commitment": 0,++ "description": "Renewal of a .shop domain name - 1 year",++ "interval": 12,++ "intervalUnit": "month",++ "mode": "transfer-default",++ "phase": 1,++ "price": 4299000000,++ "strategy": "tiered",++ "type": "rental"++ }++ ]++ },++ {++ "planCode": "co.uk",++ "invoiceName": ".co.uk",++ "product": "co-uk-product",++ "pricings": [++ {++ "capacities": [++ "installation",++ "renew"++ ],++ "commitment": 0,++ "description": "Creation of a .co.uk domain name - 1 year",++ "interval": 12,++ "intervalUnit": "month",++ "mode": "create-default",++ "phase": 0,++ "price": 849000000,++ "strategy": "tiered",++ "type": "rental"++ },++ {++ "capacities": [++ "renew"++ ],++ "commitment": 0,++ "description": "Renewal of a .co.uk domain name - 1 year",++ "interval": 12,++ "intervalUnit": "month",++ "mode": "create-default",++ "phase": 1,++ "price": 949000000,++ "strategy": "tiered",++ "type": "rental"++ },++ {++ "capacities": [++ "dynamic",++ "installation",++ "renew"++ ],++ "commitment": 0,++ "description": "Creation of a .co.uk domain name - 1 year",++ "interval": 12,++ "intervalUnit": "month",++ "mode": "create-premium",++ "phase": 0,++ "price": 99999900000000,++ "strategy": "tiered",++ "type": "rental"++ },++ {++ "capacities": [++ "dynamic",++ "renew"++ ],++ "commitment": 0,++ "description": "Renewal of a .co.uk domain name - 1 year",++ "interval": 12,++ "intervalUnit": "month",++ "mode": "create-premium",++ "phase": 1,++ "price": 99999900000000,++ "strategy": "tiered",++ "type": "rental"++ },++ {++ "capacities": [++ "installation",++ "renew"++ ],++ "commitment": 0,++ "description": "Transfer request of a .co.uk domain name",++ "interval": 12,++ "intervalUnit": "month",++ "mode": "transfer-default",++ "phase": 0,++ "price": 0,++ "strategy": "tiered",++ "type": "rental"++ },++ {++ "capacities": [++ "renew"++ ],++ "commitment": 0,++ "description": "Renewal of a .co.uk domain name - 1 year",++ "interval": 12,++ "intervalUnit": "month",++ "mode": "transfer-default",++ "phase": 1,++ "price": 949000000,++ "strategy": "tiered",++ "type": "rental"++ }++ ]++ },++ {++ "planCode": "dev",++ "invoiceName": ".dev",++ "product": "dev-product",++ "pricings": [++ {++ "capacities": [++ "installation",++ "renew"++ ],++ "commitment": 0,++ "description": "Creation of a .dev domain name - 1 year",++ "interval": 12,++ "intervalUnit": "month",++ "mode": "create-default",++ "phase": 0,++ "price": 1319000000,++ "strategy": "tiered",++ "type": "rental"++ },++ {++ "capacities": [++ "renew"++ ],++ "commitment": 0,++ "description": "Renewal of a .dev domain name - 1 year",++ "interval": 12,++ "intervalUnit": "month",++ "mode": "create-default",++ "phase": 1,++ "price": 1719000000,++ "strategy": "tiered",++ "type": "rental"++ },++ {++ "capacities": [++ "dynamic",++ "installation",++ "renew"++ ],++ "commitment": 0,++ "description": "Creation of a .dev domain name - 1 year",++ "interval": 12,++ "intervalUnit": "month",++ "mode": "create-premium",++ "phase": 0,++ "price": 99999900000000,++ "strategy": "tiered",++ "type": "rental"++ },++ {++ "capacities": [++ "dynamic",++ "renew"++ ],++ "commitment": 0,++ "description": "Renewal of a .dev domain name - 1 year",++ "interval": 12,++ "intervalUnit": "month",++ "mode": "create-premium",++ "phase": 1,++ "price": 99999900000000,++ "strategy": "tiered",++ "type": "rental"++ },++ {++ "capacities": [++ "installation",++ "renew"++ ],++ "commitment": 0,++ "description": "Transfer request of a .dev domain name",++ "interval": 12,++ "intervalUnit": "month",++ "mode": "transfer-default",++ "phase": 0,++ "price": 1719000000,++ "strategy": "tiered",++ "type": "rental"++ },++ {++ "capacities": [++ "renew"++ ],++ "commitment": 0,++ "description": "Renewal of a .dev domain name - 1 year",++ "interval": 12,++ "intervalUnit": "month",++ "mode": "transfer-default",++ "phase": 1,++ "price": 1719000000,++ "strategy": "tiered",++ "type": "rental"++ }++ ]++ },++ {++ "planCode": "com",++ "invoiceName": ".com",++ "product": "com-product",++ "pricings": [++ {++ "capacities": [++ "installation",++ "renew"++ ],++ "commitment": 0,++ "description": "Creation of a .com domain name - 1 year",++ "interval": 12,++ "intervalUnit": "month",++ "mode": "create-default",++ "phase": 0,++ "price": 920000000,++ "strategy": "tiered",++ "type": "rental"++ },++ {++ "capacities": [++ "renew"++ ],++ "commitment": 0,++ "description": "Renewal of a .com domain name - 1 year",++ "interval": 12,++ "intervalUnit": "month",++ "mode": "create-default",++ "phase": 1,++ "price": 1649000000,++ "strategy": "tiered",++ "type": "rental"++ },++ {++ "capacities": [++ "dynamic",++ "installation",++ "renew"++ ],++ "commitment": 0,++ "description": "Creation of a .com domain name - 1 year",++ "interval": 12,++ "intervalUnit": "month",++ "mode": "create-premium",++ "phase": 0,++ "price": 99999900000000,++ "strategy": "tiered",++ "type": "rental"++ },++ {++ "capacities": [++ "dynamic",++ "renew"++ ],++ "commitment": 0,++ "description": "Renewal of a .com domain name - 1 year",++ "interval": 12,++ "intervalUnit": "month",++ "mode": "create-premium",++ "phase": 1,++ "price": 99999900000000,++ "strategy": "tiered",++ "type": "rental"++ },++ {++ "capacities": [++ "installation",++ "renew"++ ],++ "commitment": 0,++ "description": "Transfer request of a .com domain name",++ "interval": 12,++ "intervalUnit": "month",++ "mode": "transfer-default",++ "phase": 0,++ "price": 920000000,++ "strategy": "tiered",++ "type": "rental"++ },++ {++ "capacities": [++ "renew"++ ],++ "commitment": 0,++ "description": "Renewal of a .com domain name - 1 year",++ "interval": 12,++ "intervalUnit": "month",++ "mode": "transfer-default",++ "phase": 1,++ "price": 1649000000,++ "strategy": "tiered",++ "type": "rental"++ }++ ]++ }++ ]++}\\ No newline at end of file@@@ -91,6 +91,25 @@ t('Porkbun prices: one item per TLD from the keyed price list, the prices as Porassert.strictEqual(by['0zebra'].special_type, 'handshake', 'Handshake names are marked, for Host to leave out');});++t('OVHcloud domain prices: one item per ending, the first year, renewal and transfer from the no-premium price modes', () => {++ const s = seed('ovhcloud-domain-pricing');++ assert.deepStrictEqual([s.type, s.category, s.enabled, s.review_required], ['api', 'hosting', false, true]);++ const ep = endpoint('ovhcloud-domain-pricing');++ assert.strictEqual(api.checkMapping(ep), null);++ assert.strictEqual(validateSource(s).max_items, 1200, 'OVHcloud sells about 950 endings; the whole list fits');++ assert.strictEqual(ep.max_bytes, 32 * 1024 * 1024, 'the whole catalog is about 30 MB');++ const r = api.parse(fx('ovhcloud-domain-pricing.json'), { url: ep.url, endpoint: ep, maxItems: 1200 });++ assert.strictEqual(r.skipped, 0);++ assert.deepStrictEqual(r.items.map((i) => i.identity), ['family', 'io', 'shop', 'co.uk', 'dev', 'com']);++ assert.ok(r.items.every((i) => i.kind === 'tld_price'));++ assert.strictEqual(r.items.find((i) => i.identity === 'co.uk').title, '.co.uk');++ const by = Object.fromEntries(r.items.map((i) => [i.identity, i.fields]));++ // Hundred-millionths of a dollar, as the catalog gives them: $9.20 the first year, $16.49 a renewal.++ assert.deepStrictEqual(by.com, { currency: 'USD', register: 920000000, renew: 1649000000, transfer: 920000000 });++ assert.deepStrictEqual(by.io, { currency: 'USD', register: 6299000000, renew: 6269000000, transfer: 5069000000 }, 'never the premium sentinel');++ assert.strictEqual(by['co.uk'].transfer, 0, 'a free transfer stays 0; Host decides what 0 means per field');++});++t('the registry accepts category hosting and refuses an unknown category', () => {const rec = validateSource(seed('vultr-plans'));assert.strictEqual(rec.category, 'hosting');
@@ -1207,6 +1207,38 @@
@@ -1207,6 +1207,38 @@
"sensitivity": "none",
"sensitivity": "none",
"default_indexability": "noindex"
"default_indexability": "noindex"
},
},
+ {
+ "key": "ovhcloud-domain-pricing",
+ "name": "OVHcloud domain prices (every TLD its international store sells, in US dollars)",
+ "type": "api",
+ "category": "hosting",
+ "homepage_url": "https://www.ovhcloud.com/en/domains/tld/",
+ "endpoints": [{
+ "url": "https://api.ca.ovhcloud.com/1.0/order/catalog/public/domain?ovhSubsidiary=WE",
+ "format": "json",
+ "items_path": "plans",
+ "item_kind": "tld_price",
+ "max_bytes": 33554432,
+ "timeout_ms": 120000,
+ "fields": { "identity": "planCode", "title": "invoiceName" },
+ "extra": {
+ "currency": "$root.locale.currencyCode",
+ "register": "pricings[mode=create-default,phase=0].price",
+ "renew": "pricings[mode=create-default,phase=1].price",
+ "transfer": "pricings[mode=transfer-default,phase=0].price"
+ }
+ }],
+ "robots_note": "robots.txt checked 2026-10-22 from the production host: https://api.ca.ovhcloud.com/robots.txt answers 404 (nginx), so the API host publishes no robots.txt rules; a 404 is treated as no restrictions (never guessed as a disallow). ca.api.ovh.com/robots.txt redirects there. The fetcher re-checks robots.txt on every run. (www.ovhcloud.com, the store, is a different host and is not fetched.)",
+ "terms_note": "OVHcloud's own API schema (https://api.ca.ovhcloud.com/1.0/order.json, read 2026-10-22) marks GET /order/catalog/public/domain 'noAuthentication': true with apiStatus 'Stable production version' ('Retrieve domain catalog'): the public catalog is meant to be read without an account, as the VPS catalog OpenVibe.Host already reads (ovhcloud-vps) is. The WE subsidiary is OVHcloud's international English store, priced in US dollars with no tax; api.us.ovhcloud.com does not sell domains ('product not found'). The terms page (https://www.ovhcloud.com/en/terms-and-conditions/contracts/) lists the service contracts; none found states a right to, or a ban on, republishing catalog prices, the same finding as ovhcloud-vps. One file a day of about 30 MB (950 endings with every price variant). Prices are the catalog's integers in hundred-millionths of a dollar (920000000 is $9.20): create-default phase 0 is the first year, phase 1 the renewal, transfer-default phase 0 the transfer; premium and aftermarket modes are not read. A first-year price of 0 (an ending sold only with conditions) or the 999999 sentinel means not sold that way, and OpenVibe.Host leaves those out. Show each price as an observation 'checked on <date>' with a link to https://www.ovhcloud.com/en/domains/tld/, never a quote, and imply no endorsement.",
+ "license_note": "Domain prices are OVHcloud's data (https://www.ovhcloud.com/en/domains/tld/). No licence to republish them was found beyond the public catalog being offered without authentication. Attribute OVHcloud and link its domain price page; no endorsement implied.",
+ "min_interval_ms": 60000,
+ "poll_interval_sec": 86400,
+ "max_items": 1200,
+ "enabled": false,
+ "review_required": true,
+ "sensitivity": "none",
+ "default_indexability": "noindex"
+ },
{
{
"key": "lowendtalk-offers",
"key": "lowendtalk-offers",
"name": "LowEndTalk: the Offers board",
"name": "LowEndTalk: the Offers board",
new file mode 100644
new file mode 100644
@@ -0,0 +1,586 @@
@@ -0,0 +1,586 @@
+{
+ "catalogId": 9886,
+ "locale": {
+ "currencyCode": "USD",
+ "subsidiary": "WE",
+ "taxRate": 0
+ },
+ "plans": [
+ {
+ "planCode": "family",
+ "invoiceName": ".family",
+ "product": "family-product",
+ "pricings": [
+ {
+ "capacities": [
+ "installation",
+ "renew"
+ ],
+ "commitment": 0,
+ "description": "Creation of a .family domain name - 1 year",
+ "interval": 12,
+ "intervalUnit": "month",
+ "mode": "create-default",
+ "phase": 0,
+ "price": 3069000000,
+ "strategy": "tiered",
+ "type": "rental"
+ },
+ {
+ "capacities": [
+ "renew"
+ ],
+ "commitment": 0,
+ "description": "Renewal of a .family domain name - 1 year",
+ "interval": 12,
+ "intervalUnit": "month",
+ "mode": "create-default",
+ "phase": 1,
+ "price": 3859000000,
+ "strategy": "tiered",
+ "type": "rental"
+ },
+ {
+ "capacities": [
+ "dynamic",
+ "installation",
+ "renew"
+ ],
+ "commitment": 0,
+ "description": "Creation of a .family domain name - 1 year",
+ "interval": 12,
+ "intervalUnit": "month",
+ "mode": "create-premium",
+ "phase": 0,
+ "price": 99999900000000,
+ "strategy": "tiered",
+ "type": "rental"
+ },
+ {
+ "capacities": [
+ "dynamic",
+ "renew"
+ ],
+ "commitment": 0,
+ "description": "Renewal of a .family domain name - 1 year",
+ "interval": 12,
+ "intervalUnit": "month",
+ "mode": "create-premium",
+ "phase": 1,
+ "price": 99999900000000,
+ "strategy": "tiered",
+ "type": "rental"
+ },
+ {
+ "capacities": [
+ "installation",
+ "renew"
+ ],
+ "commitment": 0,
+ "description": "Transfer request of a .family domain name",
+ "interval": 12,
+ "intervalUnit": "month",
+ "mode": "transfer-default",
+ "phase": 0,
+ "price": 3789000000,
+ "strategy": "tiered",
+ "type": "rental"
+ },
+ {
+ "capacities": [
+ "renew"
+ ],
+ "commitment": 0,
+ "description": "Renewal of a .family domain name - 1 year",
+ "interval": 12,
+ "intervalUnit": "month",
+ "mode": "transfer-default",
+ "phase": 1,
+ "price": 3859000000,
+ "strategy": "tiered",
+ "type": "rental"
+ }
+ ]
+ },
+ {
+ "planCode": "io",
+ "invoiceName": ".io",
+ "product": "io-product",
+ "pricings": [
+ {
+ "capacities": [
+ "installation",
+ "renew"
+ ],
+ "commitment": 0,
+ "description": "Creation of a .io domain name - 1 year",
+ "interval": 12,
+ "intervalUnit": "month",
+ "mode": "create-default",
+ "phase": 0,
+ "price": 6299000000,
+ "strategy": "tiered",
+ "type": "rental"
+ },
+ {
+ "capacities": [
+ "renew"
+ ],
+ "commitment": 0,
+ "description": "Renewal of a .io domain name - 1 year",
+ "interval": 12,
+ "intervalUnit": "month",
+ "mode": "create-default",
+ "phase": 1,
+ "price": 6269000000,
+ "strategy": "tiered",
+ "type": "rental"
+ },
+ {
+ "capacities": [
+ "dynamic",
+ "installation",
+ "renew"
+ ],
+ "commitment": 0,
+ "description": "Creation of a .io domain name - 1 year",
+ "interval": 12,
+ "intervalUnit": "month",
+ "mode": "create-premium",
+ "phase": 0,
+ "price": 99999900000000,
+ "strategy": "tiered",
+ "type": "rental"
+ },
+ {
+ "capacities": [
+ "dynamic",
+ "renew"
+ ],
+ "commitment": 0,
+ "description": "Renewal of a .io domain name - 1 year",
+ "interval": 12,
+ "intervalUnit": "month",
+ "mode": "create-premium",
+ "phase": 1,
+ "price": 99999900000000,
+ "strategy": "tiered",
+ "type": "rental"
+ },
+ {
+ "capacities": [
+ "installation",
+ "renew"
+ ],
+ "commitment": 0,
+ "description": "Transfer request of a .io domain name",
+ "interval": 12,
+ "intervalUnit": "month",
+ "mode": "transfer-default",
+ "phase": 0,
+ "price": 5069000000,
+ "strategy": "tiered",
+ "type": "rental"
+ },
+ {
+ "capacities": [
+ "renew"
+ ],
+ "commitment": 0,
+ "description": "Renewal of a .io domain name - 1 year",
+ "interval": 12,
+ "intervalUnit": "month",
+ "mode": "transfer-default",
+ "phase": 1,
+ "price": 6269000000,
+ "strategy": "tiered",
+ "type": "rental"
+ }
+ ]
+ },
+ {
+ "planCode": "shop",
+ "invoiceName": ".shop",
+ "product": "shop-product",
+ "pricings": [
+ {
+ "capacities": [
+ "installation",
+ "renew"
+ ],
+ "commitment": 0,
+ "description": "Creation of a .shop domain name - 1 year",
+ "interval": 12,
+ "intervalUnit": "month",
+ "mode": "create-default",
+ "phase": 0,
+ "price": 319000000,
+ "strategy": "tiered",
+ "type": "rental"
+ },
+ {
+ "capacities": [
+ "renew"
+ ],
+ "commitment": 0,
+ "description": "Renewal of a .shop domain name - 1 year",
+ "interval": 12,
+ "intervalUnit": "month",
+ "mode": "create-default",
+ "phase": 1,
+ "price": 4299000000,
+ "strategy": "tiered",
+ "type": "rental"
+ },
+ {
+ "capacities": [
+ "dynamic",
+ "installation",
+ "renew"
+ ],
+ "commitment": 0,
+ "description": "Creation of a .shop domain name - 1 year",
+ "interval": 12,
+ "intervalUnit": "month",
+ "mode": "create-premium",
+ "phase": 0,
+ "price": 99999900000000,
+ "strategy": "tiered",
+ "type": "rental"
+ },
+ {
+ "capacities": [
+ "dynamic",
+ "renew"
+ ],
+ "commitment": 0,
+ "description": "Renewal of a .shop domain name - 1 year",
+ "interval": 12,
+ "intervalUnit": "month",
+ "mode": "create-premium",
+ "phase": 1,
+ "price": 99999900000000,
+ "strategy": "tiered",
+ "type": "rental"
+ },
+ {
+ "capacities": [
+ "installation",
+ "renew"
+ ],
+ "commitment": 0,
+ "description": "Transfer request of a .shop domain name",
+ "interval": 12,
+ "intervalUnit": "month",
+ "mode": "transfer-default",
+ "phase": 0,
+ "price": 3429000000,
+ "strategy": "tiered",
+ "type": "rental"
+ },
+ {
+ "capacities": [
+ "renew"
+ ],
+ "commitment": 0,
+ "description": "Renewal of a .shop domain name - 1 year",
+ "interval": 12,
+ "intervalUnit": "month",
+ "mode": "transfer-default",
+ "phase": 1,
+ "price": 4299000000,
+ "strategy": "tiered",
+ "type": "rental"
+ }
+ ]
+ },
+ {
+ "planCode": "co.uk",
+ "invoiceName": ".co.uk",
+ "product": "co-uk-product",
+ "pricings": [
+ {
+ "capacities": [
+ "installation",
+ "renew"
+ ],
+ "commitment": 0,
+ "description": "Creation of a .co.uk domain name - 1 year",
+ "interval": 12,
+ "intervalUnit": "month",
+ "mode": "create-default",
+ "phase": 0,
+ "price": 849000000,
+ "strategy": "tiered",
+ "type": "rental"
+ },
+ {
+ "capacities": [
+ "renew"
+ ],
+ "commitment": 0,
+ "description": "Renewal of a .co.uk domain name - 1 year",
+ "interval": 12,
+ "intervalUnit": "month",
+ "mode": "create-default",
+ "phase": 1,
+ "price": 949000000,
+ "strategy": "tiered",
+ "type": "rental"
+ },
+ {
+ "capacities": [
+ "dynamic",
+ "installation",
+ "renew"
+ ],
+ "commitment": 0,
+ "description": "Creation of a .co.uk domain name - 1 year",
+ "interval": 12,
+ "intervalUnit": "month",
+ "mode": "create-premium",
+ "phase": 0,
+ "price": 99999900000000,
+ "strategy": "tiered",
+ "type": "rental"
+ },
+ {
+ "capacities": [
+ "dynamic",
+ "renew"
+ ],
+ "commitment": 0,
+ "description": "Renewal of a .co.uk domain name - 1 year",
+ "interval": 12,
+ "intervalUnit": "month",
+ "mode": "create-premium",
+ "phase": 1,
+ "price": 99999900000000,
+ "strategy": "tiered",
+ "type": "rental"
+ },
+ {
+ "capacities": [
+ "installation",
+ "renew"
+ ],
+ "commitment": 0,
+ "description": "Transfer request of a .co.uk domain name",
+ "interval": 12,
+ "intervalUnit": "month",
+ "mode": "transfer-default",
+ "phase": 0,
+ "price": 0,
+ "strategy": "tiered",
+ "type": "rental"
+ },
+ {
+ "capacities": [
+ "renew"
+ ],
+ "commitment": 0,
+ "description": "Renewal of a .co.uk domain name - 1 year",
+ "interval": 12,
+ "intervalUnit": "month",
+ "mode": "transfer-default",
+ "phase": 1,
+ "price": 949000000,
+ "strategy": "tiered",
+ "type": "rental"
+ }
+ ]
+ },
+ {
+ "planCode": "dev",
+ "invoiceName": ".dev",
+ "product": "dev-product",
+ "pricings": [
+ {
+ "capacities": [
+ "installation",
+ "renew"
+ ],
+ "commitment": 0,
+ "description": "Creation of a .dev domain name - 1 year",
+ "interval": 12,
+ "intervalUnit": "month",
+ "mode": "create-default",
+ "phase": 0,
+ "price": 1319000000,
+ "strategy": "tiered",
+ "type": "rental"
+ },
+ {
+ "capacities": [
+ "renew"
+ ],
+ "commitment": 0,
+ "description": "Renewal of a .dev domain name - 1 year",
+ "interval": 12,
+ "intervalUnit": "month",
+ "mode": "create-default",
+ "phase": 1,
+ "price": 1719000000,
+ "strategy": "tiered",
+ "type": "rental"
+ },
+ {
+ "capacities": [
+ "dynamic",
+ "installation",
+ "renew"
+ ],
+ "commitment": 0,
+ "description": "Creation of a .dev domain name - 1 year",
+ "interval": 12,
+ "intervalUnit": "month",
+ "mode": "create-premium",
+ "phase": 0,
+ "price": 99999900000000,
+ "strategy": "tiered",
+ "type": "rental"
+ },
+ {
+ "capacities": [
+ "dynamic",
+ "renew"
+ ],
+ "commitment": 0,
+ "description": "Renewal of a .dev domain name - 1 year",
+ "interval": 12,
+ "intervalUnit": "month",
+ "mode": "create-premium",
+ "phase": 1,
+ "price": 99999900000000,
+ "strategy": "tiered",
+ "type": "rental"
+ },
+ {
+ "capacities": [
+ "installation",
+ "renew"
+ ],
+ "commitment": 0,
+ "description": "Transfer request of a .dev domain name",
+ "interval": 12,
+ "intervalUnit": "month",
+ "mode": "transfer-default",
+ "phase": 0,
+ "price": 1719000000,
+ "strategy": "tiered",
+ "type": "rental"
+ },
+ {
+ "capacities": [
+ "renew"
+ ],
+ "commitment": 0,
+ "description": "Renewal of a .dev domain name - 1 year",
+ "interval": 12,
+ "intervalUnit": "month",
+ "mode": "transfer-default",
+ "phase": 1,
+ "price": 1719000000,
+ "strategy": "tiered",
+ "type": "rental"
+ }
+ ]
+ },
+ {
+ "planCode": "com",
+ "invoiceName": ".com",
+ "product": "com-product",
+ "pricings": [
+ {
+ "capacities": [
+ "installation",
+ "renew"
+ ],
+ "commitment": 0,
+ "description": "Creation of a .com domain name - 1 year",
+ "interval": 12,
+ "intervalUnit": "month",
+ "mode": "create-default",
+ "phase": 0,
+ "price": 920000000,
+ "strategy": "tiered",
+ "type": "rental"
+ },
+ {
+ "capacities": [
+ "renew"
+ ],
+ "commitment": 0,
+ "description": "Renewal of a .com domain name - 1 year",
+ "interval": 12,
+ "intervalUnit": "month",
+ "mode": "create-default",
+ "phase": 1,
+ "price": 1649000000,
+ "strategy": "tiered",
+ "type": "rental"
+ },
+ {
+ "capacities": [
+ "dynamic",
+ "installation",
+ "renew"
+ ],
+ "commitment": 0,
+ "description": "Creation of a .com domain name - 1 year",
+ "interval": 12,
+ "intervalUnit": "month",
+ "mode": "create-premium",
+ "phase": 0,
+ "price": 99999900000000,
+ "strategy": "tiered",
+ "type": "rental"
+ },
+ {
+ "capacities": [
+ "dynamic",
+ "renew"
+ ],
+ "commitment": 0,
+ "description": "Renewal of a .com domain name - 1 year",
+ "interval": 12,
+ "intervalUnit": "month",
+ "mode": "create-premium",
+ "phase": 1,
+ "price": 99999900000000,
+ "strategy": "tiered",
+ "type": "rental"
+ },
+ {
+ "capacities": [
+ "installation",
+ "renew"
+ ],
+ "commitment": 0,
+ "description": "Transfer request of a .com domain name",
+ "interval": 12,
+ "intervalUnit": "month",
+ "mode": "transfer-default",
+ "phase": 0,
+ "price": 920000000,
+ "strategy": "tiered",
+ "type": "rental"
+ },
+ {
+ "capacities": [
+ "renew"
+ ],
+ "commitment": 0,
+ "description": "Renewal of a .com domain name - 1 year",
+ "interval": 12,
+ "intervalUnit": "month",
+ "mode": "transfer-default",
+ "phase": 1,
+ "price": 1649000000,
+ "strategy": "tiered",
+ "type": "rental"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
\ No newline at end of file
@@ -91,6 +91,25 @@ t('Porkbun prices: one item per TLD from the keyed price list, the prices as Por
@@ -91,6 +91,25 @@ t('Porkbun prices: one item per TLD from the keyed price list, the prices as Por
assert.strictEqual(by['0zebra'].special_type, 'handshake', 'Handshake names are marked, for Host to leave out');
assert.strictEqual(by['0zebra'].special_type, 'handshake', 'Handshake names are marked, for Host to leave out');
});
});
+t('OVHcloud domain prices: one item per ending, the first year, renewal and transfer from the no-premium price modes', () => {
+ const s = seed('ovhcloud-domain-pricing');
+ assert.deepStrictEqual([s.type, s.category, s.enabled, s.review_required], ['api', 'hosting', false, true]);
+ const ep = endpoint('ovhcloud-domain-pricing');
+ assert.strictEqual(api.checkMapping(ep), null);
+ assert.strictEqual(validateSource(s).max_items, 1200, 'OVHcloud sells about 950 endings; the whole list fits');
+ assert.strictEqual(ep.max_bytes, 32 * 1024 * 1024, 'the whole catalog is about 30 MB');
+ const r = api.parse(fx('ovhcloud-domain-pricing.json'), { url: ep.url, endpoint: ep, maxItems: 1200 });
+ assert.strictEqual(r.skipped, 0);
+ assert.deepStrictEqual(r.items.map((i) => i.identity), ['family', 'io', 'shop', 'co.uk', 'dev', 'com']);
+ assert.ok(r.items.every((i) => i.kind === 'tld_price'));
+ assert.strictEqual(r.items.find((i) => i.identity === 'co.uk').title, '.co.uk');
+ const by = Object.fromEntries(r.items.map((i) => [i.identity, i.fields]));
+ // Hundred-millionths of a dollar, as the catalog gives them: $9.20 the first year, $16.49 a renewal.
+ assert.deepStrictEqual(by.com, { currency: 'USD', register: 920000000, renew: 1649000000, transfer: 920000000 });
+ assert.deepStrictEqual(by.io, { currency: 'USD', register: 6299000000, renew: 6269000000, transfer: 5069000000 }, 'never the premium sentinel');
+ assert.strictEqual(by['co.uk'].transfer, 0, 'a free transfer stays 0; Host decides what 0 means per field');
+});
+
t('the registry accepts category hosting and refuses an unknown category', () => {
t('the registry accepts category hosting and refuses an unknown category', () => {
const rec = validateSource(seed('vultr-plans'));
const rec = validateSource(seed('vultr-plans'));
assert.strictEqual(rec.category, 'hosting');
assert.strictEqual(rec.category, 'hosting');