diff --git a/manifests/micro-utilities.json b/manifests/micro-utilities.json index 7efdf48..79681b3 100644 --- a/manifests/micro-utilities.json +++ b/manifests/micro-utilities.json @@ -162,6 +162,12 @@ "description": "If the current environment is npm the `npm_config_user_agent` environment variable will be set and start with `\"npm\"`.", "example": "const isNpm = process.env.npm_config_user_agent?.startsWith(\"npm\")" }, + "snippet::is-number": { + "id": "snippet::is-number", + "type": "simple", + "description": "You can check if a value is a number by using `typeof` or coercing it to a number and using `Number.isFinite`.", + "example": "const isNumber = (v) => typeof v === \"number\" || (typeof v === \"string\" && Number.isFinite(+v));" + }, "snippet::is-object": { "id": "snippet::is-object", "type": "simple", @@ -306,11 +312,11 @@ "description": "You can check the start of a path for the Windows extended-length path prefix and if it's not present, replace backslashes with forward slashes.", "example": "path.startsWith('\\\\\\\\?\\\\') ? path : path.replace(/\\\\/g, '/')" }, - "snippet:is-number": { - "id": "snippet:is-number", + "snippet::year": { + "id": "snippet::year", "type": "simple", - "description": "You can check if a value is a number by using `typeof` or coercing it to a number and using `Number.isFinite`.", - "example": "const isNumber = (v) => typeof v === \"number\" || (typeof v === \"string\" && Number.isFinite(+v));" + "description": "You can use `new Date().getUTCFullYear()` to get the current year.", + "example": "new Date().getUTCFullYear()" } }, "mappings": { @@ -482,12 +488,12 @@ "is-number": { "type": "module", "moduleName": "is-number", - "replacements": ["snippet:is-number"] + "replacements": ["snippet::is-number"] }, "is-number-object": { "type": "module", "moduleName": "is-number-object", - "replacements": ["snippet:is-number"] + "replacements": ["snippet::is-number"] }, "is-obj": { "type": "module", @@ -643,6 +649,11 @@ "type": "module", "moduleName": "upper-case", "replacements": ["snippet::to-uppercase"] + }, + "year": { + "type": "module", + "moduleName": "year", + "replacements": ["snippet::year"] } } } diff --git a/scripts/validate-manifests.js b/scripts/validate-manifests.js index 9795f7c..ee94984 100644 --- a/scripts/validate-manifests.js +++ b/scripts/validate-manifests.js @@ -30,31 +30,6 @@ export async function validateManifests() { throw new Error(`Validation for ${manifestPath} failed!`); } - for (const [id, replacement] of Object.entries(manifest.replacements)) { - if (replacement.id !== id) { - throw new Error( - `${manifestPath}: replacement key "${id}" does not match its id property "${replacement.id}"` - ); - } - - if (!replacement.webFeatureId) continue; - - const {featureId, compatKey} = replacement.webFeatureId; - const feature = webFeatures[featureId]; - - if (!feature) { - throw new Error( - `${manifestPath}: replacement "${id}" has unknown webFeatureId.featureId "${featureId}"` - ); - } - - if (!feature.compat_features?.includes(compatKey)) { - throw new Error( - `${manifestPath}: replacement "${id}" has compatKey "${compatKey}" not found in web-features feature "${featureId}"` - ); - } - } - const usedReplacementIds = new Set(); for (const [key, mapping] of Object.entries(manifest.mappings)) { @@ -83,12 +58,41 @@ export async function validateManifests() { } } - for (const id of Object.keys(manifest.replacements)) { + for (const [id, replacement] of Object.entries(manifest.replacements)) { + if (replacement.id !== id) { + throw new Error( + `${manifestPath}: replacement key "${id}" does not match its id property "${replacement.id}"` + ); + } + if (!usedReplacementIds.has(id)) { throw new Error( `${manifestPath}: replacement "${id}" is defined but not used by any mapping.` ); } + + if (replacement.type === 'simple' && !id.startsWith('snippet::')) { + throw new Error( + `${manifestPath}: replacement "${id}" is type "simple" and must start with the "snippet::" prefix.` + ); + } + + if (!replacement.webFeatureId) continue; + + const {featureId, compatKey} = replacement.webFeatureId; + const feature = webFeatures[featureId]; + + if (!feature) { + throw new Error( + `${manifestPath}: replacement "${id}" has unknown webFeatureId.featureId "${featureId}"` + ); + } + + if (!feature.compat_features?.includes(compatKey)) { + throw new Error( + `${manifestPath}: replacement "${id}" has compatKey "${compatKey}" not found in web-features feature "${featureId}"` + ); + } } } console.log('OK');