@prisma-next/extension-author-tools 0.8.0

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/README.md ADDED
@@ -0,0 +1,33 @@
1
+ # @prisma-next/extension-author-tools
2
+
3
+ CLI tools that pair with the [`prisma-next-extension-upgrade`](../../../skills/extension-author/prisma-next-extension-upgrade/SKILL.md) agent skill. Today this package ships one tool; future tools for extension authors using the upgrade-skill flow will land here.
4
+
5
+ The agent-readable upgrade procedure itself (the SKILL.md, the `upgrades/<from>-to-<to>/instructions.md` set, the README) lives at [`skills/extension-author/prisma-next-extension-upgrade/`](../../../skills/extension-author/prisma-next-extension-upgrade/) and is distributed via `npx skills add prisma/prisma-next/skills/extension-author --all`. This package is the npm-published companion that supplies the CI bin the skill drives.
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ pnpm add -D @prisma-next/extension-author-tools
11
+ # or:
12
+ npm install --save-dev @prisma-next/extension-author-tools
13
+ ```
14
+
15
+ ## Tools
16
+
17
+ ### `prisma-next-check-pins`
18
+
19
+ CI guard for extension packages. Asserts that every `@prisma-next/*` entry under the package's `peerDependencies` (and, optionally, `dependencies`) is pinned to an exact version, not a range.
20
+
21
+ This is the invariant the [`prisma-next-extension-upgrade`](../../../skills/extension-author/prisma-next-extension-upgrade/SKILL.md) skill relies on at upgrade time: extension authors pin every `@prisma-next/*` peer to a single exact version per release of their extension, so the skill can mechanically advance both the framework deps and the extension's published version in lockstep.
22
+
23
+ Run from the extension's repository root:
24
+
25
+ ```bash
26
+ pnpm exec prisma-next-check-pins
27
+ ```
28
+
29
+ Exit code is `0` if every `@prisma-next/*` peerDep is exact, non-zero otherwise. Suitable for use in a GitHub Actions `run:` step, a pre-commit hook, or `package.json` `scripts.lint`.
30
+
31
+ ## Source location
32
+
33
+ `packages/0-shared/extension-author-tools/`
@@ -0,0 +1,86 @@
1
+ #!/usr/bin/env node
2
+ // Enforce the exact-pin rule for Prisma Next extensions: every
3
+ // `@prisma-next/*` entry in `dependencies`, `peerDependencies`, and
4
+ // `optionalDependencies` must be a single exact-version string, and
5
+ // every entry must resolve to the same version. Exits 0 on success
6
+ // (no output); on failure, prints one structured line per offending
7
+ // entry and exits non-zero.
8
+
9
+ import { readFileSync } from 'node:fs';
10
+ import { join } from 'node:path';
11
+ import { cwd, exit, stderr } from 'node:process';
12
+
13
+ const DEP_FIELDS = ['dependencies', 'peerDependencies', 'optionalDependencies'];
14
+ const PRISMA_NEXT_SCOPE = '@prisma-next/';
15
+ const EXACT_VERSION_RE = /^\d+\.\d+\.\d+(-[0-9A-Za-z.-]+)?$/;
16
+
17
+ function readPackageJson() {
18
+ const path = join(cwd(), 'package.json');
19
+ try {
20
+ return JSON.parse(readFileSync(path, 'utf8'));
21
+ } catch (err) {
22
+ stderr.write(`prisma-next-check-pins: cannot read package.json at ${path}: ${err.message}\n`);
23
+ exit(2);
24
+ }
25
+ }
26
+
27
+ function collectEntries(pkg) {
28
+ const entries = [];
29
+ for (const field of DEP_FIELDS) {
30
+ const deps = pkg[field];
31
+ if (!deps || typeof deps !== 'object') continue;
32
+ for (const [name, spec] of Object.entries(deps)) {
33
+ if (!name.startsWith(PRISMA_NEXT_SCOPE)) continue;
34
+ entries.push({ field, name, spec });
35
+ }
36
+ }
37
+ return entries;
38
+ }
39
+
40
+ function findViolations(entries) {
41
+ const violations = [];
42
+ const exactEntries = [];
43
+ for (const entry of entries) {
44
+ if (typeof entry.spec === 'string' && EXACT_VERSION_RE.test(entry.spec)) {
45
+ exactEntries.push(entry);
46
+ } else {
47
+ violations.push({
48
+ ...entry,
49
+ rule: 'exact-version',
50
+ message:
51
+ 'not an exact-version pin (operators, ranges, workspace specifiers, and wildcards are forbidden; expected e.g. "0.7.0")',
52
+ });
53
+ }
54
+ }
55
+ if (exactEntries.length > 1) {
56
+ const versions = new Set(exactEntries.map((entry) => entry.spec));
57
+ if (versions.size > 1) {
58
+ const observed = Array.from(versions).sort().join(', ');
59
+ for (const entry of exactEntries) {
60
+ violations.push({
61
+ ...entry,
62
+ rule: 'single-version',
63
+ message: `all @prisma-next/* entries must share the same exact version (observed: ${observed})`,
64
+ });
65
+ }
66
+ }
67
+ }
68
+ return violations;
69
+ }
70
+
71
+ function main() {
72
+ const pkg = readPackageJson();
73
+ const entries = collectEntries(pkg);
74
+ const violations = findViolations(entries);
75
+ if (violations.length === 0) {
76
+ exit(0);
77
+ }
78
+ const pkgName = typeof pkg.name === 'string' ? pkg.name : '<unnamed>';
79
+ stderr.write(`prisma-next-check-pins: ${violations.length} violation(s) in ${pkgName}\n`);
80
+ for (const v of violations) {
81
+ stderr.write(` ${v.field}.${v.name} = ${JSON.stringify(v.spec)} — ${v.message}\n`);
82
+ }
83
+ exit(1);
84
+ }
85
+
86
+ main();
package/package.json ADDED
@@ -0,0 +1,26 @@
1
+ {
2
+ "name": "@prisma-next/extension-author-tools",
3
+ "version": "0.8.0",
4
+ "license": "Apache-2.0",
5
+ "type": "module",
6
+ "description": "CLI tools that pair with the prisma-next-extension-upgrade agent skill — including `prisma-next-check-pins`, the CI guard that asserts every `@prisma-next/*` peerDep on an extension package is exact-version-pinned. Future tools for extension authors employing the upgrade skill ship from this package.",
7
+ "publishConfig": {
8
+ "access": "public",
9
+ "provenance": true
10
+ },
11
+ "bin": {
12
+ "prisma-next-check-pins": "./bin/prisma-next-check-pins.mjs"
13
+ },
14
+ "scripts": {
15
+ "test": "node --test test/*.test.mjs"
16
+ },
17
+ "files": [
18
+ "README.md",
19
+ "bin"
20
+ ],
21
+ "repository": {
22
+ "type": "git",
23
+ "url": "https://github.com/prisma/prisma-next.git",
24
+ "directory": "packages/0-shared/extension-author-tools"
25
+ }
26
+ }