Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 17 additions & 6 deletions manifests/micro-utilities.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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": {
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -643,6 +649,11 @@
"type": "module",
"moduleName": "upper-case",
"replacements": ["snippet::to-uppercase"]
},
"year": {
"type": "module",
"moduleName": "year",
"replacements": ["snippet::year"]
}
}
}
56 changes: 30 additions & 26 deletions scripts/validate-manifests.js
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {
Expand Down Expand Up @@ -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');
Expand Down