@rolino/local-auth 0.1.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/CHANGELOG.md ADDED
@@ -0,0 +1,32 @@
1
+ # @rolino/local-auth
2
+
3
+ ## 0.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 2f5220f: Expose Bluesky consistently across public publishing contracts, the SDK, CLI,
8
+ and MCP, including 300-grapheme caption overrides, text and image readiness,
9
+ health reporting, scheduling, and immediate publishing. The fixed release group
10
+ also advances `@rolino/local-auth` even though its source does not change.
11
+ - edd5f2e: Validate YouTube descriptions by their 5,000-byte UTF-8 provider limit so every Rolino client rejects multibyte text that YouTube would refuse.
12
+ - 1b644ef: Prepare the first coordinated public release of Rolino's contracts, SDK, shared
13
+ local authentication, CLI, and local stdio MCP packages.
14
+ - 420484d: Add reusable media discovery and direct local-file uploads across the public
15
+ API contracts, SDK, CLI, and MCP so agents can safely prepare folder-based
16
+ social scheduling workflows. The fixed release group also advances
17
+ `@rolino/local-auth` even though its source does not change.
18
+ - 52373a6: Expose YouTube consistently across public contracts, the SDK, CLI, and MCP,
19
+ including explicit draft metadata, readiness and health, early scheduled
20
+ preparation, exact publish confirmation, and typed pending reconciliation.
21
+ The fixed release group also advances `@rolino/local-auth` even though its
22
+ source does not change.
23
+
24
+ ### Patch Changes
25
+
26
+ - Updated dependencies [fdc916f]
27
+ - Updated dependencies [2f5220f]
28
+ - Updated dependencies [edd5f2e]
29
+ - Updated dependencies [1b644ef]
30
+ - Updated dependencies [420484d]
31
+ - Updated dependencies [52373a6]
32
+ - @rolino/sdk@0.1.0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Vlad
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,20 @@
1
+ # `@rolino/local-auth`
2
+
3
+ Node-only, host-scoped credential storage shared by Rolino's CLI and local
4
+ stdio MCP adapter. Environment credentials take precedence over the portable
5
+ owner-only file store.
6
+
7
+ This package must not be used by the browser, public SDK, application routes,
8
+ or server domain services. It is published only as a supported transitive
9
+ dependency of the CLI and local MCP server; applications should not treat its
10
+ file format as a public credential-storage API.
11
+
12
+ ## Support, security, and license
13
+
14
+ Stable releases are published only after the maintainer approves the release
15
+ gate. Report bugs through the
16
+ [Rolino issue tracker](https://github.com/deifos/rolino/issues) and security
17
+ issues through the repository's
18
+ [security policy](https://github.com/deifos/rolino/security/policy).
19
+
20
+ `@rolino/local-auth` is available under the MIT License.
package/dist/index.cjs ADDED
@@ -0,0 +1,117 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ clearStoredCredential: () => clearStoredCredential,
24
+ credentialStorePath: () => credentialStorePath,
25
+ loadStoredCredential: () => loadStoredCredential,
26
+ resolveCredential: () => resolveCredential,
27
+ saveStoredCredential: () => saveStoredCredential
28
+ });
29
+ module.exports = __toCommonJS(index_exports);
30
+ var import_node_fs = require("fs");
31
+ var import_node_os = require("os");
32
+ var import_node_path = require("path");
33
+ var import_sdk = require("@rolino/sdk");
34
+ function defaultConfigDirectory(env) {
35
+ if (env.ROLINO_CONFIG_DIR) return env.ROLINO_CONFIG_DIR;
36
+ if (process.platform === "win32" && env.APPDATA) {
37
+ return (0, import_node_path.join)(env.APPDATA, "Rolino");
38
+ }
39
+ if (process.platform === "darwin") {
40
+ return (0, import_node_path.join)((0, import_node_os.homedir)(), "Library", "Application Support", "Rolino");
41
+ }
42
+ return (0, import_node_path.join)(env.XDG_CONFIG_HOME ?? (0, import_node_path.join)((0, import_node_os.homedir)(), ".config"), "rolino");
43
+ }
44
+ function credentialStorePath(env = process.env) {
45
+ return (0, import_node_path.join)(defaultConfigDirectory(env), "credentials.json");
46
+ }
47
+ function isStoredCredential(value) {
48
+ if (!value || typeof value !== "object") return false;
49
+ const credential = value;
50
+ return typeof credential.token === "string" && credential.token.length > 0 && typeof credential.createdAt === "string" && typeof credential.expiresAt === "string" && Boolean(credential.organization) && typeof credential.organization?.id === "string" && typeof credential.organization?.name === "string";
51
+ }
52
+ function readStore(env) {
53
+ const path = credentialStorePath(env);
54
+ if (!(0, import_node_fs.existsSync)(path)) return { version: 1, credentials: {} };
55
+ let parsed;
56
+ try {
57
+ parsed = JSON.parse((0, import_node_fs.readFileSync)(path, "utf8"));
58
+ } catch {
59
+ throw new TypeError(`Rolino could not read its credential store at ${path}.`);
60
+ }
61
+ if (!parsed || typeof parsed !== "object") {
62
+ throw new TypeError(`Rolino's credential store at ${path} is invalid.`);
63
+ }
64
+ const candidate = parsed;
65
+ if (candidate.version !== 1 || !candidate.credentials || typeof candidate.credentials !== "object" || !Object.values(candidate.credentials).every(isStoredCredential)) {
66
+ throw new TypeError(`Rolino's credential store at ${path} is invalid.`);
67
+ }
68
+ return candidate;
69
+ }
70
+ function writeStore(store, env) {
71
+ const path = credentialStorePath(env);
72
+ (0, import_node_fs.mkdirSync)((0, import_node_path.dirname)(path), { recursive: true, mode: 448 });
73
+ (0, import_node_fs.writeFileSync)(path, `${JSON.stringify(store, null, 2)}
74
+ `, {
75
+ encoding: "utf8",
76
+ mode: 384
77
+ });
78
+ (0, import_node_fs.chmodSync)(path, 384);
79
+ }
80
+ function loadStoredCredential(baseUrl, env = process.env) {
81
+ return readStore(env).credentials[(0, import_sdk.normalizeRolinoBaseUrl)(baseUrl)] ?? null;
82
+ }
83
+ function saveStoredCredential(baseUrl, credential, env = process.env) {
84
+ const store = readStore(env);
85
+ store.credentials[(0, import_sdk.normalizeRolinoBaseUrl)(baseUrl)] = credential;
86
+ writeStore(store, env);
87
+ return credentialStorePath(env);
88
+ }
89
+ function clearStoredCredential(baseUrl, env = process.env) {
90
+ const path = credentialStorePath(env);
91
+ const store = readStore(env);
92
+ const key = (0, import_sdk.normalizeRolinoBaseUrl)(baseUrl);
93
+ const existed = Boolean(store.credentials[key]);
94
+ delete store.credentials[key];
95
+ if (Object.keys(store.credentials).length === 0) {
96
+ if ((0, import_node_fs.existsSync)(path)) (0, import_node_fs.unlinkSync)(path);
97
+ } else {
98
+ writeStore(store, env);
99
+ }
100
+ return existed;
101
+ }
102
+ function resolveCredential(baseUrl, env = process.env) {
103
+ if (env.ROLINO_TOKEN) {
104
+ return { source: "environment", token: env.ROLINO_TOKEN };
105
+ }
106
+ const stored = loadStoredCredential(baseUrl, env);
107
+ return stored ? { source: "stored", token: stored.token, credential: stored } : { source: "none", token: null };
108
+ }
109
+ // Annotate the CommonJS export names for ESM import in node:
110
+ 0 && (module.exports = {
111
+ clearStoredCredential,
112
+ credentialStorePath,
113
+ loadStoredCredential,
114
+ resolveCredential,
115
+ saveStoredCredential
116
+ });
117
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import {\r\n chmodSync,\r\n existsSync,\r\n mkdirSync,\r\n readFileSync,\r\n unlinkSync,\r\n writeFileSync,\r\n} from \"node:fs\";\r\nimport { homedir } from \"node:os\";\r\nimport { dirname, join } from \"node:path\";\r\n\r\nimport { normalizeRolinoBaseUrl } from \"@rolino/sdk\";\r\n\r\nexport type StoredCredential = {\r\n token: string;\r\n createdAt: string;\r\n expiresAt: string;\r\n organization: { id: string; name: string };\r\n};\r\n\r\ntype CredentialStore = {\r\n version: 1;\r\n credentials: Record<string, StoredCredential>;\r\n};\r\n\r\nfunction defaultConfigDirectory(env: Record<string, string | undefined>) {\r\n if (env.ROLINO_CONFIG_DIR) return env.ROLINO_CONFIG_DIR;\r\n if (process.platform === \"win32\" && env.APPDATA) {\r\n return join(env.APPDATA, \"Rolino\");\r\n }\r\n if (process.platform === \"darwin\") {\r\n return join(homedir(), \"Library\", \"Application Support\", \"Rolino\");\r\n }\r\n return join(env.XDG_CONFIG_HOME ?? join(homedir(), \".config\"), \"rolino\");\r\n}\r\n\r\nexport function credentialStorePath(\r\n env: Record<string, string | undefined> = process.env,\r\n) {\r\n return join(defaultConfigDirectory(env), \"credentials.json\");\r\n}\r\n\r\nfunction isStoredCredential(value: unknown): value is StoredCredential {\r\n if (!value || typeof value !== \"object\") return false;\r\n const credential = value as Partial<StoredCredential>;\r\n return typeof credential.token === \"string\"\r\n && credential.token.length > 0\r\n && typeof credential.createdAt === \"string\"\r\n && typeof credential.expiresAt === \"string\"\r\n && Boolean(credential.organization)\r\n && typeof credential.organization?.id === \"string\"\r\n && typeof credential.organization?.name === \"string\";\r\n}\r\n\r\nfunction readStore(env: Record<string, string | undefined>): CredentialStore {\r\n const path = credentialStorePath(env);\r\n if (!existsSync(path)) return { version: 1, credentials: {} };\r\n\r\n let parsed: unknown;\r\n try {\r\n parsed = JSON.parse(readFileSync(path, \"utf8\"));\r\n } catch {\r\n throw new TypeError(`Rolino could not read its credential store at ${path}.`);\r\n }\r\n if (!parsed || typeof parsed !== \"object\") {\r\n throw new TypeError(`Rolino's credential store at ${path} is invalid.`);\r\n }\r\n const candidate = parsed as Partial<CredentialStore>;\r\n if (\r\n candidate.version !== 1\r\n || !candidate.credentials\r\n || typeof candidate.credentials !== \"object\"\r\n || !Object.values(candidate.credentials).every(isStoredCredential)\r\n ) {\r\n throw new TypeError(`Rolino's credential store at ${path} is invalid.`);\r\n }\r\n return candidate as CredentialStore;\r\n}\r\n\r\nfunction writeStore(\r\n store: CredentialStore,\r\n env: Record<string, string | undefined>,\r\n) {\r\n const path = credentialStorePath(env);\r\n mkdirSync(dirname(path), { recursive: true, mode: 0o700 });\r\n writeFileSync(path, `${JSON.stringify(store, null, 2)}\\n`, {\r\n encoding: \"utf8\",\r\n mode: 0o600,\r\n });\r\n chmodSync(path, 0o600);\r\n}\r\n\r\nexport function loadStoredCredential(\r\n baseUrl: string,\r\n env: Record<string, string | undefined> = process.env,\r\n) {\r\n return readStore(env).credentials[normalizeRolinoBaseUrl(baseUrl)] ?? null;\r\n}\r\n\r\nexport function saveStoredCredential(\r\n baseUrl: string,\r\n credential: StoredCredential,\r\n env: Record<string, string | undefined> = process.env,\r\n) {\r\n const store = readStore(env);\r\n store.credentials[normalizeRolinoBaseUrl(baseUrl)] = credential;\r\n writeStore(store, env);\r\n return credentialStorePath(env);\r\n}\r\n\r\nexport function clearStoredCredential(\r\n baseUrl: string,\r\n env: Record<string, string | undefined> = process.env,\r\n) {\r\n const path = credentialStorePath(env);\r\n const store = readStore(env);\r\n const key = normalizeRolinoBaseUrl(baseUrl);\r\n const existed = Boolean(store.credentials[key]);\r\n delete store.credentials[key];\r\n\r\n if (Object.keys(store.credentials).length === 0) {\r\n if (existsSync(path)) unlinkSync(path);\r\n } else {\r\n writeStore(store, env);\r\n }\r\n return existed;\r\n}\r\n\r\nexport function resolveCredential(\r\n baseUrl: string,\r\n env: Record<string, string | undefined> = process.env,\r\n) {\r\n if (env.ROLINO_TOKEN) {\r\n return { source: \"environment\" as const, token: env.ROLINO_TOKEN };\r\n }\r\n const stored = loadStoredCredential(baseUrl, env);\r\n return stored\r\n ? { source: \"stored\" as const, token: stored.token, credential: stored }\r\n : { source: \"none\" as const, token: null };\r\n}\r\n"],"mappings":"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","names":[]}
@@ -0,0 +1,28 @@
1
+ type StoredCredential = {
2
+ token: string;
3
+ createdAt: string;
4
+ expiresAt: string;
5
+ organization: {
6
+ id: string;
7
+ name: string;
8
+ };
9
+ };
10
+ declare function credentialStorePath(env?: Record<string, string | undefined>): string;
11
+ declare function loadStoredCredential(baseUrl: string, env?: Record<string, string | undefined>): StoredCredential | null;
12
+ declare function saveStoredCredential(baseUrl: string, credential: StoredCredential, env?: Record<string, string | undefined>): string;
13
+ declare function clearStoredCredential(baseUrl: string, env?: Record<string, string | undefined>): boolean;
14
+ declare function resolveCredential(baseUrl: string, env?: Record<string, string | undefined>): {
15
+ source: "environment";
16
+ token: string;
17
+ credential?: undefined;
18
+ } | {
19
+ source: "stored";
20
+ token: string;
21
+ credential: StoredCredential;
22
+ } | {
23
+ source: "none";
24
+ token: null;
25
+ credential?: undefined;
26
+ };
27
+
28
+ export { type StoredCredential, clearStoredCredential, credentialStorePath, loadStoredCredential, resolveCredential, saveStoredCredential };
@@ -0,0 +1,28 @@
1
+ type StoredCredential = {
2
+ token: string;
3
+ createdAt: string;
4
+ expiresAt: string;
5
+ organization: {
6
+ id: string;
7
+ name: string;
8
+ };
9
+ };
10
+ declare function credentialStorePath(env?: Record<string, string | undefined>): string;
11
+ declare function loadStoredCredential(baseUrl: string, env?: Record<string, string | undefined>): StoredCredential | null;
12
+ declare function saveStoredCredential(baseUrl: string, credential: StoredCredential, env?: Record<string, string | undefined>): string;
13
+ declare function clearStoredCredential(baseUrl: string, env?: Record<string, string | undefined>): boolean;
14
+ declare function resolveCredential(baseUrl: string, env?: Record<string, string | undefined>): {
15
+ source: "environment";
16
+ token: string;
17
+ credential?: undefined;
18
+ } | {
19
+ source: "stored";
20
+ token: string;
21
+ credential: StoredCredential;
22
+ } | {
23
+ source: "none";
24
+ token: null;
25
+ credential?: undefined;
26
+ };
27
+
28
+ export { type StoredCredential, clearStoredCredential, credentialStorePath, loadStoredCredential, resolveCredential, saveStoredCredential };
package/dist/index.js ADDED
@@ -0,0 +1,95 @@
1
+ // src/index.ts
2
+ import {
3
+ chmodSync,
4
+ existsSync,
5
+ mkdirSync,
6
+ readFileSync,
7
+ unlinkSync,
8
+ writeFileSync
9
+ } from "fs";
10
+ import { homedir } from "os";
11
+ import { dirname, join } from "path";
12
+ import { normalizeRolinoBaseUrl } from "@rolino/sdk";
13
+ function defaultConfigDirectory(env) {
14
+ if (env.ROLINO_CONFIG_DIR) return env.ROLINO_CONFIG_DIR;
15
+ if (process.platform === "win32" && env.APPDATA) {
16
+ return join(env.APPDATA, "Rolino");
17
+ }
18
+ if (process.platform === "darwin") {
19
+ return join(homedir(), "Library", "Application Support", "Rolino");
20
+ }
21
+ return join(env.XDG_CONFIG_HOME ?? join(homedir(), ".config"), "rolino");
22
+ }
23
+ function credentialStorePath(env = process.env) {
24
+ return join(defaultConfigDirectory(env), "credentials.json");
25
+ }
26
+ function isStoredCredential(value) {
27
+ if (!value || typeof value !== "object") return false;
28
+ const credential = value;
29
+ return typeof credential.token === "string" && credential.token.length > 0 && typeof credential.createdAt === "string" && typeof credential.expiresAt === "string" && Boolean(credential.organization) && typeof credential.organization?.id === "string" && typeof credential.organization?.name === "string";
30
+ }
31
+ function readStore(env) {
32
+ const path = credentialStorePath(env);
33
+ if (!existsSync(path)) return { version: 1, credentials: {} };
34
+ let parsed;
35
+ try {
36
+ parsed = JSON.parse(readFileSync(path, "utf8"));
37
+ } catch {
38
+ throw new TypeError(`Rolino could not read its credential store at ${path}.`);
39
+ }
40
+ if (!parsed || typeof parsed !== "object") {
41
+ throw new TypeError(`Rolino's credential store at ${path} is invalid.`);
42
+ }
43
+ const candidate = parsed;
44
+ if (candidate.version !== 1 || !candidate.credentials || typeof candidate.credentials !== "object" || !Object.values(candidate.credentials).every(isStoredCredential)) {
45
+ throw new TypeError(`Rolino's credential store at ${path} is invalid.`);
46
+ }
47
+ return candidate;
48
+ }
49
+ function writeStore(store, env) {
50
+ const path = credentialStorePath(env);
51
+ mkdirSync(dirname(path), { recursive: true, mode: 448 });
52
+ writeFileSync(path, `${JSON.stringify(store, null, 2)}
53
+ `, {
54
+ encoding: "utf8",
55
+ mode: 384
56
+ });
57
+ chmodSync(path, 384);
58
+ }
59
+ function loadStoredCredential(baseUrl, env = process.env) {
60
+ return readStore(env).credentials[normalizeRolinoBaseUrl(baseUrl)] ?? null;
61
+ }
62
+ function saveStoredCredential(baseUrl, credential, env = process.env) {
63
+ const store = readStore(env);
64
+ store.credentials[normalizeRolinoBaseUrl(baseUrl)] = credential;
65
+ writeStore(store, env);
66
+ return credentialStorePath(env);
67
+ }
68
+ function clearStoredCredential(baseUrl, env = process.env) {
69
+ const path = credentialStorePath(env);
70
+ const store = readStore(env);
71
+ const key = normalizeRolinoBaseUrl(baseUrl);
72
+ const existed = Boolean(store.credentials[key]);
73
+ delete store.credentials[key];
74
+ if (Object.keys(store.credentials).length === 0) {
75
+ if (existsSync(path)) unlinkSync(path);
76
+ } else {
77
+ writeStore(store, env);
78
+ }
79
+ return existed;
80
+ }
81
+ function resolveCredential(baseUrl, env = process.env) {
82
+ if (env.ROLINO_TOKEN) {
83
+ return { source: "environment", token: env.ROLINO_TOKEN };
84
+ }
85
+ const stored = loadStoredCredential(baseUrl, env);
86
+ return stored ? { source: "stored", token: stored.token, credential: stored } : { source: "none", token: null };
87
+ }
88
+ export {
89
+ clearStoredCredential,
90
+ credentialStorePath,
91
+ loadStoredCredential,
92
+ resolveCredential,
93
+ saveStoredCredential
94
+ };
95
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import {\r\n chmodSync,\r\n existsSync,\r\n mkdirSync,\r\n readFileSync,\r\n unlinkSync,\r\n writeFileSync,\r\n} from \"node:fs\";\r\nimport { homedir } from \"node:os\";\r\nimport { dirname, join } from \"node:path\";\r\n\r\nimport { normalizeRolinoBaseUrl } from \"@rolino/sdk\";\r\n\r\nexport type StoredCredential = {\r\n token: string;\r\n createdAt: string;\r\n expiresAt: string;\r\n organization: { id: string; name: string };\r\n};\r\n\r\ntype CredentialStore = {\r\n version: 1;\r\n credentials: Record<string, StoredCredential>;\r\n};\r\n\r\nfunction defaultConfigDirectory(env: Record<string, string | undefined>) {\r\n if (env.ROLINO_CONFIG_DIR) return env.ROLINO_CONFIG_DIR;\r\n if (process.platform === \"win32\" && env.APPDATA) {\r\n return join(env.APPDATA, \"Rolino\");\r\n }\r\n if (process.platform === \"darwin\") {\r\n return join(homedir(), \"Library\", \"Application Support\", \"Rolino\");\r\n }\r\n return join(env.XDG_CONFIG_HOME ?? join(homedir(), \".config\"), \"rolino\");\r\n}\r\n\r\nexport function credentialStorePath(\r\n env: Record<string, string | undefined> = process.env,\r\n) {\r\n return join(defaultConfigDirectory(env), \"credentials.json\");\r\n}\r\n\r\nfunction isStoredCredential(value: unknown): value is StoredCredential {\r\n if (!value || typeof value !== \"object\") return false;\r\n const credential = value as Partial<StoredCredential>;\r\n return typeof credential.token === \"string\"\r\n && credential.token.length > 0\r\n && typeof credential.createdAt === \"string\"\r\n && typeof credential.expiresAt === \"string\"\r\n && Boolean(credential.organization)\r\n && typeof credential.organization?.id === \"string\"\r\n && typeof credential.organization?.name === \"string\";\r\n}\r\n\r\nfunction readStore(env: Record<string, string | undefined>): CredentialStore {\r\n const path = credentialStorePath(env);\r\n if (!existsSync(path)) return { version: 1, credentials: {} };\r\n\r\n let parsed: unknown;\r\n try {\r\n parsed = JSON.parse(readFileSync(path, \"utf8\"));\r\n } catch {\r\n throw new TypeError(`Rolino could not read its credential store at ${path}.`);\r\n }\r\n if (!parsed || typeof parsed !== \"object\") {\r\n throw new TypeError(`Rolino's credential store at ${path} is invalid.`);\r\n }\r\n const candidate = parsed as Partial<CredentialStore>;\r\n if (\r\n candidate.version !== 1\r\n || !candidate.credentials\r\n || typeof candidate.credentials !== \"object\"\r\n || !Object.values(candidate.credentials).every(isStoredCredential)\r\n ) {\r\n throw new TypeError(`Rolino's credential store at ${path} is invalid.`);\r\n }\r\n return candidate as CredentialStore;\r\n}\r\n\r\nfunction writeStore(\r\n store: CredentialStore,\r\n env: Record<string, string | undefined>,\r\n) {\r\n const path = credentialStorePath(env);\r\n mkdirSync(dirname(path), { recursive: true, mode: 0o700 });\r\n writeFileSync(path, `${JSON.stringify(store, null, 2)}\\n`, {\r\n encoding: \"utf8\",\r\n mode: 0o600,\r\n });\r\n chmodSync(path, 0o600);\r\n}\r\n\r\nexport function loadStoredCredential(\r\n baseUrl: string,\r\n env: Record<string, string | undefined> = process.env,\r\n) {\r\n return readStore(env).credentials[normalizeRolinoBaseUrl(baseUrl)] ?? null;\r\n}\r\n\r\nexport function saveStoredCredential(\r\n baseUrl: string,\r\n credential: StoredCredential,\r\n env: Record<string, string | undefined> = process.env,\r\n) {\r\n const store = readStore(env);\r\n store.credentials[normalizeRolinoBaseUrl(baseUrl)] = credential;\r\n writeStore(store, env);\r\n return credentialStorePath(env);\r\n}\r\n\r\nexport function clearStoredCredential(\r\n baseUrl: string,\r\n env: Record<string, string | undefined> = process.env,\r\n) {\r\n const path = credentialStorePath(env);\r\n const store = readStore(env);\r\n const key = normalizeRolinoBaseUrl(baseUrl);\r\n const existed = Boolean(store.credentials[key]);\r\n delete store.credentials[key];\r\n\r\n if (Object.keys(store.credentials).length === 0) {\r\n if (existsSync(path)) unlinkSync(path);\r\n } else {\r\n writeStore(store, env);\r\n }\r\n return existed;\r\n}\r\n\r\nexport function resolveCredential(\r\n baseUrl: string,\r\n env: Record<string, string | undefined> = process.env,\r\n) {\r\n if (env.ROLINO_TOKEN) {\r\n return { source: \"environment\" as const, token: env.ROLINO_TOKEN };\r\n }\r\n const stored = loadStoredCredential(baseUrl, env);\r\n return stored\r\n ? { source: \"stored\" as const, token: stored.token, credential: stored }\r\n : { source: \"none\" as const, token: null };\r\n}\r\n"],"mappings":"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","names":[]}
package/package.json ADDED
@@ -0,0 +1,62 @@
1
+ {
2
+ "name": "@rolino/local-auth",
3
+ "version": "0.1.0",
4
+ "description": "Host-scoped local credential storage shared by Rolino's Node.js adapters",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "keywords": [
8
+ "rolino",
9
+ "authentication",
10
+ "credentials",
11
+ "cli",
12
+ "mcp"
13
+ ],
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "git+https://github.com/deifos/rolino.git",
17
+ "directory": "packages/local-auth"
18
+ },
19
+ "homepage": "https://github.com/deifos/rolino/tree/main/packages/local-auth#readme",
20
+ "bugs": {
21
+ "url": "https://github.com/deifos/rolino/issues"
22
+ },
23
+ "sideEffects": false,
24
+ "main": "./dist/index.cjs",
25
+ "module": "./dist/index.js",
26
+ "types": "./dist/index.d.ts",
27
+ "exports": {
28
+ ".": {
29
+ "import": {
30
+ "types": "./dist/index.d.ts",
31
+ "default": "./dist/index.js"
32
+ },
33
+ "require": {
34
+ "types": "./dist/index.d.cts",
35
+ "default": "./dist/index.cjs"
36
+ }
37
+ }
38
+ },
39
+ "files": [
40
+ "dist/**/*.js",
41
+ "dist/**/*.cjs",
42
+ "dist/**/*.map",
43
+ "dist/**/*.d.ts",
44
+ "dist/**/*.d.cts",
45
+ "README.md",
46
+ "CHANGELOG.md",
47
+ "LICENSE"
48
+ ],
49
+ "publishConfig": {
50
+ "access": "public"
51
+ },
52
+ "scripts": {
53
+ "build": "tsup src/index.ts --format esm,cjs --dts --sourcemap --clean",
54
+ "typecheck": "tsc --noEmit"
55
+ },
56
+ "dependencies": {
57
+ "@rolino/sdk": "0.1.0"
58
+ },
59
+ "engines": {
60
+ "node": ">=20.19.0"
61
+ }
62
+ }