@flyingboat/upup 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,25 +1,32 @@
1
1
  {
2
2
  "name": "@flyingboat/upup",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "CLI tool for listing outdated dependencies",
5
- "git": "https://github.com/flyingboat/upup",
6
- "key": [
7
- "upup",
5
+ "license": "Apache-2.0",
6
+ "author": "Francois Lajoie",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/flyingboat-dev/upup.git"
10
+ },
11
+ "keywords": [
8
12
  "cli",
9
13
  "tool",
10
14
  "dependencies",
11
15
  "update"
12
16
  ],
13
- "author": "Francois Lajoie",
14
17
  "type": "module",
15
18
  "main": "dist/bundle.js",
19
+ "bin": {
20
+ "upup": "./dist/bundle.js"
21
+ },
22
+ "files": ["dist"],
16
23
  "scripts": {
17
24
  "dev": "node src/main.ts",
18
25
  "build": "rolldown -c rolldown.config.ts"
19
26
  },
20
27
  "packageManager": "pnpm@10.28.2",
21
28
  "devDependencies": {
22
- "@types/node": "^25.1.0",
29
+ "@types/node": "^25.2.0",
23
30
  "rolldown": "^1.0.0-rc.2",
24
31
  "typescript": "~5.9.3"
25
32
  }
package/CHANGELOG.md DELETED
@@ -1,3 +0,0 @@
1
- # 0.1.0
2
-
3
- - Initial release
@@ -1,25 +0,0 @@
1
- {
2
- "dependencies": {
3
- "@flyingboat/form-store-editor-ace": "workspace:*",
4
- "@flyingboat/form-store-api": "workspace:*",
5
- "@tailwindcss/postcss": "^4.1.16",
6
- "@tailwindcss/vite": "^4.1.16",
7
- "@tanstack/nitro-v2-vite-plugin": "^1.133.19",
8
- "@tanstack/router-plugin": "^1.133.36",
9
- "@tanstack/solid-query": "^5.90.8",
10
- "@tanstack/solid-router": "^1.134.1",
11
- "@tanstack/solid-router-devtools": "^1.134.1",
12
- "@tanstack/solid-start": "^1.134.3",
13
- "solid-js": "^1.9.10",
14
- "tailwindcss": "^4.1.16"
15
- },
16
- "devDependencies": {
17
- "daisyui": "^5.3.10",
18
- "postcss": "^8.5.6",
19
- "tailwind-merge": "^3.3.1",
20
- "tailwindcss-animate": "^1.0.7",
21
- "typescript": "^5.9.3",
22
- "vite": "7.1.12",
23
- "vite-plugin-solid": "2.11.10"
24
- }
25
- }
@@ -1,12 +0,0 @@
1
- import { defineConfig } from "rolldown";
2
-
3
- export default defineConfig({
4
- input: "src/main.ts",
5
- output: {
6
- file: "dist/bundle.js",
7
- format: "esm",
8
- },
9
- // For Node CLIs: don't try to bundle Node built-ins
10
- external: [/^node:/],
11
- platform: "node",
12
- });
package/src/cli.ts DELETED
@@ -1,64 +0,0 @@
1
- import type { Dependency } from "./npm.ts";
2
- import { timeAgoFromAge } from "./helpers.ts";
3
-
4
- const defaultRefreshInterval = 80;
5
- export const spinnerFrames = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
6
-
7
- export type RenderProps = {
8
- deps: Row[]
9
- }
10
-
11
- export type Row = {
12
- dep: Dependency,
13
- status: string,
14
- needUpdate: boolean
15
- }
16
-
17
- export class Renderer<TProps = RenderProps> {
18
- private readonly _renderFn: (props: TProps) => void;
19
-
20
- constructor(renderFn: (props: TProps) => void) {
21
- this._renderFn = renderFn;
22
- }
23
-
24
- public render(props: TProps) {
25
- this._renderFn(props);
26
- }
27
- }
28
-
29
- export function spinner(refreshInterval: number = defaultRefreshInterval) {
30
- const i = Math.floor(Date.now() / refreshInterval) % spinnerFrames.length;
31
- return spinnerFrames[i];
32
- }
33
-
34
- export function renderDepsTable(rows: Row[], refreshInterval: number = defaultRefreshInterval) {
35
- const nDeps = rows.filter(x => x.dep.type === 'dep').length;
36
- const nDevDeps = rows.filter(x => x.dep.type === 'devDep').length;
37
- const fn = (r: Row) => {
38
- return {
39
- package: r.dep.name,
40
- current: r.dep.version,
41
- age: r.dep.localDep ? "" : r.dep.versionAge ? timeAgoFromAge(r.dep.versionAge) : spinner(refreshInterval),
42
- latest: r.dep.latestVersion ?? spinner(refreshInterval),
43
- latestAge: r.dep.localDep ? "" : r.dep.latestVersionAge ? timeAgoFromAge(r.dep.latestVersionAge) : spinner(refreshInterval),
44
- status: r.status === "pending" ? spinner(refreshInterval) : r.status === "done" && r.needUpdate ? "need update" : "ok",
45
- }
46
- }
47
- if (nDeps > 0) {
48
- console.log(`${nDeps} Dependencies`);
49
- console.table(
50
- rows.filter(x => x.dep.type === 'dep')
51
- .map((r) => fn(r))
52
- );
53
- }
54
-
55
- if (nDevDeps > 0) {
56
- console.log(`${nDevDeps} Dev Dependencies`);
57
- console.table(
58
- rows.filter(x => x.dep.type === 'devDep')
59
- .map((r) => fn(r))
60
- );
61
- }
62
- }
63
-
64
-
package/src/helpers.ts DELETED
@@ -1,28 +0,0 @@
1
- const minute = 60_000;
2
- const hour = 60 * minute;
3
- const day = 24 * hour;
4
- const year = 365 * day;
5
-
6
- function plural(n: number, unit: string): string {
7
- return `${n} ${unit}${n === 1 ? "" : "s"}`;
8
- }
9
-
10
- export function timeAgoFromAge(ts: number): string {
11
- if (ts < minute) {
12
- return plural(0, "min");
13
- }
14
-
15
- if (ts < hour) {
16
- return plural(Math.floor(ts / minute), "min");
17
- }
18
-
19
- if (ts < day) {
20
- return plural(Math.floor(ts / hour), "hour");
21
- }
22
-
23
- if (ts < year) {
24
- return plural(Math.floor(ts / day), "day");
25
- }
26
-
27
- return plural(Math.floor(ts / year), "year");
28
- }
package/src/main.ts DELETED
@@ -1,73 +0,0 @@
1
- import * as process from "node:process";
2
- import { getLatestVersion, getPackageJsonDeps, getPkgRegistryInfo, getVersionAgeOf } from "./npm.ts";
3
- import { renderDepsTable, Renderer, type RenderProps } from "./cli.ts";
4
-
5
- if (!process || !process.argv) {
6
- console.log("no process");
7
- process.exit(1);
8
- }
9
-
10
- let args: string[] = process.argv
11
- args = args.slice(2);
12
-
13
- let cwd = process.cwd();
14
- if (args.length > 0) {
15
- cwd = args[0];
16
- }
17
-
18
- const refreshInterval = 80;
19
-
20
- async function run() {
21
- const renderer = new Renderer<RenderProps>((props) => {
22
- console.clear();
23
- console.log("Checking for updates...\n");
24
- renderDepsTable(props.deps);
25
- });
26
-
27
- const props: RenderProps = {
28
- deps: getPackageJsonDeps(`${cwd}/package.json`).map((dep) => ({
29
- dep,
30
- needUpdate: false,
31
- status: "pending"
32
- }))
33
- };
34
-
35
- const ticker = setInterval(() => renderer.render(props), refreshInterval);
36
-
37
- const tasks = props.deps.map(async (row) => {
38
- try {
39
- if (row.dep.localDep) {
40
- row.dep.latestVersion = "local";
41
- row.status = "done";
42
- return;
43
- }
44
- const info = await getPkgRegistryInfo(row.dep.name);
45
- row.dep.latestVersion = getLatestVersion(info);
46
- if (row.dep.latestVersion) {
47
- row.dep.latestVersionAge = getVersionAgeOf(info, row.dep.latestVersion);
48
- }
49
- row.dep.versionAge = getVersionAgeOf(info, row.dep.version);
50
- row.needUpdate = row.dep.version !== row.dep.latestVersion;
51
- row.status = "done";
52
- } catch {
53
- row.status = "error";
54
- } finally {
55
- // update as each finishes
56
- renderer.render(props);
57
- }
58
- });
59
-
60
- await Promise.all(tasks);
61
-
62
- clearInterval(ticker);
63
- renderer.render(props); // final render
64
-
65
- const nOutdated = props.deps.filter(x => x.needUpdate).length;
66
- const nUpToDate = props.deps.filter(x => !x.needUpdate).length;
67
- console.log(`\n${nOutdated} outdated, ${nUpToDate} up to date`);
68
- }
69
-
70
- run().catch((err) => {
71
- console.error(err);
72
- process.exit(1);
73
- });
package/src/npm.ts DELETED
@@ -1,84 +0,0 @@
1
- import * as fs from "node:fs";
2
-
3
- export type PackageJson = {
4
- deps: Record<string, string>,
5
- devDeps: Record<string, string>
6
- }
7
-
8
- export type Dependency = {
9
- type: 'dep' | 'devDep',
10
- localDep: boolean,
11
- name: string,
12
- version: string,
13
- versionAge: number | undefined,
14
- info: RegistryInfo | undefined,
15
- latestVersion: string | undefined;
16
- latestVersionAge: number | undefined;
17
- }
18
-
19
- export type RegistryInfo = {
20
- "dist-tags": Record<string, string>,
21
- versions: Record<string, any>[],
22
- time: Record<string, string>
23
- }
24
-
25
- export function getPackageJson(packageJsonPath: string): PackageJson {
26
- const packageJsonContent = fs.readFileSync(packageJsonPath, 'utf-8');
27
- const packageJson = JSON.parse(packageJsonContent);
28
- return {
29
- deps: packageJson.dependencies || {},
30
- devDeps: packageJson.devDependencies || {}
31
- };
32
- }
33
-
34
- export function getPackageJsonDeps(packageJsonPath: string): Dependency[] {
35
- const packageJson = getPackageJson(packageJsonPath);
36
- const deps: Dependency[] = [];
37
- const fn = (entries: Record<string, string>, t: string) => {
38
- for (const [name, version] of Object.entries(entries)) {
39
- const localDep = version.startsWith('file:') || version.startsWith("workspace:");
40
- const v = localDep ? version : normalizeVersion(version);
41
- deps.push({
42
- type: t as Dependency["type"],
43
- localDep,
44
- name,
45
- version: v,
46
- versionAge: undefined,
47
- info: undefined,
48
- latestVersion: undefined,
49
- latestVersionAge: undefined
50
- });
51
- }
52
- }
53
- fn(packageJson.deps, 'dep');
54
- fn(packageJson.devDeps, 'devDep');
55
- return deps;
56
- }
57
-
58
-
59
- // remove first non digit character
60
- export function normalizeVersion(version: string): string {
61
- return version.replace(/^[^0-9]/, '');
62
- }
63
-
64
- export async function getPkgRegistryInfo(pkg: string): Promise<RegistryInfo> {
65
- const url = `https://registry.npmjs.org/${pkg}`;
66
- const response = await fetch(url);
67
- if (!response.ok) {
68
- throw new Error(`Failed to fetch ${url}`);
69
- }
70
- return response.json();
71
- }
72
-
73
- export function getVersionReleaseDateOf(info: RegistryInfo, version: string): string | undefined {
74
- return info.time[version] || undefined;
75
- }
76
-
77
- export function getLatestVersion(info: RegistryInfo): string | undefined {
78
- return info["dist-tags"].latest ?? undefined;
79
- }
80
-
81
- export function getVersionAgeOf(info: RegistryInfo, version: string): number | undefined {
82
- const releaseDate = getVersionReleaseDateOf(info, version);
83
- return releaseDate ? Date.now() - new Date(releaseDate as string).getTime() : undefined;
84
- }
package/tsconfig.json DELETED
@@ -1,26 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2022",
4
- "useDefineForClassFields": true,
5
- "module": "NodeNext",
6
- "lib": ["ES2022", "DOM"],
7
- "types": ["node"],
8
- "skipLibCheck": true,
9
-
10
- /* Bundler mode */
11
- "moduleResolution": "bundler",
12
- "allowImportingTsExtensions": true,
13
- "verbatimModuleSyntax": true,
14
- "moduleDetection": "force",
15
- "noEmit": true,
16
-
17
- /* Linting */
18
- "strict": true,
19
- "noUnusedLocals": true,
20
- "noUnusedParameters": true,
21
- "erasableSyntaxOnly": false,
22
- "noFallthroughCasesInSwitch": true,
23
- "noUncheckedSideEffectImports": true
24
- },
25
- "include": ["src"]
26
- }