-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
86c17e1
commit f1abc9e
Showing
11 changed files
with
327 additions
and
37 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,33 +1,41 @@ | ||
name: CI | ||
|
||
on: | ||
push: | ||
branches: | ||
- main | ||
|
||
jobs: | ||
publish: | ||
ci: | ||
name: CI | ||
runs-on: ubuntu-latest | ||
permissions: | ||
contents: read | ||
id-token: write | ||
steps: | ||
- name: Checkout repository | ||
- name: Check out repository | ||
uses: actions/checkout@v4 | ||
|
||
- name: Set up Deno | ||
uses: denoland/setup-deno@v1 | ||
uses: denoland/setup-deno@v2 | ||
with: | ||
deno-version: v1.x | ||
|
||
deno-version: v2.x | ||
- name: Set up Node.js | ||
uses: actions/setup-node@v4 | ||
with: | ||
node-version: '22.x' | ||
registry-url: 'https://registry.npmjs.org' | ||
- name: Format | ||
run: deno fmt --check | ||
|
||
- name: Lint | ||
run: deno lint | ||
|
||
- name: Check | ||
run: deno task check | ||
|
||
- name: Publish to JSR | ||
run: deno publish | ||
- name: Type-check | ||
run: deno check --frozen **/*.ts | ||
- name: Run tests | ||
run: deno test --permit-no-files | ||
- name: Generate jsr.json | ||
run: deno run --allow-read=. --allow-run=deno scripts/generate-package-manifest.ts --type=jsr | tee jsr.json | ||
- name: Dry run publish to JSR | ||
run: deno publish --config=jsr.json --dry-run | ||
- name: Generate package.json | ||
run: deno run --allow-read=. --allow-run=deno scripts/generate-package-manifest.ts --type=npm | tee package.json | ||
- name: Install dependencies | ||
run: deno install | ||
- name: Build | ||
run: deno task --eval "tsc -b" | ||
- name: Dry run publish to NPM | ||
run: npm publish --dry-run |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
name: Publish | ||
on: | ||
release: | ||
types: [published] | ||
jobs: | ||
publish-jsr: | ||
name: Publish to JSR | ||
runs-on: ubuntu-latest | ||
permissions: | ||
contents: read | ||
id-token: write | ||
steps: | ||
- name: Check out repository | ||
uses: actions/checkout@v4 | ||
- name: Set up Deno | ||
uses: denoland/setup-deno@v2 | ||
with: | ||
deno-version: v2.x | ||
- name: Generate jsr.json | ||
run: deno run --allow-read=. --allow-run=deno scripts/generate-package-manifest.ts --type=jsr | tee jsr.json | ||
- name: Publish to JSR | ||
run: deno publish --config=jsr.json | ||
publish-npm: | ||
name: Publish to NPM | ||
runs-on: ubuntu-latest | ||
permissions: | ||
contents: read | ||
id-token: write | ||
steps: | ||
- name: Check out repository | ||
uses: actions/checkout@v4 | ||
- name: Set up Deno | ||
uses: denoland/setup-deno@v2 | ||
with: | ||
deno-version: v2.x | ||
- name: Set up Node.js | ||
uses: actions/setup-node@v4 | ||
with: | ||
node-version: '22.x' | ||
registry-url: 'https://registry.npmjs.org' | ||
- name: Generate package.json | ||
run: deno run --allow-read=. --allow-run=deno scripts/generate-package-manifest.ts --type=npm | tee package.json | ||
- name: Install dependencies | ||
run: deno install | ||
- name: Build | ||
run: deno task --eval "tsc -b" | ||
- name: Publish to NPM | ||
run: npm publish --provenance --access public | ||
env: | ||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,5 @@ | ||
deno.lock | ||
dist | ||
jsr.json | ||
package.json | ||
node_modules | ||
tsconfig.tsbuildinfo |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,23 +1,21 @@ | ||
{ | ||
"name": "@quentinadam/zip", | ||
"version": "0.1.3", | ||
"description": "A library for creating and extracting ZIP archives", | ||
"license": "MIT", | ||
"exports": "./zip.ts", | ||
"exports": "./src/zip.ts", | ||
"imports": { | ||
"@quentinadam/assert": "jsr:@quentinadam/assert@^0.1.7", | ||
"@quentinadam/uint8array-extension": "jsr:@quentinadam/uint8array-extension@^0.1.4" | ||
}, | ||
"publish": { | ||
"exclude": [ | ||
".github/", | ||
".vscode/" | ||
] | ||
"@quentinadam/assert": "jsr:@quentinadam/assert@^0.1.10", | ||
"@quentinadam/require": "jsr:@quentinadam/require@^0.1.4", | ||
"@quentinadam/uint8array-extension": "jsr:@quentinadam/uint8array-extension@^0.1.5", | ||
"typescript": "npm:typescript@^5.7.2" | ||
}, | ||
"fmt": { | ||
"singleQuote": true, | ||
"lineWidth": 120 | ||
}, | ||
"tasks": { | ||
"check": "deno check **/*.ts" | ||
"compilerOptions": { | ||
"noUncheckedIndexedAccess": true, | ||
"noImplicitReturns": true | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
type Graph = { | ||
version: number; | ||
roots: string[]; | ||
modules: ({ kind: 'external'; specifier: string } | { | ||
kind: 'esm'; | ||
dependencies?: { specifier: string; code?: { specifier: string } }[]; | ||
specifier: string; | ||
})[]; | ||
}; | ||
|
||
function assert(value: boolean): asserts value { | ||
if (value !== true) { | ||
throw new Error('Assertion failed'); | ||
} | ||
} | ||
|
||
function require<T>(value: T | undefined | null): T { | ||
assert(value !== undefined && value !== null); | ||
return value; | ||
} | ||
|
||
function parsePackageSpecifier(specifier: string) { | ||
// deno-fmt-ignore | ||
const regex = /^(:?(?<registry>jsr|npm):\/?)?(?<name>(?:@[a-zA-Z0-9_\-]+\/)?[a-zA-Z0-9_\-]+)(?:@(?<version>(?:\*|(?:\^|~|[<>]=?)?\d+(?:\.\d+)*)))?(?<path>(\/[^\/]+)+)?$/; | ||
const match = specifier.match(regex); | ||
if (match !== null) { | ||
const groups = require(match.groups); | ||
const registry = groups.registry; | ||
const name = require(groups.name); | ||
const version = groups.version; | ||
const path = groups.path; | ||
return { registry, name, version, path }; | ||
} | ||
return undefined; | ||
} | ||
|
||
class GraphAnalyzer { | ||
readonly #graph: Graph; | ||
readonly #specifiers: Set<string>; | ||
|
||
constructor(graph: Graph, specifiers: Set<string>) { | ||
this.#graph = graph; | ||
this.#specifiers = specifiers; | ||
} | ||
|
||
analyze(specifier: string) { | ||
const module = require(this.#graph.modules.find((module) => module.specifier === specifier)); | ||
if (module.kind === 'esm' && module.dependencies !== undefined) { | ||
for (const dependency of module.dependencies) { | ||
const parsedPackageSpecifier = parsePackageSpecifier(dependency.specifier); | ||
if (parsedPackageSpecifier !== undefined) { | ||
this.#specifiers.add(parsedPackageSpecifier.name); | ||
} else if (dependency.code !== undefined) { | ||
this.analyze(dependency.code.specifier); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
export default async function getExportsDependencies() { | ||
const exports = require(configurationFile.exports); | ||
const exportedPaths = (typeof exports === 'string') ? [exports] : Object.values(exports); | ||
const specifiers = new Set<string>(); | ||
for (const path of exportedPaths) { | ||
const command = new Deno.Command('deno', { args: ['info', '--json', path] }); | ||
const { code, stdout, stderr } = await command.output(); | ||
if (code !== 0) { | ||
throw new Error(new TextDecoder().decode(stderr)); | ||
} | ||
const graph = JSON.parse(new TextDecoder().decode(stdout)) as Graph; | ||
const analyzer = new GraphAnalyzer(graph, specifiers); | ||
analyzer.analyze(require(graph.roots[0])); | ||
} | ||
if (specifiers.size > 0) { | ||
const imports = configurationFile.imports as Record<string, string> | undefined; | ||
assert(imports !== undefined); | ||
return Array.from(specifiers).toSorted().map((specifier) => { | ||
const parsedPackageSpecifier = require(parsePackageSpecifier(require(imports[specifier]))); | ||
const { registry, name, version } = parsedPackageSpecifier; | ||
assert(registry !== undefined); | ||
assert(version !== undefined); | ||
return { registry, name, version }; | ||
}); | ||
} | ||
return []; | ||
} | ||
|
||
type ConfigurationFile = { | ||
name: string; | ||
version: string; | ||
description: string; | ||
license: string; | ||
exports?: string | Record<string, string>; | ||
imports?: Record<string, string>; | ||
}; | ||
|
||
const type = (() => { | ||
try { | ||
return require(require(require(Deno.args[0]).match(/^--type=(jsr|npm)$/))[1]); | ||
} catch { | ||
throw new Error('Missing or invalid type argument'); | ||
} | ||
})(); | ||
|
||
const configurationFile: ConfigurationFile = JSON.parse(Deno.readTextFileSync('deno.json')); | ||
|
||
const dependencies = await getExportsDependencies(); | ||
|
||
const scopedName = require(configurationFile.name); | ||
const name = require(scopedName.split('/')[1]); | ||
|
||
const manifest = (() => { | ||
if (type === 'jsr') { | ||
return { | ||
name: scopedName, | ||
version: require(configurationFile.version), | ||
license: require(configurationFile.license), | ||
exports: require(configurationFile.exports), | ||
publish: { include: ['src', 'README.md'], exclude: ['**/*.test.ts'] }, | ||
imports: dependencies.length > 0 | ||
? Object.fromEntries(dependencies.map(({ name, registry, version }) => { | ||
return [name, `${registry}:${name}@${version}`]; | ||
})) | ||
: undefined, | ||
}; | ||
} | ||
if (type === 'npm') { | ||
return { | ||
name: scopedName, | ||
version: require(configurationFile.version), | ||
description: require(configurationFile.description), | ||
license: require(configurationFile.license), | ||
author: 'Quentin Adam', | ||
repository: { type: 'git', url: `git+https://github.com/quentinadam/deno-${name}.git` }, | ||
type: 'module', | ||
exports: ((exports) => { | ||
const replaceFn = (path: string) => path.replace(/^\.\/src\//, './dist/').replace(/\.ts$/, '.js'); | ||
if (typeof exports === 'string') { | ||
return replaceFn(exports); | ||
} else { | ||
return Object.fromEntries(Object.entries(exports).map(([key, value]) => [key, replaceFn(value)])); | ||
} | ||
})(require(configurationFile.exports)), | ||
files: ['dist', 'README.md'], | ||
dependencies: dependencies.length > 0 | ||
? Object.fromEntries(dependencies.map(({ name, version }) => [name, version])) | ||
: undefined, | ||
}; | ||
} | ||
throw new Error(`Invalid type ${type}`); | ||
})(); | ||
|
||
console.log(JSON.stringify(manifest, null, 2)); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.