publish.ts 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. #!/usr/bin/env bun
  2. import { Script } from "@opencode-ai/script"
  3. import { $ } from "bun"
  4. import { Effect } from "effect"
  5. import { fileURLToPath } from "url"
  6. const dir = fileURLToPath(new URL("..", import.meta.url))
  7. process.chdir(dir)
  8. type PackageJson = {
  9. name: string
  10. version: string
  11. exports: Record<string, string>
  12. }
  13. const packageJson = (value: unknown) => {
  14. if (
  15. typeof value === "object" &&
  16. value !== null &&
  17. "name" in value &&
  18. typeof value.name === "string" &&
  19. "version" in value &&
  20. typeof value.version === "string" &&
  21. "exports" in value &&
  22. typeof value.exports === "object" &&
  23. value.exports !== null
  24. ) {
  25. return {
  26. name: value.name,
  27. version: value.version,
  28. exports: Object.fromEntries(
  29. Object.entries(value.exports).filter((entry): entry is [string, string] => typeof entry[1] === "string"),
  30. ),
  31. }
  32. }
  33. throw new Error("invalid plugin package manifest")
  34. }
  35. const published = (name: string, version: string) =>
  36. Effect.promise(() => $`npm view ${name}@${version} version`.nothrow()).pipe(
  37. Effect.map((result) => result.exitCode === 0),
  38. )
  39. const withPackageJson = (
  40. pkg: PackageJson,
  41. next: { name: string; version: string; exports: Record<string, { import: string; types: string }> },
  42. ) =>
  43. Effect.promise(() => Bun.write("package.json", JSON.stringify(next, null, 2))).pipe(
  44. Effect.zipRight(Effect.promise(() => $`bun pm pack && npm publish *.tgz --tag ${Script.channel} --access public`)),
  45. Effect.ensuring(Effect.promise(() => Bun.write("package.json", JSON.stringify(pkg, null, 2)))),
  46. )
  47. const program = Effect.gen(function* () {
  48. yield* Effect.promise(() => $`bun tsc`)
  49. const pkg = packageJson(yield* Effect.promise(() => import("../package.json").then((m) => m.default)))
  50. if (yield* published(pkg.name, pkg.version)) {
  51. console.log(`already published ${pkg.name}@${pkg.version}`)
  52. return
  53. }
  54. const next = {
  55. ...pkg,
  56. exports: Object.fromEntries(
  57. Object.entries(pkg.exports).map(([key, value]) => {
  58. const file = value.replace("./src/", "./dist/").replace(".ts", "")
  59. return [key, { import: file + ".js", types: file + ".d.ts" }]
  60. }),
  61. ),
  62. }
  63. yield* withPackageJson(pkg, next)
  64. })
  65. await Effect.runPromise(program)