@fatagnus/dink-sdk 2.13.2 → 2.15.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 CHANGED
@@ -81,6 +81,51 @@ const result = await center.call({
81
81
  console.log(result); // { temperature: 22.5 }
82
82
  ```
83
83
 
84
+ ## Loading Credentials
85
+
86
+ Use `loadDinkEnv()` to load credentials from the `.dink/` directory (managed by the `dink env` CLI) with automatic fallback to `DINK_SERVER` / `DINK_API_KEY` environment variables.
87
+
88
+ > **Note:** This is Node.js only (uses `node:fs`, `node:path`). Available via subpath import `@fatagnus/dink-sdk/env` or from the main entry point.
89
+
90
+ ```typescript
91
+ import { loadDinkEnv } from '@fatagnus/dink-sdk/env';
92
+ import { CenterClient, EdgeClient } from '@fatagnus/dink-sdk';
93
+
94
+ // Load current environment (from .dink/.current) or fall back to env vars
95
+ const env = await loadDinkEnv();
96
+
97
+ const center = new CenterClient({ serverUrl: env.server, apiKey: env.apiKey });
98
+ const edge = new EdgeClient({ apiKey: env.apiKey });
99
+ ```
100
+
101
+ Load a specific named environment:
102
+
103
+ ```typescript
104
+ const env = await loadDinkEnv('staging'); // reads .dink/staging.yaml
105
+ ```
106
+
107
+ Credential resolution order:
108
+ 1. **Named env** — `.dink/<name>.yaml` (when a name is passed)
109
+ 2. **Current env** — `.dink/.current` → `.dink/<current>.yaml`
110
+ 3. **Env vars** — `DINK_SERVER` / `DINK_API_KEY` (CI/Docker fallback)
111
+
112
+ Error handling:
113
+
114
+ ```typescript
115
+ import { DinkEnvError } from '@fatagnus/dink-sdk/env';
116
+
117
+ try {
118
+ const env = await loadDinkEnv();
119
+ } catch (e) {
120
+ if (e instanceof DinkEnvError) {
121
+ // e.code === 'NO_ENVIRONMENT' — no .dink/ dir and no env vars set
122
+ // e.code === 'NOT_FOUND' — named env file missing
123
+ }
124
+ }
125
+ ```
126
+
127
+ This integrates with `dink env` CLI commands for managing environments. In CI/Docker where no `.dink/` directory exists, set `DINK_SERVER` and `DINK_API_KEY` as environment variables — the same code works without changes.
128
+
84
129
  ## API Key Formats
85
130
 
86
131
  Dink supports two API key formats for edge authentication:
@@ -188,6 +233,7 @@ You can also import specific clients directly:
188
233
  ```typescript
189
234
  import { EdgeClient } from '@fatagnus/dink-sdk/edge';
190
235
  import { CenterClient } from '@fatagnus/dink-sdk/center';
236
+ import { loadDinkEnv } from '@fatagnus/dink-sdk/env';
191
237
  ```
192
238
 
193
239
  ## Naming Rules
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Credentials loaded from a .dink/ environment or env vars.
3
+ */
4
+ export interface DinkEnv {
5
+ name: string;
6
+ server: string;
7
+ apiKey: string;
8
+ appId: string;
9
+ syncKey: string;
10
+ }
11
+ /**
12
+ * Options for loadDinkEnv.
13
+ */
14
+ export interface LoadOptions {
15
+ app?: string;
16
+ }
17
+ /**
18
+ * Error thrown when environment resolution fails.
19
+ */
20
+ export declare class DinkEnvError extends Error {
21
+ readonly code: 'NO_ENVIRONMENT' | 'NOT_FOUND';
22
+ constructor(message: string, code: 'NO_ENVIRONMENT' | 'NOT_FOUND');
23
+ }
24
+ /**
25
+ * Load Dink credentials.
26
+ *
27
+ * Resolution order:
28
+ * 1. If `name` provided: find `.dink/` dir, read `.dink/<name>.yaml`
29
+ * 2. If no `name`: find `.dink/` dir, read `.dink/.current` for active env name
30
+ * 3. Fall back to `DINK_SERVER` / `DINK_API_KEY` environment variables
31
+ * 4. Throw `DinkEnvError` with code `'NO_ENVIRONMENT'` if nothing found
32
+ *
33
+ * App resolution priority:
34
+ * 1. `options.app` if provided
35
+ * 2. `DINK_APP_ID` env var
36
+ * 3. `.current` second line
37
+ * 4. YAML `default_app`
38
+ * 5. empty string
39
+ */
40
+ export declare function loadDinkEnv(name?: string, options?: LoadOptions): Promise<DinkEnv>;
41
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/env/index.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,qBAAa,YAAa,SAAQ,KAAK;IACrC,QAAQ,CAAC,IAAI,EAAE,gBAAgB,GAAG,WAAW,CAAC;gBAElC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,gBAAgB,GAAG,WAAW;CAKlE;AAuID;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,WAAW,CAC/B,IAAI,CAAC,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,WAAW,GACpB,OAAO,CAAC,OAAO,CAAC,CAmClB"}
@@ -0,0 +1,225 @@
1
+ import { readFile, stat } from 'node:fs/promises';
2
+ import { join, dirname } from 'node:path';
3
+ /**
4
+ * Error thrown when environment resolution fails.
5
+ */
6
+ export class DinkEnvError extends Error {
7
+ code;
8
+ constructor(message, code) {
9
+ super(message);
10
+ this.name = 'DinkEnvError';
11
+ this.code = code;
12
+ }
13
+ }
14
+ /**
15
+ * Walk up from cwd looking for a .dink/ directory.
16
+ * Returns the absolute path to the .dink/ dir, or null if none found.
17
+ */
18
+ async function findDinkDir() {
19
+ let dir = process.cwd();
20
+ for (;;) {
21
+ const candidate = join(dir, '.dink');
22
+ try {
23
+ const info = await stat(candidate);
24
+ if (info.isDirectory()) {
25
+ return candidate;
26
+ }
27
+ }
28
+ catch {
29
+ // not found, keep walking
30
+ }
31
+ const parent = dirname(dir);
32
+ if (parent === dir) {
33
+ // Reached filesystem root.
34
+ return null;
35
+ }
36
+ dir = parent;
37
+ }
38
+ }
39
+ /**
40
+ * Parse a trivial YAML file containing `server`, `api_key`, `default_app`,
41
+ * and an optional `apps:` section.
42
+ * No dependency — files are always simple key: value pairs with one level of nesting for apps.
43
+ */
44
+ function parseEnvYaml(content) {
45
+ const serverMatch = content.match(/^server:\s*["']?(.*?)["']?\s*$/m);
46
+ const apiKeyMatch = content.match(/^api_key:\s*["']?(.*?)["']?\s*$/m);
47
+ const defaultAppMatch = content.match(/^default_app:\s*["']?(.*?)["']?\s*$/m);
48
+ const server = serverMatch ? serverMatch[1] : '';
49
+ const apiKey = apiKeyMatch ? apiKeyMatch[1] : '';
50
+ const defaultApp = defaultAppMatch ? defaultAppMatch[1] : '';
51
+ const apps = parseAppsSection(content);
52
+ return { server, apiKey, defaultApp, apps };
53
+ }
54
+ /**
55
+ * Parse the `apps:` section from YAML content.
56
+ * Handles the known two-level structure only:
57
+ *
58
+ * apps:
59
+ * app-name:
60
+ * api_key: xxx
61
+ * sync_key: yyy
62
+ *
63
+ * Uses indent-aware line parsing. NOT a full YAML parser.
64
+ */
65
+ function parseAppsSection(content) {
66
+ const result = {};
67
+ const lines = content.split('\n');
68
+ // Find the `apps:` line at column 0
69
+ let i = 0;
70
+ for (; i < lines.length; i++) {
71
+ if (/^apps:\s*$/.test(lines[i])) {
72
+ i++;
73
+ break;
74
+ }
75
+ }
76
+ if (i >= lines.length)
77
+ return result;
78
+ // Parse app entries — each app name is indented (typically 2 spaces / 1 tab)
79
+ let currentApp = '';
80
+ for (; i < lines.length; i++) {
81
+ const line = lines[i];
82
+ // Blank line or comment — skip
83
+ if (/^\s*$/.test(line) || /^\s*#/.test(line))
84
+ continue;
85
+ // Non-indented line — we've left the apps block
86
+ if (/^\S/.test(line))
87
+ break;
88
+ // App name line: indented, ends with ':'
89
+ const appNameMatch = line.match(/^[ \t]+([^\s:]+):\s*$/);
90
+ if (appNameMatch) {
91
+ currentApp = appNameMatch[1];
92
+ result[currentApp] = { apiKey: '', syncKey: '' };
93
+ continue;
94
+ }
95
+ // Property line inside an app (deeper indent)
96
+ if (currentApp) {
97
+ const propMatch = line.match(/^[ \t]+([a-z_]+):\s*["']?(.*?)["']?\s*$/);
98
+ if (propMatch) {
99
+ const [, key, value] = propMatch;
100
+ if (key === 'api_key') {
101
+ result[currentApp].apiKey = value;
102
+ }
103
+ else if (key === 'sync_key') {
104
+ result[currentApp].syncKey = value;
105
+ }
106
+ }
107
+ }
108
+ }
109
+ return result;
110
+ }
111
+ /**
112
+ * Read the .dink/.current file.
113
+ * New format: line 1 = envName, line 2 (optional) = appName.
114
+ * Old format: single trimmed line = envName.
115
+ */
116
+ async function readCurrentContext(dinkDir) {
117
+ try {
118
+ const data = await readFile(join(dinkDir, '.current'), 'utf-8');
119
+ const lines = data.split('\n');
120
+ const envName = (lines[0] ?? '').trim();
121
+ const appName = (lines[1] ?? '').trim();
122
+ if (!envName)
123
+ return null;
124
+ return { envName, appName };
125
+ }
126
+ catch {
127
+ return null;
128
+ }
129
+ }
130
+ /**
131
+ * Load Dink credentials.
132
+ *
133
+ * Resolution order:
134
+ * 1. If `name` provided: find `.dink/` dir, read `.dink/<name>.yaml`
135
+ * 2. If no `name`: find `.dink/` dir, read `.dink/.current` for active env name
136
+ * 3. Fall back to `DINK_SERVER` / `DINK_API_KEY` environment variables
137
+ * 4. Throw `DinkEnvError` with code `'NO_ENVIRONMENT'` if nothing found
138
+ *
139
+ * App resolution priority:
140
+ * 1. `options.app` if provided
141
+ * 2. `DINK_APP_ID` env var
142
+ * 3. `.current` second line
143
+ * 4. YAML `default_app`
144
+ * 5. empty string
145
+ */
146
+ export async function loadDinkEnv(name, options) {
147
+ const dinkDir = await findDinkDir();
148
+ // If a name is explicitly provided, we require a .dink/ directory.
149
+ if (name !== undefined) {
150
+ if (!dinkDir) {
151
+ throw new DinkEnvError(`no .dink/ directory found while looking for environment "${name}"`, 'NOT_FOUND');
152
+ }
153
+ return loadFromFile(dinkDir, name, options);
154
+ }
155
+ // Try .dink/.current
156
+ if (dinkDir) {
157
+ const ctx = await readCurrentContext(dinkDir);
158
+ if (ctx) {
159
+ return loadFromFile(dinkDir, ctx.envName, options, ctx.appName);
160
+ }
161
+ }
162
+ // Fall back to env vars
163
+ const server = process.env['DINK_SERVER'];
164
+ const apiKey = process.env['DINK_API_KEY'];
165
+ if (server) {
166
+ const appId = resolveAppId(options?.app, '', '');
167
+ const syncKey = process.env['DINK_APP_SYNC_KEY'] ?? '';
168
+ return { name: '', server, apiKey: apiKey ?? '', appId, syncKey };
169
+ }
170
+ throw new DinkEnvError('no dink environment found: no .dink/ directory, no .current file, and DINK_SERVER is not set', 'NO_ENVIRONMENT');
171
+ }
172
+ /**
173
+ * Resolve appId from the priority chain.
174
+ * 1. options.app
175
+ * 2. DINK_APP_ID env var
176
+ * 3. currentAppName (from .current second line)
177
+ * 4. YAML default_app
178
+ * 5. empty string
179
+ */
180
+ function resolveAppId(optionApp, currentAppName, yamlDefaultApp) {
181
+ if (optionApp)
182
+ return optionApp;
183
+ const envAppId = process.env['DINK_APP_ID'];
184
+ if (envAppId)
185
+ return envAppId;
186
+ if (currentAppName)
187
+ return currentAppName;
188
+ if (yamlDefaultApp)
189
+ return yamlDefaultApp;
190
+ return '';
191
+ }
192
+ /**
193
+ * Load and validate a named environment file from `.dink/<name>.yaml`.
194
+ */
195
+ async function loadFromFile(dinkDir, name, options, currentAppName) {
196
+ const filePath = join(dinkDir, `${name}.yaml`);
197
+ let content;
198
+ try {
199
+ content = await readFile(filePath, 'utf-8');
200
+ }
201
+ catch {
202
+ throw new DinkEnvError(`environment "${name}" not found (expected ${filePath})`, 'NOT_FOUND');
203
+ }
204
+ const { server, apiKey, defaultApp, apps } = parseEnvYaml(content);
205
+ if (!server) {
206
+ throw new Error(`environment "${name}": server field is empty or missing`);
207
+ }
208
+ const appId = resolveAppId(options?.app, currentAppName ?? '', defaultApp);
209
+ // If the resolved app has its own api_key in the apps section, use it
210
+ let resolvedApiKey = apiKey;
211
+ let syncKey = '';
212
+ if (appId && apps[appId]) {
213
+ const appConfig = apps[appId];
214
+ if (appConfig.apiKey) {
215
+ resolvedApiKey = appConfig.apiKey;
216
+ }
217
+ syncKey = appConfig.syncKey;
218
+ }
219
+ // Env var fallback for sync key
220
+ if (!syncKey) {
221
+ syncKey = process.env['DINK_APP_SYNC_KEY'] ?? '';
222
+ }
223
+ return { name, server, apiKey: resolvedApiKey, appId, syncKey };
224
+ }
225
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/env/index.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -3,4 +3,5 @@ export { extractPayload, wrapResponse } from './types.js';
3
3
  export { EdgeClient, parseEdgeKey, type ParsedEdgeKey } from './edge/client.js';
4
4
  export { ServiceBuilder } from './edge/service-builder.js';
5
5
  export { CenterClient } from './center/index.js';
6
+ export { loadDinkEnv, DinkEnvError, type DinkEnv, type LoadOptions } from './env/index.js';
6
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,YAAY,EACV,iBAAiB,EACjB,cAAc,EACd,aAAa,EACb,YAAY,EAEZ,OAAO,EACP,SAAS,EACT,WAAW,EACX,gBAAgB,EAChB,eAAe,EACf,eAAe,GAChB,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAG1D,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAChF,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAG3D,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,YAAY,EACV,iBAAiB,EACjB,cAAc,EACd,aAAa,EACb,YAAY,EAEZ,OAAO,EACP,SAAS,EACT,WAAW,EACX,gBAAgB,EAChB,eAAe,EACf,eAAe,GAChB,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAG1D,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAChF,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAG3D,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAGjD,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,KAAK,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,gBAAgB,CAAC"}
package/dist/index.js CHANGED
@@ -7,4 +7,6 @@ export { EdgeClient, parseEdgeKey } from './edge/client.js';
7
7
  export { ServiceBuilder } from './edge/service-builder.js';
8
8
  // Export center client for connecting to dinkd from the center/cloud
9
9
  export { CenterClient } from './center/index.js';
10
+ // Export environment/credential loader (Node.js only)
11
+ export { loadDinkEnv, DinkEnvError } from './env/index.js';
10
12
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,2EAA2E;AAiB3E,0BAA0B;AAC1B,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1D,0DAA0D;AAC1D,OAAO,EAAE,UAAU,EAAE,YAAY,EAAsB,MAAM,kBAAkB,CAAC;AAChF,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAE3D,qEAAqE;AACrE,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,2EAA2E;AAiB3E,0BAA0B;AAC1B,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1D,0DAA0D;AAC1D,OAAO,EAAE,UAAU,EAAE,YAAY,EAAsB,MAAM,kBAAkB,CAAC;AAChF,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAE3D,qEAAqE;AACrE,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,sDAAsD;AACtD,OAAO,EAAE,WAAW,EAAE,YAAY,EAAkC,MAAM,gBAAgB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fatagnus/dink-sdk",
3
- "version": "2.13.2",
3
+ "version": "2.15.0",
4
4
  "description": "TypeScript SDK for Dink edge mesh platform",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -21,6 +21,10 @@
21
21
  "./center": {
22
22
  "types": "./dist/center/index.d.ts",
23
23
  "import": "./dist/center/index.js"
24
+ },
25
+ "./env": {
26
+ "types": "./dist/env/index.d.ts",
27
+ "import": "./dist/env/index.js"
24
28
  }
25
29
  },
26
30
  "scripts": {