├── .vscode └── settings.json ├── types ├── importType.ts └── dependencyType.ts ├── constants └── commands.ts ├── .github └── ISSUE_TEMPLATE │ ├── custom.md │ ├── feature_request.md │ └── bug_report.md ├── example_map.json ├── .gitattributes ├── import_map.json ├── main.ts ├── version.ts ├── README.md ├── LICENSE ├── help.ts └── file.ts /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "cSpell.words": [ 3 | "soxa" 4 | ] 5 | } -------------------------------------------------------------------------------- /types/importType.ts: -------------------------------------------------------------------------------- 1 | export type importsType = { 2 | imports: {}; 3 | }; 4 | -------------------------------------------------------------------------------- /constants/commands.ts: -------------------------------------------------------------------------------- 1 | export const HELP_COMMANDS = ["-help", "-h"]; 2 | export const FILE_COMMANDS = ["-file", "-f"]; 3 | -------------------------------------------------------------------------------- /types/dependencyType.ts: -------------------------------------------------------------------------------- 1 | export type dependencyType = { 2 | name: string, 3 | module: string, 4 | version: string, 5 | url: string, 6 | latest?: string, 7 | upToDate?: boolean 8 | } 9 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/custom.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Custom issue template 3 | about: Describe this issue template's purpose here. 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | 11 | -------------------------------------------------------------------------------- /example_map.json: -------------------------------------------------------------------------------- 1 | { 2 | "imports": { 3 | "soxa/": "https://deno.land/x/soxa@1.4/", 4 | "soxa2/": "https://deno.land/x/soxa@v1.1/", 5 | "checksum": "https://deno.land/x/checksum@1.2.0", 6 | "http": "https://deno.land/std@0.51.0/http/" 7 | } 8 | } -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | *.* text eol=lf 3 | *.doc binary 4 | *.docx binary 5 | *.eot binary 6 | *.jar binary 7 | *.jks binary 8 | *.jpeg binary 9 | *.jpg binary 10 | *.pdf binary 11 | *.png binary 12 | *.ttf binary 13 | *.vsd binary 14 | *.woff2 binary 15 | *.woff binary 16 | *.xls binary 17 | *.zip binary 18 | -------------------------------------------------------------------------------- /import_map.json: -------------------------------------------------------------------------------- 1 | { 2 | "imports": { 3 | "http/": "https://deno.land/std@0.51.0/http/", 4 | "http2/": "https://deno.land/std@0.50.0/http/", 5 | "http3/": "https://deno.land/std@0.52.0/http/", 6 | "soxa/": "https://deno.land/x/soxa@1.4/", 7 | "soxa2/": "https://deno.land/x/soxa@v0.4/", 8 | "deno-chunked/": "https://deno.land/x/deno-chunked/", 9 | "checksum": "https://deno.land/x/checksum@1.2.0", 10 | "curve": "https://deno.land/x/curve25519@v0.2.0", 11 | "moment/": "https://deno.land/x/moment/" 12 | } 13 | } -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /main.ts: -------------------------------------------------------------------------------- 1 | import { HELP_COMMANDS, FILE_COMMANDS } from './constants/commands.ts'; 2 | import { help } from './help.ts'; 3 | import { readDependencies } from './file.ts'; 4 | import { addLatestVersions } from './version.ts' 5 | 6 | async function main(args: string[]) { 7 | if (args.length > 0) { 8 | const mainArgument = args[0]; 9 | if (HELP_COMMANDS.includes(mainArgument)) { 10 | help(); 11 | } else if (FILE_COMMANDS.includes(mainArgument)) { 12 | if (args[1]) { 13 | let dependencies = await readDependencies(args[1]); 14 | if (dependencies) { 15 | dependencies = await addLatestVersions(dependencies); 16 | } 17 | console.log('***** List of dependencies *****'); 18 | console.table(dependencies); 19 | } 20 | } 21 | } else { 22 | console.debug("No arguments are passed ..."); 23 | } 24 | } 25 | 26 | if (import.meta.main) { 27 | await main(Deno.args); 28 | } 29 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /version.ts: -------------------------------------------------------------------------------- 1 | // We handle the methods to look for the latest versions 2 | import { dependencyType } from "./types/dependencyType.ts"; 3 | import { soxa } from 'https://deno.land/x/soxa/mod.ts'; 4 | 5 | export async function addLatestVersions(dependencies: dependencyType[]): Promise { 6 | return await Promise.all(dependencies.map(async (dependency: dependencyType) => { 7 | const url = `https://cdn.deno.land/${dependency.module}/meta/versions.json`; 8 | return await getVersionFromUrl(dependency, url); 9 | })); 10 | } 11 | 12 | async function getVersionFromUrl(dependency: dependencyType, url: string): Promise { 13 | const versionsList = await soxa.get(url) 14 | .catch((error) => { 15 | console.error('Error getting the latest dependency ', error); 16 | }); 17 | if (versionsList.data) { 18 | dependency.latest = versionsList.data.latest; 19 | dependency.upToDate = versionsList.data.latest === dependency.version; 20 | } else { 21 | dependency.latest = "not found"; 22 | } 23 | return dependency; 24 | } 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # deno-check-updates 2 | Automatically checks deno dependencies versions 3 | 4 | ## Help 5 | deno run -A https://deno.land/x/deno_check_updates/main.ts -h 6 | 7 | ## Check updates 8 | ```shell 9 | $ deno run -A https://deno.land/x/deno_check_updates/main.ts -f example_map.json 10 | ``` 11 | 12 | ## Example output 13 | For this input file : 14 | 15 | ```json 16 | { 17 | "imports": { 18 | "soxa/": "https://deno.land/x/soxa@1.4/", 19 | "soxa2/": "https://deno.land/x/soxa@v0.4/", 20 | "checksum": "https://deno.land/x/checksum@1.2.0", 21 | "http": "https://deno.land/std@0.51.0/http/" 22 | } 23 | } 24 | ``` 25 | 26 | | name | module | url | version | latest | upToDate 27 | | :---:| :-----: | :--: | :-----: | :----: | :----: | 28 | | soxa | soxa | "https://deno.land/x/soxa@1.4/" | "1.4" | "1.4" | true 29 | | soxa2 | soxa | "https://deno.land/x/soxa@v1.0/" | "v1.1" | "v1.1" | true 30 | | checksum | checksum | "https://deno.land/x/checksum@1.2.0" | "v1.2.0" | "v1.4.0" | false 31 | | http | std | "https://deno.land/std@0.51.0/http/" | "v0.51.0" | "v0.52.0" | false 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Wael Fezai 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /help.ts: -------------------------------------------------------------------------------- 1 | export function help(): void { 2 | console.log(` 3 | ██████  ███████ ███  ██  ██████  ██████ ██  ██ ███████  ██████ ██  ██  ██  ██ ██████  ██████  █████  ████████ ███████ ███████  4 | ██   ██ ██      ████  ██ ██    ██  ██      ██  ██ ██      ██      ██  ██   ██  ██ ██   ██ ██   ██ ██   ██    ██    ██      ██       5 | ██  ██ █████  ██ ██  ██ ██  ██  ██  ███████ █████  ██  █████   ██  ██ ██████  ██  ██ ███████  ██  █████  ███████  6 | ██  ██ ██     ██  ██ ██ ██  ██  ██  ██   ██ ██     ██  ██  ██  ██  ██ ██      ██  ██ ██   ██  ██  ██          ██  7 | ██████  ███████ ██   ████  ██████    ██████ ██  ██ ███████  ██████ ██  ██   ██████  ██  ██████  ██  ██  ██  ███████ ███████  8 | `); 9 | 10 | console.log(` 11 | Help manual - Using the plugin is very simple type the following command : 12 | deno run -A --unstable https://deno.land/x/deno_check_updates/main.ts -f import_map.json 13 | 14 | Where import_map.json is your imports map file. 15 | The result is a logged table with details on which modules needs to be updated. 16 | `); 17 | 18 | } 19 | -------------------------------------------------------------------------------- /file.ts: -------------------------------------------------------------------------------- 1 | import { importsType } from "./types/importType.ts"; 2 | import { dependencyType } from "./types/dependencyType.ts"; 3 | 4 | export async function readDependencies(filename: string): Promise { 5 | try { 6 | const fileContent = JSON.parse(await Deno.readTextFile(filename)) as importsType; 7 | return extractDependencyAndVersion(fileContent.imports); 8 | } catch (err) { 9 | console.error("Cant read imports file !"); 10 | return []; 11 | } 12 | } 13 | 14 | function extractDependencyAndVersion(imports: object): dependencyType[] { 15 | let result: dependencyType[] = []; 16 | for (const [key, value] of Object.entries(imports)) { 17 | // TODO find cleaner solution to extract version 18 | const substr = value.substring(value.indexOf("@") + 1); 19 | const exactVersion = (substr.indexOf("/") > -1) ? substr.substring(0, substr.indexOf("/")) : substr; 20 | // In case if there is an extra backslash at the end of the dependency name 21 | const exactName = (key.indexOf('/') > -1) ? key.substring(0, key.lastIndexOf('/')) : key; 22 | // Find the correct module name 23 | const moduleUrl = value.substring(0, value.lastIndexOf("@")); 24 | const moduleName = moduleUrl.slice(moduleUrl.lastIndexOf("/") + 1); 25 | if (exactName && moduleName && value && exactVersion) { 26 | result.push({ 27 | name: exactName, 28 | module: moduleName, 29 | url: value, 30 | version: exactVersion, 31 | }); 32 | } else { 33 | console.warn('Could not find all information about module ', value, ' Skipping module.'); 34 | } 35 | } 36 | return result; 37 | } 38 | --------------------------------------------------------------------------------