From 77e916d209f303a1595f4c549beb17fdeb120aa3 Mon Sep 17 00:00:00 2001 From: Huakun Shen Date: Sat, 18 Jan 2025 22:24:42 -0500 Subject: [PATCH] init hacker news --- .github/workflows/npm-publish.yml | 44 ++++++++ .gitignore | 175 ++++++++++++++++++++++++++++++ README.md | 4 + build.ts | 20 ++++ bun.lockb | Bin 0 -> 63304 bytes package.json | 59 ++++++++++ src/index.ts | 158 +++++++++++++++++++++++++++ tsconfig.json | 24 ++++ 8 files changed, 484 insertions(+) create mode 100644 .github/workflows/npm-publish.yml create mode 100644 .gitignore create mode 100644 README.md create mode 100644 build.ts create mode 100755 bun.lockb create mode 100644 package.json create mode 100644 src/index.ts create mode 100644 tsconfig.json diff --git a/.github/workflows/npm-publish.yml b/.github/workflows/npm-publish.yml new file mode 100644 index 0000000..f55d9ed --- /dev/null +++ b/.github/workflows/npm-publish.yml @@ -0,0 +1,44 @@ +# This workflow will run tests using node and then publish a package to GitHub Packages when a release is created +# For more information see: https://docs.github.com/en/actions/publishing-packages/publishing-nodejs-packages + +name: NPM Package Publish + +on: + push: + branches: [main] + release: + types: [created] + workflow_dispatch: + +jobs: + publish-npm: + runs-on: ubuntu-latest + permissions: + contents: read + id-token: write + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: 22 + registry-url: https://registry.npmjs.org/ + - uses: oven-sh/setup-bun@v2 + - run: bun install + - run: bun run build + - run: | + PACKAGE_NAME=$(jq -r '.name' package.json) + PACKAGE_VERSION=$(jq -r '.version' package.json) + + # Get the version from npm registry + REGISTRY_VERSION=$(npm show "$PACKAGE_NAME" version) + + # Compare versions + if [ "$PACKAGE_VERSION" == "$REGISTRY_VERSION" ]; then + echo "Version $PACKAGE_VERSION already exists in the npm registry." + exit 0 + else + echo "Version $PACKAGE_VERSION does not exist in the npm registry. Proceeding..." + npm publish --provenance --access public + fi + env: + NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9b1ee42 --- /dev/null +++ b/.gitignore @@ -0,0 +1,175 @@ +# Based on https://raw.githubusercontent.com/github/gitignore/main/Node.gitignore + +# Logs + +logs +_.log +npm-debug.log_ +yarn-debug.log* +yarn-error.log* +lerna-debug.log* +.pnpm-debug.log* + +# Caches + +.cache + +# Diagnostic reports (https://nodejs.org/api/report.html) + +report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json + +# Runtime data + +pids +_.pid +_.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover + +lib-cov + +# Coverage directory used by tools like istanbul + +coverage +*.lcov + +# nyc test coverage + +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) + +.grunt + +# Bower dependency directory (https://bower.io/) + +bower_components + +# node-waf configuration + +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) + +build/Release + +# Dependency directories + +node_modules/ +jspm_packages/ + +# Snowpack dependency directory (https://snowpack.dev/) + +web_modules/ + +# TypeScript cache + +*.tsbuildinfo + +# Optional npm cache directory + +.npm + +# Optional eslint cache + +.eslintcache + +# Optional stylelint cache + +.stylelintcache + +# Microbundle cache + +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history + +.node_repl_history + +# Output of 'npm pack' + +*.tgz + +# Yarn Integrity file + +.yarn-integrity + +# dotenv environment variable files + +.env +.env.development.local +.env.test.local +.env.production.local +.env.local + +# parcel-bundler cache (https://parceljs.org/) + +.parcel-cache + +# Next.js build output + +.next +out + +# Nuxt.js build / generate output + +.nuxt +dist + +# Gatsby files + +# Comment in the public line in if your project uses Gatsby and not Next.js + +# https://nextjs.org/blog/next-9-1#public-directory-support + +# public + +# vuepress build output + +.vuepress/dist + +# vuepress v2.x temp and cache directory + +.temp + +# Docusaurus cache and generated files + +.docusaurus + +# Serverless directories + +.serverless/ + +# FuseBox cache + +.fusebox/ + +# DynamoDB Local files + +.dynamodb/ + +# TernJS port file + +.tern-port + +# Stores VSCode versions used for testing VSCode extensions + +.vscode-test + +# yarn v2 + +.yarn/cache +.yarn/unplugged +.yarn/build-state.yml +.yarn/install-state.gz +.pnp.* + +# IntelliJ based IDEs +.idea + +# Finder (MacOS) folder config +.DS_Store diff --git a/README.md b/README.md new file mode 100644 index 0000000..498dd6a --- /dev/null +++ b/README.md @@ -0,0 +1,4 @@ +## Kunkun Extension Hacker News + + + diff --git a/build.ts b/build.ts new file mode 100644 index 0000000..6a7ba8f --- /dev/null +++ b/build.ts @@ -0,0 +1,20 @@ +import { watch } from "fs" +import { join } from "path" +import { refreshTemplateWorkerExtension } from "@kksh/api/dev" +import { $ } from "bun" + +async function build() { + await $`bun build --minify --target=browser --outdir=./dist ./src/index.ts` + await refreshTemplateWorkerExtension() +} + +const srcDir = join(import.meta.dir, "src") + +await build() + +if (Bun.argv.includes("dev")) { + console.log(`Watching ${srcDir} for changes...`) + watch(srcDir, { recursive: true }, async (event, filename) => { + await build() + }) +} diff --git a/bun.lockb b/bun.lockb new file mode 100755 index 0000000000000000000000000000000000000000..6b0a51068a20843e9bb78b00088e1c4f3df81970 GIT binary patch literal 63304 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 + +function hackerNewsItemToListItem(item: HackerNewsItem, idx: number): List.Item { + return new List.Item({ + title: item.title, + value: item.title, + subTitle: `${item.by}`, + icon: new Icon({ type: IconEnum.Text, value: (idx + 1).toString() }), + keywords: [item.by], + accessories: [ + new List.ItemAccessory({ + icon: new Icon({ + type: IconEnum.Iconify, + value: "fa6-regular:circle-up" + }), + text: `${item.score}` + }) + ], + defaultAction: "Open", + actions: new Action.ActionPanel({ + items: [ + new Action.Action({ + title: "Open", + icon: new Icon({ type: IconEnum.Iconify, value: "ion:open-outline" }), + value: "open" + }) + ] + }) + }) +} + +class HackerNews extends WorkerExtension { + items: HackerNewsItem[] + listitems: List.Item[] + storyIds: number[] + value?: string + + constructor() { + super() + this.items = [] + this.listitems = [] + this.storyIds = [] + } + + onActionSelected(actionValue: string): Promise { + switch (actionValue) { + case "open": + const target = this.items.find((item) => item.title === this.value) + if (target) { + if (target.url) { + return open.url(target.url) + } + } + toast.error("Item not found") + break + default: + break + } + return Promise.resolve() + } + async onListScrolledToBottom(): Promise { + await ui.setScrollLoading(true) + return Promise.all( + this.storyIds + .slice(this.items.length, this.items.length + 20) + .map((id) => + fetch(`https://hacker-news.firebaseio.com/v0/item/${id}.json`).then((res) => res.json()) + ) + ) + .then((stories) => { + const parsed = safeParse(array(HackerNewsItem), stories) + if (parsed.issues) { + for (const issue of parsed.issues) { + toast.error(issue.message) + } + return + } + this.items = this.items.concat(parsed.output) + this.listitems = this.items.map(hackerNewsItemToListItem) + return ui.render(new List.List({ items: this.listitems })) + }) + .then(() => ui.setScrollLoading(false)) + } + async load(): Promise { + return ui + .setSearchBarPlaceholder("Scroll down to load more...") + .then(() => fetch("https://hacker-news.firebaseio.com/v0/topstories.json")) + .then((res) => res.json()) + .then((data) => { + const storyIds = parse(array(number()), data) + this.storyIds = storyIds + return Promise.all( + this.storyIds + .slice(0, 20) + .map((id) => + fetch(`https://hacker-news.firebaseio.com/v0/item/${id}.json`).then((res) => + res.json() + ) + ) + ) + }) + .then((stories) => { + const parsed = safeParse(array(HackerNewsItem), stories) + if (parsed.issues) { + for (const issue of parsed.issues) { + toast.error(issue.message) + } + return + } + this.items = parsed.output + this.listitems = this.items.map(hackerNewsItemToListItem) + return ui.render( + new List.List({ + items: this.listitems + + // detail: new List.ItemDetail({width: 50, children: [ + // new Markdown(`# Hacker News\n1. hello\n2. world\n\n**bold**`) + // ]}) + }) + ) + }) + .catch((err) => { + console.error(err) + }) + } + + onListItemSelected(value: string): Promise { + const target = this.items.find((item) => item.title === value) + if (target) { + if (target.url) { + return open.url(target.url) + } + } + toast.error("Item not found") + return Promise.resolve() + } +} + +expose(new HackerNews()) diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..5905e7a --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,24 @@ +{ + "compilerOptions": { + "target": "es2021", + "module": "esnext", + "moduleResolution": "Bundler", + "skipLibCheck": true, + "strict": true, + "noUnusedLocals": false, + "noImplicitAny": true, + "noEmit": true, + "outDir": "dist", + "baseUrl": ".", + "esModuleInterop": true, + "allowSyntheticDefaultImports": false, + "verbatimModuleSyntax": true, + }, + "include": [ + "." + ], + "exclude": [ + "dist", + "node_modules" + ] +} \ No newline at end of file