@theholocron/holocron-plugin-neon 5.0.0-alpha.28 → 5.0.0-alpha.280
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/dist/index.d.mts +31 -34
- package/dist/index.mjs +31 -17
- package/package.json +21 -19
package/dist/index.d.mts
CHANGED
|
@@ -1,24 +1,30 @@
|
|
|
1
|
-
import { AuthError, ConnectionStringOptions, ResolveTokenInput, Storage, StorageBranch } from "@theholocron/cli";
|
|
1
|
+
import { AuthError, ConnectionStringOptions, PluginToken, ResolveTokenInput, Storage, StorageBranch, VerifyTokenFailure, VerifyTokenResult, VerifyTokenResult as VerifyTokenResult$1, VerifyTokenSuccess } from "@theholocron/cli";
|
|
2
2
|
import { NeonClient, NeonClient as NeonClient$1, NeonClientOptions, createNeonClient } from "@theholocron/neon-client";
|
|
3
|
-
|
|
4
|
-
declare const resolveToken: (
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
/** Resolves the Neon API key from `--token`, `HOLOCRON_NEON_API_KEY`, `NEON_API_KEY` or the keyring entry for `neon`, and throws `AuthError` when none is set. */
|
|
4
|
+
export declare const resolveToken: import("@theholocron/cli").TokenResolver;
|
|
5
|
+
/** Every token this plugin takes, for `holocron doctor tokens`. */
|
|
6
|
+
export declare const tokens: PluginToken[];
|
|
7
7
|
interface StorageOptions {
|
|
8
8
|
projectId: string;
|
|
9
9
|
}
|
|
10
|
-
|
|
10
|
+
/** `storage` capability for Neon, bound to the single project named by the `projectId` option. */
|
|
11
|
+
export declare class NeonStorage implements Storage {
|
|
11
12
|
private readonly client;
|
|
12
13
|
private readonly opts;
|
|
14
|
+
/** Capability key; always `"storage"`. */
|
|
13
15
|
readonly key: "storage";
|
|
16
|
+
/** Provider name; always `"neon"`. */
|
|
14
17
|
readonly providerName = "neon";
|
|
15
18
|
constructor(client: () => NeonClient$1, opts: StorageOptions);
|
|
16
19
|
getConnectionString(scope: string, options?: ConnectionStringOptions): Promise<string>;
|
|
20
|
+
/** Lists every branch of the bound project, mapped to `StorageBranch`. */
|
|
17
21
|
listBranches(): Promise<StorageBranch[]>;
|
|
22
|
+
/** Creates a branch (optionally from the `from` parent branch id) with a read-write endpoint, so its connection string works at once. */
|
|
18
23
|
createBranch(input: {
|
|
19
24
|
name: string;
|
|
20
25
|
from?: string;
|
|
21
26
|
}): Promise<StorageBranch>;
|
|
27
|
+
/** Deletes the branch with the given id from the bound project. */
|
|
22
28
|
destroyBranch(branch: string): Promise<void>;
|
|
23
29
|
resetBranch(input: {
|
|
24
30
|
branch: string;
|
|
@@ -35,31 +41,14 @@ declare class NeonStorage implements Storage {
|
|
|
35
41
|
*/
|
|
36
42
|
private firstDatabase;
|
|
37
43
|
}
|
|
38
|
-
//#endregion
|
|
39
|
-
//#region src/verify-token.d.ts
|
|
40
|
-
/**
|
|
41
|
-
* `verifyToken` — plugin-level export used by `holocron auth set` +
|
|
42
|
-
* `holocron auth check`. Hits Neon's `/users/me` endpoint and
|
|
43
|
-
* translates the response into the normalized `VerifyTokenResult`
|
|
44
|
-
* shape.
|
|
45
|
-
*/
|
|
46
|
-
interface VerifyTokenSuccess {
|
|
47
|
-
ok: true;
|
|
48
|
-
subject: string;
|
|
49
|
-
}
|
|
50
|
-
interface VerifyTokenFailure {
|
|
51
|
-
ok: false;
|
|
52
|
-
message: string;
|
|
53
|
-
}
|
|
54
|
-
type VerifyTokenResult = VerifyTokenSuccess | VerifyTokenFailure;
|
|
55
44
|
interface VerifyTokenOptions {
|
|
56
45
|
baseUrl?: string;
|
|
57
46
|
fetch?: typeof fetch;
|
|
58
47
|
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
interface NeonPluginOptions extends ResolveTokenInput {
|
|
48
|
+
/** Checks a Neon API key by calling `/users/me` and reports who it belongs to, or why it was rejected. */
|
|
49
|
+
export declare function verifyToken(token: string, opts?: VerifyTokenOptions): Promise<VerifyTokenResult$1>;
|
|
50
|
+
/** Options for the Neon plugin: the token lookup inputs plus the project it is bound to. */
|
|
51
|
+
export interface NeonPluginOptions extends ResolveTokenInput {
|
|
63
52
|
/** Neon project id this plugin is bound to. Required. */
|
|
64
53
|
projectId: string;
|
|
65
54
|
/** Override base URL for tests. */
|
|
@@ -67,14 +56,23 @@ interface NeonPluginOptions extends ResolveTokenInput {
|
|
|
67
56
|
/** Override `fetch` for tests. */
|
|
68
57
|
fetch?: typeof fetch;
|
|
69
58
|
}
|
|
70
|
-
|
|
59
|
+
/** Shared state for one Neon plugin instance: its options and a lazily created client. */
|
|
60
|
+
export interface PluginContext {
|
|
61
|
+
/** The options the plugin was created with. */
|
|
71
62
|
options: NeonPluginOptions;
|
|
63
|
+
/** Returns the memoized Neon client; the token is resolved on the first call, not at plugin load. */
|
|
72
64
|
client: () => NeonClient;
|
|
73
65
|
}
|
|
74
|
-
|
|
75
|
-
declare function
|
|
76
|
-
|
|
66
|
+
/** Builds the plugin context from its options; throws when `projectId` is missing. */
|
|
67
|
+
export declare function createContext(options: NeonPluginOptions): PluginContext;
|
|
68
|
+
/** Builds the `storage` capability for the context's project. */
|
|
69
|
+
export declare function storage(ctx: PluginContext): Storage;
|
|
70
|
+
/** Creates the Neon plugin: its `connection` probe and the `storage` capability. */
|
|
71
|
+
export declare function createPlugin(options: NeonPluginOptions): {
|
|
77
72
|
name: string;
|
|
73
|
+
probes: {
|
|
74
|
+
connection: import("@theholocron/cli").Probe;
|
|
75
|
+
};
|
|
78
76
|
capabilities: {
|
|
79
77
|
storage: () => Storage;
|
|
80
78
|
};
|
|
@@ -85,6 +83,5 @@ declare function createPlugin(options: NeonPluginOptions): {
|
|
|
85
83
|
* at https://console.neon.tech/app/settings/api-keys where API keys
|
|
86
84
|
* are minted.
|
|
87
85
|
*/
|
|
88
|
-
declare const AUTH_HINT: string;
|
|
89
|
-
|
|
90
|
-
export { AUTH_HINT, AuthError, type NeonClient, type NeonClientOptions, NeonPluginOptions, NeonStorage, PluginContext, type ResolveTokenInput, type VerifyTokenFailure, type VerifyTokenResult, type VerifyTokenSuccess, createContext, createNeonClient, createPlugin, resolveToken, storage, verifyToken };
|
|
86
|
+
export declare const AUTH_HINT: string;
|
|
87
|
+
export { AuthError, type NeonClient, type NeonClientOptions, type ResolveTokenInput, type VerifyTokenFailure, type VerifyTokenResult, type VerifyTokenSuccess, createNeonClient };
|
package/dist/index.mjs
CHANGED
|
@@ -1,18 +1,24 @@
|
|
|
1
|
-
import { AuthError, ProviderApiError, createResolveToken } from "@theholocron/cli";
|
|
1
|
+
import { AuthError, ProviderApiError, connectionProbe, createResolveToken } from "@theholocron/cli";
|
|
2
2
|
import { createNeonClient } from "@theholocron/neon-client";
|
|
3
|
-
|
|
3
|
+
import { errorMessage } from "@theholocron/misc-utils";
|
|
4
|
+
// src/auth.ts
|
|
5
|
+
/** Resolves the Neon API key from `--token`, `HOLOCRON_NEON_API_KEY`, `NEON_API_KEY` or the keyring entry for `neon`, and throws `AuthError` when none is set. */
|
|
4
6
|
const resolveToken = createResolveToken({
|
|
5
7
|
envName: "HOLOCRON_NEON_API_KEY",
|
|
6
8
|
vendorEnvName: "NEON_API_KEY",
|
|
7
9
|
keyringService: "neon",
|
|
8
10
|
errorMessage: "no Neon API key found. Pass --token <KEY>, set HOLOCRON_NEON_API_KEY / NEON_API_KEY, or run: holocron auth set neon <KEY>"
|
|
9
11
|
});
|
|
10
|
-
|
|
11
|
-
|
|
12
|
+
/** Every token this plugin takes, for `holocron doctor tokens`. */
|
|
13
|
+
const tokens = [resolveToken.token];
|
|
14
|
+
// src/capabilities/storage.ts
|
|
15
|
+
/** `storage` capability for Neon, bound to the single project named by the `projectId` option. */
|
|
12
16
|
var NeonStorage = class {
|
|
13
17
|
client;
|
|
14
18
|
opts;
|
|
19
|
+
/** Capability key; always `"storage"`. */
|
|
15
20
|
key = "storage";
|
|
21
|
+
/** Provider name; always `"neon"`. */
|
|
16
22
|
providerName = "neon";
|
|
17
23
|
constructor(client, opts) {
|
|
18
24
|
this.client = client;
|
|
@@ -29,10 +35,12 @@ var NeonStorage = class {
|
|
|
29
35
|
});
|
|
30
36
|
return uri;
|
|
31
37
|
}
|
|
38
|
+
/** Lists every branch of the bound project, mapped to `StorageBranch`. */
|
|
32
39
|
async listBranches() {
|
|
33
40
|
const { branches } = await this.client().branches.list(this.opts.projectId);
|
|
34
41
|
return branches.map(mapBranch);
|
|
35
42
|
}
|
|
43
|
+
/** Creates a branch (optionally from the `from` parent branch id) with a read-write endpoint, so its connection string works at once. */
|
|
36
44
|
async createBranch(input) {
|
|
37
45
|
const { branch } = await this.client().branches.create(this.opts.projectId, {
|
|
38
46
|
name: input.name,
|
|
@@ -41,6 +49,7 @@ var NeonStorage = class {
|
|
|
41
49
|
});
|
|
42
50
|
return mapBranch(branch);
|
|
43
51
|
}
|
|
52
|
+
/** Deletes the branch with the given id from the bound project. */
|
|
44
53
|
async destroyBranch(branch) {
|
|
45
54
|
await this.client().branches.destroy(this.opts.projectId, branch);
|
|
46
55
|
}
|
|
@@ -71,14 +80,8 @@ function mapBranch(raw) {
|
|
|
71
80
|
createdAt: raw.created_at
|
|
72
81
|
};
|
|
73
82
|
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* `verifyToken` — plugin-level export used by `holocron auth set` +
|
|
78
|
-
* `holocron auth check`. Hits Neon's `/users/me` endpoint and
|
|
79
|
-
* translates the response into the normalized `VerifyTokenResult`
|
|
80
|
-
* shape.
|
|
81
|
-
*/
|
|
83
|
+
// src/verify-token.ts
|
|
84
|
+
/** Checks a Neon API key by calling `/users/me` and reports who it belongs to, or why it was rejected. */
|
|
82
85
|
async function verifyToken(token, opts = {}) {
|
|
83
86
|
const client = createNeonClient({
|
|
84
87
|
token,
|
|
@@ -94,12 +97,12 @@ async function verifyToken(token, opts = {}) {
|
|
|
94
97
|
} catch (err) {
|
|
95
98
|
return {
|
|
96
99
|
ok: false,
|
|
97
|
-
message:
|
|
100
|
+
message: errorMessage(err)
|
|
98
101
|
};
|
|
99
102
|
}
|
|
100
103
|
}
|
|
101
|
-
|
|
102
|
-
|
|
104
|
+
// src/index.ts
|
|
105
|
+
/** Builds the plugin context from its options; throws when `projectId` is missing. */
|
|
103
106
|
function createContext(options) {
|
|
104
107
|
if (!options.projectId) throw new Error("@theholocron/holocron-plugin-neon requires `projectId` in options");
|
|
105
108
|
let client;
|
|
@@ -112,13 +115,25 @@ function createContext(options) {
|
|
|
112
115
|
})
|
|
113
116
|
};
|
|
114
117
|
}
|
|
118
|
+
/** Builds the `storage` capability for the context's project. */
|
|
115
119
|
function storage(ctx) {
|
|
116
120
|
return new NeonStorage(ctx.client, { projectId: ctx.options.projectId });
|
|
117
121
|
}
|
|
122
|
+
/** Creates the Neon plugin: its `connection` probe and the `storage` capability. */
|
|
118
123
|
function createPlugin(options) {
|
|
119
124
|
const ctx = createContext(options);
|
|
120
125
|
return {
|
|
121
126
|
name: "@theholocron/holocron-plugin-neon",
|
|
127
|
+
probes: { connection: connectionProbe({
|
|
128
|
+
provider: "Neon",
|
|
129
|
+
url: options.baseUrl ?? "https://console.neon.tech",
|
|
130
|
+
fetch: options.fetch,
|
|
131
|
+
token: () => resolveToken(options),
|
|
132
|
+
verify: (token) => verifyToken(token, {
|
|
133
|
+
baseUrl: options.baseUrl,
|
|
134
|
+
fetch: options.fetch
|
|
135
|
+
})
|
|
136
|
+
}) },
|
|
122
137
|
capabilities: { storage: () => storage(ctx) }
|
|
123
138
|
};
|
|
124
139
|
}
|
|
@@ -129,5 +144,4 @@ function createPlugin(options) {
|
|
|
129
144
|
* are minted.
|
|
130
145
|
*/
|
|
131
146
|
const AUTH_HINT = "generate a Neon API key at https://console.neon.tech/app/settings/api-keys, then run: holocron auth set neon <KEY>";
|
|
132
|
-
|
|
133
|
-
export { AUTH_HINT, AuthError, NeonStorage, createContext, createNeonClient, createPlugin, resolveToken, storage, verifyToken };
|
|
147
|
+
export { AUTH_HINT, AuthError, NeonStorage, createContext, createNeonClient, createPlugin, resolveToken, storage, tokens, verifyToken };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@theholocron/holocron-plugin-neon",
|
|
3
|
-
"version": "5.0.0-alpha.
|
|
3
|
+
"version": "5.0.0-alpha.280",
|
|
4
4
|
"description": "Holocron plugin for Neon. Implements the storage capability against Neon's REST API — branch ops, connection strings, extensions.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"holocron",
|
|
@@ -8,12 +8,12 @@
|
|
|
8
8
|
"plugin",
|
|
9
9
|
"storage"
|
|
10
10
|
],
|
|
11
|
-
"homepage": "https://
|
|
11
|
+
"homepage": "https://docs.theholocron.dev/holocron/plugins/neon/",
|
|
12
12
|
"bugs": "https://github.com/theholocron/holocron/issues",
|
|
13
13
|
"repository": {
|
|
14
14
|
"type": "git",
|
|
15
15
|
"url": "git+https://github.com/theholocron/holocron.git",
|
|
16
|
-
"directory": "
|
|
16
|
+
"directory": "plugins/holocron-plugin-neon"
|
|
17
17
|
},
|
|
18
18
|
"license": "MIT",
|
|
19
19
|
"author": "Newton Koumantzelis",
|
|
@@ -30,27 +30,29 @@
|
|
|
30
30
|
"dist"
|
|
31
31
|
],
|
|
32
32
|
"devDependencies": {
|
|
33
|
-
"@theholocron/eslint-config": "^8.0.0",
|
|
34
|
-
"@theholocron/http-client": "^1.23.0",
|
|
35
|
-
"@theholocron/neon-client": "^1.23.0",
|
|
36
|
-
"@theholocron/tsconfig": "^8.0.0",
|
|
37
|
-
"@theholocron/tsdown-config": "^8.0.0",
|
|
38
|
-
"@theholocron/vitest-config": "^8.0.0",
|
|
39
33
|
"@types/node": "^26",
|
|
40
|
-
"@vitest/coverage-v8": "^
|
|
34
|
+
"@vitest/coverage-v8": "^5.0.5",
|
|
41
35
|
"@vitest/eslint-plugin": "^1.6.27",
|
|
42
36
|
"eslint": "^10.8.1",
|
|
43
37
|
"eslint-plugin-n": "^18.3.0",
|
|
44
38
|
"globals": "^17.11.0",
|
|
45
|
-
"tsdown": "^0.
|
|
46
|
-
"tsx": "4.23.
|
|
39
|
+
"tsdown": "^0.23.3",
|
|
40
|
+
"tsx": "4.23.15",
|
|
47
41
|
"typescript": "^5.9.3",
|
|
48
|
-
"vitest": "^
|
|
49
|
-
"@theholocron/cli": "5.0.0-alpha.
|
|
42
|
+
"vitest": "^5.0.5",
|
|
43
|
+
"@theholocron/cli": "5.0.0-alpha.280",
|
|
44
|
+
"@theholocron/eslint-config": "^8.9.0-alpha.4",
|
|
45
|
+
"@theholocron/http-client": "^1.58.0-alpha.3",
|
|
46
|
+
"@theholocron/misc-utils": "^1.16.1-alpha.3",
|
|
47
|
+
"@theholocron/tsconfig": "^8.9.0-alpha.4",
|
|
48
|
+
"@theholocron/tsdown-config": "^8.9.0-alpha.4",
|
|
49
|
+
"@theholocron/vitest-config": "^8.9.0-alpha.4",
|
|
50
|
+
"@theholocron/neon-client": "^1.58.0-alpha.3"
|
|
50
51
|
},
|
|
51
52
|
"peerDependencies": {
|
|
52
|
-
"@theholocron/
|
|
53
|
-
"@theholocron/
|
|
53
|
+
"@theholocron/misc-utils": "^1.16.0",
|
|
54
|
+
"@theholocron/neon-client": "^1.43.1",
|
|
55
|
+
"@theholocron/cli": "5.0.0-alpha.280"
|
|
54
56
|
},
|
|
55
57
|
"peerDependenciesMeta": {
|
|
56
58
|
"@theholocron/neon-client": {}
|
|
@@ -63,10 +65,10 @@
|
|
|
63
65
|
},
|
|
64
66
|
"scripts": {
|
|
65
67
|
"delivery.build": "tsdown",
|
|
66
|
-
"sourceQuality.staticAnalysis": "
|
|
68
|
+
"sourceQuality.staticAnalysis": "eslint .",
|
|
67
69
|
"test:watch": "vitest",
|
|
68
70
|
"validate": "tsx scripts/validate.mjs",
|
|
69
|
-
"verification.typeSafety": "
|
|
70
|
-
"verification.unitTests": "
|
|
71
|
+
"verification.typeSafety": "tsc --noEmit",
|
|
72
|
+
"verification.unitTests": "vitest run"
|
|
71
73
|
}
|
|
72
74
|
}
|