Comparing version
#!/usr/bin/env node | ||
require('..').cli(process.argv.slice(2)); | ||
import process from 'process'; | ||
import { cli } from '../lib/cli.js'; | ||
cli(process.argv.slice(2)); |
@@ -1,11 +0,10 @@ | ||
const clipboardy = require('clipboardy'); | ||
const matter = require('gray-matter'); | ||
const { | ||
import clipboardy from 'clipboardy'; | ||
import matter from 'gray-matter'; | ||
import { | ||
containsOnlyAlphanumeric, | ||
removeLocaleFromUrl, | ||
splitHashFromUrl, | ||
addLocaleToUrl | ||
} = require('./util'); | ||
} from './util.js'; | ||
const trackedDomains = [ | ||
export const trackedDomains = [ | ||
'azure.com', | ||
@@ -17,20 +16,23 @@ 'azure.microsoft.com', | ||
'cloudblogs.microsoft.com', | ||
'devblogs.microsoft.com ', | ||
'devblogs.microsoft.com', | ||
'docs.microsoft.com', | ||
'marketplace.visualstudio.com', | ||
'techcommunity.microsoft.com' | ||
'techcommunity.microsoft.com', | ||
'microsoftazurepass.com', | ||
'account.microsoft.com' | ||
]; | ||
const trackingParametersRegex = /wt\.mc_id=\w+-\w+-\w+/gi; | ||
const trackingParam = 'WT.mc_id'; | ||
const urlRegex = /\bhttps?:\/\/[-\w+&@#/%?=~|!:,.;]*[-\w+&@#/%=~|]/gim; | ||
function isTrackedDomain(url) { | ||
const {hostname} = new URL(url); | ||
export function isTrackedDomain(url) { | ||
const { hostname } = new URL(url); | ||
return trackedDomains.some((domain) => hostname.includes(domain)); | ||
} | ||
function checkTrackedDomain(url) { | ||
export function checkTrackedDomain(url) { | ||
if (!isTrackedDomain(url)) throw new Error('URL domain is not tracked'); | ||
} | ||
function mergeTrackingCode(baseTrackingCode, otherTrackingCode) { | ||
export function mergeTrackingCode(baseTrackingCode, otherTrackingCode) { | ||
const base = baseTrackingCode ? parseTrackingCode(baseTrackingCode) : {}; | ||
@@ -48,4 +50,4 @@ const other = otherTrackingCode ? parseTrackingCode(otherTrackingCode) : {}; | ||
function mergeFrontMatterTrackingCode(trackingCode, text) { | ||
const {data} = matter(text); | ||
export function mergeFrontMatterTrackingCode(trackingCode, text) { | ||
const { data } = matter(text); | ||
const code = data.trackingCode || data.tracking_code || data['tracking-code']; | ||
@@ -59,5 +61,10 @@ if (code) { | ||
const generateTrackingParameters = (trackingCode) => `WT.mc_id=${trackingCode}`; | ||
export function generateTrackingParameters(trackingCode, params = {}) { | ||
return new URLSearchParams({ | ||
...params, | ||
[trackingParam]: trackingCode | ||
}).toString(); | ||
} | ||
function parseTrackingCode(partialTrackingCode) { | ||
export function parseTrackingCode(partialTrackingCode) { | ||
if (!partialTrackingCode) throw new Error('no tracking code defined'); | ||
@@ -80,6 +87,6 @@ | ||
return {area, id, alias}; | ||
return { area, id, alias }; | ||
} | ||
function updateTrackedUrl(url, trackingCode, locale) { | ||
export function updateTrackedUrl(url, trackingCode, locale, extraParams = {}) { | ||
if (locale !== true) url = removeLocaleFromUrl(url); | ||
@@ -89,17 +96,19 @@ | ||
const newTrackingParameters = generateTrackingParameters(trackingCode); | ||
if (trackingParametersRegex.test(url)) { | ||
// Update tracking params | ||
return url.replace(trackingParametersRegex, newTrackingParameters); | ||
} | ||
// Add tracking params | ||
const separator = url.indexOf('?') > 0 ? '&' : '?'; | ||
const [baseUrl, hash] = splitHashFromUrl(url); | ||
return baseUrl + separator + newTrackingParameters + hash; | ||
const currentUrl = new URL(url); | ||
const existingParams = Object.fromEntries(currentUrl.searchParams.entries()); | ||
const newTrackingParameters = generateTrackingParameters(trackingCode, { | ||
...existingParams, | ||
...extraParams | ||
}); | ||
currentUrl.search = newTrackingParameters; | ||
return currentUrl.href; | ||
} | ||
function updateTrackedUrlAndCopy(url, trackingCode, locale) { | ||
const newUrl = updateTrackedUrl(url, trackingCode, locale); | ||
export function updateTrackedUrlAndCopy( | ||
url, | ||
trackingCode, | ||
locale, | ||
extraParams | ||
) { | ||
const newUrl = updateTrackedUrl(url, trackingCode, locale, extraParams); | ||
clipboardy.writeSync(newUrl); | ||
@@ -109,21 +118,15 @@ return newUrl; | ||
function updateTrackingCodeInText(text, trackingCode, locale) { | ||
export function updateTrackingCodeInText( | ||
text, | ||
trackingCode, | ||
locale, | ||
extraParams | ||
) { | ||
return text | ||
? text.replace(urlRegex, (url) => | ||
isTrackedDomain(url) ? updateTrackedUrl(url, trackingCode, locale) : url | ||
isTrackedDomain(url) | ||
? updateTrackedUrl(url, trackingCode, locale, extraParams) | ||
: url | ||
) | ||
: text; | ||
} | ||
module.exports = { | ||
trackedDomains, | ||
isTrackedDomain, | ||
checkTrackedDomain, | ||
mergeTrackingCode, | ||
mergeFrontMatterTrackingCode, | ||
generateTrackingParameters, | ||
parseTrackingCode, | ||
updateTrackedUrl, | ||
updateTrackedUrlAndCopy, | ||
updateTrackingCodeInText | ||
}; |
@@ -1,41 +0,28 @@ | ||
const chalk = require('chalk'); | ||
import process from 'process'; | ||
import chalk from 'chalk'; | ||
const containsOnlyAlphanumeric = (string) => /^\w+$/.test(string); | ||
export const containsOnlyAlphanumeric = (string) => /^\w+$/.test(string); | ||
const isUrl = (string) => /^https?:\/\/\w/.test(string); | ||
export const isUrl = (string) => /^https?:\/\/\w/.test(string); | ||
const removeLocaleFromUrl = (url) => | ||
export const removeLocaleFromUrl = (url) => | ||
url.replace(/microsoft.com\/\w{2}-\w{2}\//g, 'microsoft.com/'); | ||
const addLocaleToUrl = (url, locale) => | ||
export const addLocaleToUrl = (url, locale) => | ||
locale ? url.replace(/microsoft.com\//g, `microsoft.com/${locale}/`) : url; | ||
function checkLocale(locale) { | ||
export const parseQueryParams = (queryString) => | ||
Object.fromEntries(new URLSearchParams(queryString).entries()); | ||
export function checkLocale(locale) { | ||
if (!/^\w{2}-\w{2}$/.test(locale)) throw new Error('Invalid locale format'); | ||
} | ||
function splitHashFromUrl(url) { | ||
const hashIndex = url.indexOf('#'); | ||
return hashIndex === -1 | ||
? [url, ''] | ||
: [url.slice(0, hashIndex), url.slice(hashIndex)]; | ||
} | ||
function safeRun(func) { | ||
export function safeRun(func) { | ||
try { | ||
return func() || true; | ||
} catch (error) { | ||
console.error(chalk`{yellow Error: ${error.message}}`); | ||
console.error(chalk.yellow`Error: ${error.message}`); | ||
process.exitCode = -1; | ||
} | ||
} | ||
module.exports = { | ||
containsOnlyAlphanumeric, | ||
isUrl, | ||
removeLocaleFromUrl, | ||
addLocaleToUrl, | ||
checkLocale, | ||
splitHashFromUrl, | ||
safeRun | ||
}; |
{ | ||
"name": "cxa-track", | ||
"version": "1.3.0", | ||
"version": "2.0.0", | ||
"description": "Convenient CLI to quickly update CxA tracked links", | ||
"preferGlobal": true, | ||
"repository": "sinedied/cxa-track", | ||
"homepage": "https://github.com/sinedied/cxa-track", | ||
"bugs": { | ||
"url": "https://github.com/sinedied/cxa-track/issues" | ||
"type": "module", | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/sinedied/cxa-track" | ||
}, | ||
"keywords": [ | ||
"cli", | ||
"cxa", | ||
"advocate", | ||
"microsoft", | ||
"links" | ||
], | ||
"main": "cli.js", | ||
"exports": "./lib/index.js", | ||
"bin": { | ||
@@ -23,8 +15,9 @@ "cxa": "./bin/cxa.js" | ||
"scripts": { | ||
"commit": "git-cz", | ||
"lint": "xo", | ||
"lint:fix": "xo --fix", | ||
"test": "xo && jest --verbose", | ||
"test:watch": "jest --watch", | ||
"release:check": "semantic-release --dry-run" | ||
"test": "xo && npm run -s test:unit", | ||
"test:unit": "cross-env NODE_OPTIONS=--experimental-vm-modules jest --verbose", | ||
"test:watch": "npm run -s test:unit -- --watch", | ||
"release:check": "semantic-release --dry-run", | ||
"prepare": "husky install" | ||
}, | ||
@@ -35,26 +28,38 @@ "author": { | ||
}, | ||
"homepage": "https://github.com/sinedied/cxa-track", | ||
"bugs": { | ||
"url": "https://github.com/sinedied/cxa-track/issues" | ||
}, | ||
"keywords": [ | ||
"cli", | ||
"cxa", | ||
"advocate", | ||
"microsoft", | ||
"links" | ||
], | ||
"license": "MIT", | ||
"dependencies": { | ||
"chalk": "^4.1.0", | ||
"clipboardy": "^2.3.0", | ||
"conf": "^7.1.2", | ||
"chalk": "^5.0.1", | ||
"clipboardy": "^3.0.0", | ||
"conf": "^10.2.0", | ||
"gray-matter": "^4.0.2", | ||
"minimist": "^1.2.5", | ||
"update-notifier": "^5.0.1" | ||
"update-notifier": "^6.0.2" | ||
}, | ||
"devDependencies": { | ||
"@commitlint/cli": "^11.0.0", | ||
"@commitlint/config-conventional": "^11.0.0", | ||
"commitizen": "^4.2.2", | ||
"cz-conventional-changelog": "^3.3.0", | ||
"husky": "^4.3.7", | ||
"jest": "^26.6.3", | ||
"lint-staged": "^10.5.3", | ||
"semantic-release": "^17.3.1", | ||
"semantic-release-npm-github": "^1.0.2", | ||
"xo": "^0.37.1" | ||
"cross-env": "^7.0.3", | ||
"husky": "^8.0.1", | ||
"jest": "^28.1.3", | ||
"lint-staged": "^13.0.3", | ||
"semantic-release": "^19.0.3", | ||
"semantic-release-npm-github": "^3.0.0", | ||
"xo": "^0.51.0" | ||
}, | ||
"engines": { | ||
"node": ">=12.0.0" | ||
"node": ">=14.0.0" | ||
}, | ||
"prettier": { | ||
"trailingComma": "none", | ||
"bracketSpacing": true | ||
}, | ||
"xo": { | ||
@@ -66,3 +71,7 @@ "space": true, | ||
"jest" | ||
] | ||
], | ||
"rules": { | ||
"unicorn/prevent-abbreviations": "off", | ||
"unicorn/prefer-node-protocol": "off" | ||
} | ||
}, | ||
@@ -77,9 +86,5 @@ "jest": { | ||
], | ||
"resolver": "<rootDir>/test/jest.resolver.cjs", | ||
"silent": true | ||
}, | ||
"commitlint": { | ||
"extends": [ | ||
"@commitlint/config-conventional" | ||
] | ||
}, | ||
"lint-staged": { | ||
@@ -95,13 +100,2 @@ "*.js": [ | ||
}, | ||
"husky": { | ||
"hooks": { | ||
"precommit": "lint-staged", | ||
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS" | ||
} | ||
}, | ||
"config": { | ||
"commitizen": { | ||
"path": "cz-conventional-changelog" | ||
} | ||
}, | ||
"files": [ | ||
@@ -108,0 +102,0 @@ "index.js", |
@@ -27,3 +27,3 @@ # :memo: cxa-track | ||
```sh | ||
``` | ||
Usage: cxa [options] [<files|URL>] | ||
@@ -39,2 +39,3 @@ | ||
-l, --locale <locale-code> Force locale code in URLs | ||
-e, --extra Extra query params to update | ||
-h, --help Show this help | ||
@@ -48,2 +49,3 @@ | ||
Locale format: <language>-<country>, example: en-us | ||
Extra format: <param1>=<value1>&<param2>=<value2>, example: foo=bar&baz=qux | ||
``` | ||
@@ -50,0 +52,0 @@ |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
7
-30%343
6.52%69
2.99%2
-33.33%Yes
NaN17188
-8.33%7
-12.5%1
Infinity%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
Updated
Updated
Updated
Updated