@slates/profiles 1.0.0-rc.2
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.cjs +445 -0
- package/dist/index.d.cts +122 -0
- package/dist/index.d.ts +122 -0
- package/dist/index.module.js +403 -0
- package/package.json +44 -0
- package/src/client.ts +143 -0
- package/src/index.ts +3 -0
- package/src/store.test.ts +315 -0
- package/src/store.ts +422 -0
- package/src/types.ts +67 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,445 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/index.ts
|
|
31
|
+
var index_exports = {};
|
|
32
|
+
__export(index_exports, {
|
|
33
|
+
SlatesCliStore: () => SlatesCliStore,
|
|
34
|
+
createSlatesClientFromProfile: () => createSlatesClientFromProfile,
|
|
35
|
+
openSlatesCliStore: () => openSlatesCliStore,
|
|
36
|
+
resolveSlatesCliDir: () => resolveSlatesCliDir,
|
|
37
|
+
resolveSlatesCliProfilesDir: () => resolveSlatesCliProfilesDir,
|
|
38
|
+
resolveSlatesCliRoot: () => resolveSlatesCliRoot
|
|
39
|
+
});
|
|
40
|
+
module.exports = __toCommonJS(index_exports);
|
|
41
|
+
|
|
42
|
+
// src/client.ts
|
|
43
|
+
var import_client = require("@slates/client");
|
|
44
|
+
var import_path2 = __toESM(require("path"), 1);
|
|
45
|
+
var import_url = require("url");
|
|
46
|
+
|
|
47
|
+
// src/store.ts
|
|
48
|
+
var import_child_process = require("child_process");
|
|
49
|
+
var import_crypto = require("crypto");
|
|
50
|
+
var import_promises = require("fs/promises");
|
|
51
|
+
var import_path = __toESM(require("path"), 1);
|
|
52
|
+
var STORE_VERSION = 3;
|
|
53
|
+
var CLI_DIR_NAME = ".slates-cli";
|
|
54
|
+
var PROFILES_DIR_NAME = "profiles";
|
|
55
|
+
var STORE_FILE_NAME = "store.json";
|
|
56
|
+
var GITIGNORE_FILE_NAME = ".gitignore";
|
|
57
|
+
var createEmptyStore = () => ({
|
|
58
|
+
version: STORE_VERSION,
|
|
59
|
+
currentProfileId: null,
|
|
60
|
+
profiles: {},
|
|
61
|
+
oauthCredentials: {}
|
|
62
|
+
});
|
|
63
|
+
var now = () => (/* @__PURE__ */ new Date()).toISOString();
|
|
64
|
+
var ensureDir = async (dirPath) => {
|
|
65
|
+
await (0, import_promises.mkdir)(dirPath, { recursive: true });
|
|
66
|
+
};
|
|
67
|
+
var ensureGitIgnore = async (dirPath) => {
|
|
68
|
+
let filePath = import_path.default.join(dirPath, GITIGNORE_FILE_NAME);
|
|
69
|
+
await (0, import_promises.writeFile)(filePath, "*\n!.gitignore\n", { encoding: "utf-8" }).catch(async (error) => {
|
|
70
|
+
if (error.code === "EEXIST") return;
|
|
71
|
+
throw error;
|
|
72
|
+
});
|
|
73
|
+
};
|
|
74
|
+
var resolveSlatesCliRoot = (cwd = process.cwd()) => {
|
|
75
|
+
try {
|
|
76
|
+
return (0, import_child_process.execFileSync)("git", ["rev-parse", "--show-toplevel"], {
|
|
77
|
+
cwd,
|
|
78
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
79
|
+
encoding: "utf-8"
|
|
80
|
+
}).trim();
|
|
81
|
+
} catch {
|
|
82
|
+
return cwd;
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
var resolveSlatesCliDir = (cwd = process.cwd()) => import_path.default.join(resolveSlatesCliRoot(cwd), CLI_DIR_NAME);
|
|
86
|
+
var resolveSlatesCliProfilesDir = (cwd = process.cwd()) => import_path.default.join(resolveSlatesCliDir(cwd), PROFILES_DIR_NAME);
|
|
87
|
+
var normalizeScopeKey = (scopeKey) => import_path.default.posix.normalize(scopeKey.replace(/\\/g, "/")).replace(/^\.?\//, "");
|
|
88
|
+
var splitScopeKey = (scopeKey) => normalizeScopeKey(scopeKey).split("/").filter(Boolean).filter((segment) => segment !== "." && segment !== "..");
|
|
89
|
+
var resolveScopedStoreDir = (rootDir, scopeKey) => import_path.default.join(resolveSlatesCliProfilesDir(rootDir), ...splitScopeKey(scopeKey));
|
|
90
|
+
var resolveScopedStorePath = (rootDir, scopeKey) => import_path.default.join(resolveScopedStoreDir(rootDir, scopeKey), STORE_FILE_NAME);
|
|
91
|
+
var inferRootDirFromStorePath = (storePath) => {
|
|
92
|
+
let normalized = import_path.default.resolve(storePath);
|
|
93
|
+
let parts = normalized.split(import_path.default.sep).filter(Boolean);
|
|
94
|
+
let cliDirIndex = parts.lastIndexOf(CLI_DIR_NAME);
|
|
95
|
+
if (cliDirIndex === -1) {
|
|
96
|
+
throw new Error(`Could not infer Slates CLI root from store path: ${storePath}`);
|
|
97
|
+
}
|
|
98
|
+
let rootParts = parts.slice(0, cliDirIndex);
|
|
99
|
+
return import_path.default.join(import_path.default.sep, ...rootParts);
|
|
100
|
+
};
|
|
101
|
+
var resolveScopeKeyFromStorePath = (rootDir, storePath) => {
|
|
102
|
+
let profilesDir = resolveSlatesCliProfilesDir(rootDir);
|
|
103
|
+
let relativeDir = import_path.default.relative(profilesDir, import_path.default.dirname(storePath));
|
|
104
|
+
if (!relativeDir || relativeDir.startsWith("..") || import_path.default.isAbsolute(relativeDir)) {
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
return normalizeScopeKey(relativeDir);
|
|
108
|
+
};
|
|
109
|
+
var readStoreData = async (storePath) => {
|
|
110
|
+
try {
|
|
111
|
+
let raw = await (0, import_promises.readFile)(storePath, "utf-8");
|
|
112
|
+
if (!raw.trim()) {
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
return JSON.parse(raw);
|
|
116
|
+
} catch (error) {
|
|
117
|
+
if (error.code === "ENOENT") {
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
throw error;
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
var isProfileInScope = (rootDir, scopeKey, profile) => {
|
|
124
|
+
if (profile.target.type !== "local") {
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
let scopeDir = import_path.default.resolve(rootDir, ...splitScopeKey(scopeKey));
|
|
128
|
+
let entryPath = import_path.default.isAbsolute(profile.target.entry) ? profile.target.entry : import_path.default.resolve(rootDir, profile.target.entry);
|
|
129
|
+
let relative = import_path.default.relative(scopeDir, entryPath);
|
|
130
|
+
return relative !== "" && !relative.startsWith("..") && !import_path.default.isAbsolute(relative);
|
|
131
|
+
};
|
|
132
|
+
var loadMigratedLegacyStore = async (rootDir, scopeKey) => {
|
|
133
|
+
let legacyStorePath = import_path.default.join(resolveSlatesCliDir(rootDir), STORE_FILE_NAME);
|
|
134
|
+
let legacy = await readStoreData(legacyStorePath);
|
|
135
|
+
if (!legacy) {
|
|
136
|
+
return createEmptyStore();
|
|
137
|
+
}
|
|
138
|
+
let profiles = Object.fromEntries(
|
|
139
|
+
Object.entries(legacy.profiles ?? {}).filter(
|
|
140
|
+
([, profile]) => isProfileInScope(rootDir, scopeKey, profile)
|
|
141
|
+
)
|
|
142
|
+
);
|
|
143
|
+
let currentProfileId = legacy.currentProfileId && profiles[legacy.currentProfileId] ? legacy.currentProfileId : null;
|
|
144
|
+
return {
|
|
145
|
+
version: STORE_VERSION,
|
|
146
|
+
currentProfileId,
|
|
147
|
+
profiles,
|
|
148
|
+
oauthCredentials: {}
|
|
149
|
+
};
|
|
150
|
+
};
|
|
151
|
+
var SlatesCliStore = class _SlatesCliStore {
|
|
152
|
+
constructor(rootDir, dirPath, storePath, scope, data) {
|
|
153
|
+
this.rootDir = rootDir;
|
|
154
|
+
this.dirPath = dirPath;
|
|
155
|
+
this.storePath = storePath;
|
|
156
|
+
this.scope = scope;
|
|
157
|
+
this.data = data;
|
|
158
|
+
}
|
|
159
|
+
rootDir;
|
|
160
|
+
dirPath;
|
|
161
|
+
storePath;
|
|
162
|
+
scope;
|
|
163
|
+
data;
|
|
164
|
+
static async open(opts = {}) {
|
|
165
|
+
let rootDir = opts.storePath ? inferRootDirFromStorePath(opts.storePath) : resolveSlatesCliRoot(opts.cwd);
|
|
166
|
+
let cliDir = resolveSlatesCliDir(rootDir);
|
|
167
|
+
let scopeKey = opts.storePath ? resolveScopeKeyFromStorePath(rootDir, opts.storePath) : opts.scope?.key ? normalizeScopeKey(opts.scope.key) : null;
|
|
168
|
+
let dirPath = opts.storePath ? import_path.default.dirname(opts.storePath) : scopeKey ? resolveScopedStoreDir(rootDir, scopeKey) : cliDir;
|
|
169
|
+
let storePath = opts.storePath ?? (scopeKey ? resolveScopedStorePath(rootDir, scopeKey) : import_path.default.join(cliDir, STORE_FILE_NAME));
|
|
170
|
+
await ensureDir(cliDir);
|
|
171
|
+
await ensureGitIgnore(cliDir);
|
|
172
|
+
await ensureDir(dirPath);
|
|
173
|
+
let parsed = await readStoreData(storePath);
|
|
174
|
+
let data = parsed ? {
|
|
175
|
+
version: STORE_VERSION,
|
|
176
|
+
currentProfileId: parsed.currentProfileId ?? null,
|
|
177
|
+
profiles: parsed.profiles ?? {},
|
|
178
|
+
oauthCredentials: parsed.oauthCredentials ?? {}
|
|
179
|
+
} : scopeKey ? await loadMigratedLegacyStore(rootDir, scopeKey) : createEmptyStore();
|
|
180
|
+
if (!parsed) {
|
|
181
|
+
await (0, import_promises.writeFile)(storePath, JSON.stringify(data, null, 2) + "\n", "utf-8");
|
|
182
|
+
}
|
|
183
|
+
return new _SlatesCliStore(
|
|
184
|
+
rootDir,
|
|
185
|
+
dirPath,
|
|
186
|
+
storePath,
|
|
187
|
+
scopeKey ? { key: scopeKey, name: opts.scope?.name } : null,
|
|
188
|
+
data
|
|
189
|
+
);
|
|
190
|
+
}
|
|
191
|
+
async save() {
|
|
192
|
+
await ensureDir(this.dirPath);
|
|
193
|
+
await ensureDir(resolveSlatesCliDir(this.rootDir));
|
|
194
|
+
await ensureGitIgnore(resolveSlatesCliDir(this.rootDir));
|
|
195
|
+
await (0, import_promises.writeFile)(this.storePath, JSON.stringify(this.data, null, 2) + "\n", "utf-8");
|
|
196
|
+
}
|
|
197
|
+
listProfiles() {
|
|
198
|
+
return Object.values(this.data.profiles).sort((a, b) => a.name.localeCompare(b.name));
|
|
199
|
+
}
|
|
200
|
+
listOAuthCredentials(authMethodId) {
|
|
201
|
+
return Object.values(this.data.oauthCredentials).filter((credential) => !authMethodId || credential.authMethodId === authMethodId).sort((a, b) => a.name.localeCompare(b.name));
|
|
202
|
+
}
|
|
203
|
+
getOAuthCredential(credentialId, authMethodId) {
|
|
204
|
+
if (credentialId) {
|
|
205
|
+
let direct = this.data.oauthCredentials[credentialId];
|
|
206
|
+
if (direct && (!authMethodId || direct.authMethodId === authMethodId)) {
|
|
207
|
+
return direct;
|
|
208
|
+
}
|
|
209
|
+
let matches = this.listOAuthCredentials(authMethodId ?? void 0).filter(
|
|
210
|
+
(credential) => credential.name === credentialId
|
|
211
|
+
);
|
|
212
|
+
if (matches.length === 1) {
|
|
213
|
+
return matches[0];
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
return this.listOAuthCredentials(authMethodId ?? void 0)[0] ?? null;
|
|
217
|
+
}
|
|
218
|
+
getProfile(profileId) {
|
|
219
|
+
if (profileId) {
|
|
220
|
+
if (this.data.profiles[profileId]) {
|
|
221
|
+
return this.data.profiles[profileId] ?? null;
|
|
222
|
+
}
|
|
223
|
+
let matches = this.listProfiles().filter((profile) => profile.name === profileId);
|
|
224
|
+
if (matches.length === 1) {
|
|
225
|
+
return matches[0];
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
if (this.data.currentProfileId && this.data.profiles[this.data.currentProfileId]) {
|
|
229
|
+
return this.data.profiles[this.data.currentProfileId];
|
|
230
|
+
}
|
|
231
|
+
return this.listProfiles()[0] ?? null;
|
|
232
|
+
}
|
|
233
|
+
requireProfile(profileId) {
|
|
234
|
+
let profile = this.getProfile(profileId);
|
|
235
|
+
if (!profile) {
|
|
236
|
+
throw new Error("No Slates profile found for this integration.");
|
|
237
|
+
}
|
|
238
|
+
return profile;
|
|
239
|
+
}
|
|
240
|
+
upsertProfile(d) {
|
|
241
|
+
let existing = d.profileId ? this.data.profiles[d.profileId] : void 0;
|
|
242
|
+
let id = existing?.id ?? d.profileId ?? (0, import_crypto.randomUUID)();
|
|
243
|
+
let createdAt = existing?.createdAt ?? now();
|
|
244
|
+
let profile = {
|
|
245
|
+
id,
|
|
246
|
+
name: d.name,
|
|
247
|
+
target: d.target,
|
|
248
|
+
config: d.config ?? existing?.config ?? null,
|
|
249
|
+
auth: existing?.auth ?? {},
|
|
250
|
+
session: d.session ?? existing?.session ?? null,
|
|
251
|
+
metadata: {
|
|
252
|
+
provider: d.metadata?.provider ?? existing?.metadata?.provider ?? null,
|
|
253
|
+
actions: d.metadata?.actions ?? existing?.metadata?.actions ?? null
|
|
254
|
+
},
|
|
255
|
+
createdAt,
|
|
256
|
+
updatedAt: now()
|
|
257
|
+
};
|
|
258
|
+
this.data.profiles[id] = profile;
|
|
259
|
+
if (!this.data.currentProfileId) {
|
|
260
|
+
this.data.currentProfileId = id;
|
|
261
|
+
}
|
|
262
|
+
return profile;
|
|
263
|
+
}
|
|
264
|
+
upsertOAuthCredential(d) {
|
|
265
|
+
let existing = d.credentialId ? this.data.oauthCredentials[d.credentialId] : void 0;
|
|
266
|
+
let id = existing?.id ?? d.credentialId ?? (0, import_crypto.randomUUID)();
|
|
267
|
+
let credential = {
|
|
268
|
+
id,
|
|
269
|
+
name: d.name,
|
|
270
|
+
authMethodId: d.authMethodId,
|
|
271
|
+
clientId: d.clientId,
|
|
272
|
+
clientSecret: d.clientSecret,
|
|
273
|
+
createdAt: existing?.createdAt ?? now(),
|
|
274
|
+
updatedAt: now()
|
|
275
|
+
};
|
|
276
|
+
this.data.oauthCredentials[id] = credential;
|
|
277
|
+
return credential;
|
|
278
|
+
}
|
|
279
|
+
setCurrentProfile(profileId) {
|
|
280
|
+
if (!this.data.profiles[profileId]) {
|
|
281
|
+
throw new Error(`Unknown profile: ${profileId}`);
|
|
282
|
+
}
|
|
283
|
+
this.data.currentProfileId = profileId;
|
|
284
|
+
}
|
|
285
|
+
removeProfile(profileId) {
|
|
286
|
+
delete this.data.profiles[profileId];
|
|
287
|
+
if (this.data.currentProfileId === profileId) {
|
|
288
|
+
this.data.currentProfileId = this.listProfiles()[0]?.id ?? null;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
setProfileConfig(profileId, config) {
|
|
292
|
+
let profile = this.requireProfile(profileId);
|
|
293
|
+
profile.config = config;
|
|
294
|
+
profile.updatedAt = now();
|
|
295
|
+
return profile;
|
|
296
|
+
}
|
|
297
|
+
setProfileSession(profileId, session) {
|
|
298
|
+
let profile = this.requireProfile(profileId);
|
|
299
|
+
profile.session = session;
|
|
300
|
+
profile.updatedAt = now();
|
|
301
|
+
return profile;
|
|
302
|
+
}
|
|
303
|
+
setProfileMetadata(profileId, metadata) {
|
|
304
|
+
let profile = this.requireProfile(profileId);
|
|
305
|
+
profile.metadata = {
|
|
306
|
+
provider: metadata.provider ?? profile.metadata.provider ?? null,
|
|
307
|
+
actions: metadata.actions ?? profile.metadata.actions ?? null
|
|
308
|
+
};
|
|
309
|
+
profile.updatedAt = now();
|
|
310
|
+
return profile;
|
|
311
|
+
}
|
|
312
|
+
upsertAuth(profileId, auth) {
|
|
313
|
+
let profile = this.requireProfile(profileId);
|
|
314
|
+
let existing = profile.auth[auth.authMethodId];
|
|
315
|
+
profile.auth[auth.authMethodId] = {
|
|
316
|
+
...auth,
|
|
317
|
+
id: auth.id ?? existing?.id ?? (0, import_crypto.randomUUID)(),
|
|
318
|
+
createdAt: existing?.createdAt ?? now(),
|
|
319
|
+
updatedAt: now()
|
|
320
|
+
};
|
|
321
|
+
profile.updatedAt = now();
|
|
322
|
+
return profile.auth[auth.authMethodId];
|
|
323
|
+
}
|
|
324
|
+
getAuth(profileId, authMethodId) {
|
|
325
|
+
let profile = this.requireProfile(profileId);
|
|
326
|
+
if (authMethodId) return profile.auth[authMethodId] ?? null;
|
|
327
|
+
return Object.values(profile.auth)[0] ?? null;
|
|
328
|
+
}
|
|
329
|
+
listAuth(profileId) {
|
|
330
|
+
let profile = this.requireProfile(profileId);
|
|
331
|
+
return Object.values(profile.auth).sort(
|
|
332
|
+
(a, b) => a.authMethodId.localeCompare(b.authMethodId)
|
|
333
|
+
);
|
|
334
|
+
}
|
|
335
|
+
};
|
|
336
|
+
var openSlatesCliStore = async (opts = {}) => SlatesCliStore.open(opts);
|
|
337
|
+
|
|
338
|
+
// src/client.ts
|
|
339
|
+
var resolveEntryPath = (entry, cwd) => {
|
|
340
|
+
if (import_path2.default.isAbsolute(entry)) return entry;
|
|
341
|
+
return import_path2.default.resolve(resolveSlatesCliRoot(cwd), entry);
|
|
342
|
+
};
|
|
343
|
+
var loadSlateFromProfile = async (profile, cwd) => {
|
|
344
|
+
if (profile.target.type !== "local") {
|
|
345
|
+
throw new Error(`Unsupported profile target type: ${profile.target.type}`);
|
|
346
|
+
}
|
|
347
|
+
let modulePath = resolveEntryPath(profile.target.entry, cwd);
|
|
348
|
+
let loaded = await import((0, import_url.pathToFileURL)(modulePath).href);
|
|
349
|
+
let exportName = profile.target.exportName;
|
|
350
|
+
let slate = (exportName ? loaded[exportName] : void 0) ?? loaded.provider ?? loaded.slate ?? loaded.default;
|
|
351
|
+
if (!slate) {
|
|
352
|
+
throw new Error(
|
|
353
|
+
`Could not find a slate export in ${profile.target.entry}. Tried ${exportName ? `\`${exportName}\`, ` : ""}\`provider\`, \`slate\`, and \`default\`.`
|
|
354
|
+
);
|
|
355
|
+
}
|
|
356
|
+
return slate;
|
|
357
|
+
};
|
|
358
|
+
var createSlatesClientFromProfile = async (profile, opts = {}) => {
|
|
359
|
+
let firstAuth = Object.values(profile.auth)[0];
|
|
360
|
+
let slate = await loadSlateFromProfile(profile, opts.cwd);
|
|
361
|
+
let client = (0, import_client.createSlatesClient)({
|
|
362
|
+
transport: (0, import_client.createLocalSlateTransport)({ slate }),
|
|
363
|
+
state: {
|
|
364
|
+
config: profile.config,
|
|
365
|
+
session: profile.session,
|
|
366
|
+
auth: firstAuth ? {
|
|
367
|
+
authenticationMethodId: firstAuth.authMethodId,
|
|
368
|
+
output: firstAuth.output
|
|
369
|
+
} : null
|
|
370
|
+
}
|
|
371
|
+
});
|
|
372
|
+
if (firstAuth) {
|
|
373
|
+
attachAutoRefresh(client, profile, firstAuth, opts.store);
|
|
374
|
+
}
|
|
375
|
+
return client;
|
|
376
|
+
};
|
|
377
|
+
var EXPIRY_BUFFER_MS = 60 * 1e3;
|
|
378
|
+
var shouldRefreshOAuthAuth = (auth) => {
|
|
379
|
+
if (auth.authType !== "auth.oauth") return false;
|
|
380
|
+
if (!auth.clientId || !auth.clientSecret) return false;
|
|
381
|
+
if (typeof auth.output?.refreshToken !== "string" || !auth.output.refreshToken) return false;
|
|
382
|
+
if (typeof auth.output?.expiresAt !== "string" || !auth.output.expiresAt) return false;
|
|
383
|
+
let expiresAt = Date.parse(auth.output.expiresAt);
|
|
384
|
+
return Number.isFinite(expiresAt) && expiresAt <= Date.now() + EXPIRY_BUFFER_MS;
|
|
385
|
+
};
|
|
386
|
+
var attachAutoRefresh = (client, profile, storedAuth, store) => {
|
|
387
|
+
let baseRequest = client.request.bind(client);
|
|
388
|
+
let inflightRefresh = null;
|
|
389
|
+
let refreshIfNeeded = async () => {
|
|
390
|
+
if (inflightRefresh) {
|
|
391
|
+
await inflightRefresh;
|
|
392
|
+
return;
|
|
393
|
+
}
|
|
394
|
+
if (!shouldRefreshOAuthAuth(storedAuth)) {
|
|
395
|
+
return;
|
|
396
|
+
}
|
|
397
|
+
inflightRefresh = (async () => {
|
|
398
|
+
let authMethod = await baseRequest("slates/auth.method.get", {
|
|
399
|
+
authenticationMethodId: storedAuth.authMethodId
|
|
400
|
+
});
|
|
401
|
+
if (!authMethod.authenticationMethod.capabilities.handleTokenRefresh?.enabled) {
|
|
402
|
+
return;
|
|
403
|
+
}
|
|
404
|
+
let refreshed = await baseRequest("slates/auth.token_refresh.handle", {
|
|
405
|
+
authenticationMethodId: storedAuth.authMethodId,
|
|
406
|
+
output: storedAuth.output,
|
|
407
|
+
input: storedAuth.input,
|
|
408
|
+
clientId: storedAuth.clientId ?? "",
|
|
409
|
+
clientSecret: storedAuth.clientSecret ?? "",
|
|
410
|
+
scopes: storedAuth.scopes
|
|
411
|
+
});
|
|
412
|
+
storedAuth.input = refreshed.input ?? storedAuth.input;
|
|
413
|
+
storedAuth.output = refreshed.output;
|
|
414
|
+
storedAuth.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
415
|
+
client.setAuth({
|
|
416
|
+
authenticationMethodId: storedAuth.authMethodId,
|
|
417
|
+
output: storedAuth.output
|
|
418
|
+
});
|
|
419
|
+
if (store) {
|
|
420
|
+
store.upsertAuth(profile.id, storedAuth);
|
|
421
|
+
await store.save();
|
|
422
|
+
}
|
|
423
|
+
})();
|
|
424
|
+
try {
|
|
425
|
+
await inflightRefresh;
|
|
426
|
+
} finally {
|
|
427
|
+
inflightRefresh = null;
|
|
428
|
+
}
|
|
429
|
+
};
|
|
430
|
+
client.request = (async (method, params) => {
|
|
431
|
+
if (method !== "slates/auth.token_refresh.handle") {
|
|
432
|
+
await refreshIfNeeded();
|
|
433
|
+
}
|
|
434
|
+
return baseRequest(method, params);
|
|
435
|
+
});
|
|
436
|
+
};
|
|
437
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
438
|
+
0 && (module.exports = {
|
|
439
|
+
SlatesCliStore,
|
|
440
|
+
createSlatesClientFromProfile,
|
|
441
|
+
openSlatesCliStore,
|
|
442
|
+
resolveSlatesCliDir,
|
|
443
|
+
resolveSlatesCliProfilesDir,
|
|
444
|
+
resolveSlatesCliRoot
|
|
445
|
+
});
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import * as _slates_client from '@slates/client';
|
|
2
|
+
import { SlatesJsonObject } from '@slates/client';
|
|
3
|
+
import { SlateAuthenticationMethod, SlatesAction } from '@slates/proto';
|
|
4
|
+
|
|
5
|
+
interface SlatesStoredAuth {
|
|
6
|
+
id: string;
|
|
7
|
+
authMethodId: string;
|
|
8
|
+
authMethodName?: string;
|
|
9
|
+
authType: SlateAuthenticationMethod['type'];
|
|
10
|
+
input: SlatesJsonObject;
|
|
11
|
+
output: SlatesJsonObject;
|
|
12
|
+
scopes: string[];
|
|
13
|
+
oauthCredentialId?: string;
|
|
14
|
+
clientId?: string;
|
|
15
|
+
clientSecret?: string;
|
|
16
|
+
callbackState?: SlatesJsonObject | null;
|
|
17
|
+
profile?: SlatesJsonObject | null;
|
|
18
|
+
createdAt: string;
|
|
19
|
+
updatedAt: string;
|
|
20
|
+
}
|
|
21
|
+
interface SlatesOAuthCredentialRecord {
|
|
22
|
+
id: string;
|
|
23
|
+
name: string;
|
|
24
|
+
authMethodId: string;
|
|
25
|
+
clientId: string;
|
|
26
|
+
clientSecret: string;
|
|
27
|
+
createdAt: string;
|
|
28
|
+
updatedAt: string;
|
|
29
|
+
}
|
|
30
|
+
interface SlatesLocalProfileTarget {
|
|
31
|
+
type: 'local';
|
|
32
|
+
entry: string;
|
|
33
|
+
exportName?: string;
|
|
34
|
+
}
|
|
35
|
+
type SlatesProfileTarget = SlatesLocalProfileTarget;
|
|
36
|
+
interface SlatesCliStoreScope {
|
|
37
|
+
key: string;
|
|
38
|
+
name?: string;
|
|
39
|
+
}
|
|
40
|
+
interface SlatesProfileRecord {
|
|
41
|
+
id: string;
|
|
42
|
+
name: string;
|
|
43
|
+
target: SlatesProfileTarget;
|
|
44
|
+
config: SlatesJsonObject | null;
|
|
45
|
+
auth: Record<string, SlatesStoredAuth>;
|
|
46
|
+
session: {
|
|
47
|
+
id: string;
|
|
48
|
+
state: SlatesJsonObject;
|
|
49
|
+
} | null;
|
|
50
|
+
metadata: {
|
|
51
|
+
provider?: SlatesJsonObject | null;
|
|
52
|
+
actions?: SlatesAction[] | null;
|
|
53
|
+
};
|
|
54
|
+
createdAt: string;
|
|
55
|
+
updatedAt: string;
|
|
56
|
+
}
|
|
57
|
+
interface SlatesCliStoreData {
|
|
58
|
+
version: 3;
|
|
59
|
+
currentProfileId: string | null;
|
|
60
|
+
profiles: Record<string, SlatesProfileRecord>;
|
|
61
|
+
oauthCredentials: Record<string, SlatesOAuthCredentialRecord>;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
declare let resolveSlatesCliRoot: (cwd?: string) => string;
|
|
65
|
+
declare let resolveSlatesCliDir: (cwd?: string) => string;
|
|
66
|
+
declare let resolveSlatesCliProfilesDir: (cwd?: string) => string;
|
|
67
|
+
declare class SlatesCliStore {
|
|
68
|
+
readonly rootDir: string;
|
|
69
|
+
readonly dirPath: string;
|
|
70
|
+
readonly storePath: string;
|
|
71
|
+
readonly scope: SlatesCliStoreScope | null;
|
|
72
|
+
readonly data: SlatesCliStoreData;
|
|
73
|
+
constructor(rootDir: string, dirPath: string, storePath: string, scope: SlatesCliStoreScope | null, data: SlatesCliStoreData);
|
|
74
|
+
static open(opts?: {
|
|
75
|
+
cwd?: string;
|
|
76
|
+
scope?: SlatesCliStoreScope;
|
|
77
|
+
storePath?: string;
|
|
78
|
+
}): Promise<SlatesCliStore>;
|
|
79
|
+
save(): Promise<void>;
|
|
80
|
+
listProfiles(): SlatesProfileRecord[];
|
|
81
|
+
listOAuthCredentials(authMethodId?: string): SlatesOAuthCredentialRecord[];
|
|
82
|
+
getOAuthCredential(credentialId?: string | null, authMethodId?: string | null): SlatesOAuthCredentialRecord;
|
|
83
|
+
getProfile(profileId?: string | null): SlatesProfileRecord;
|
|
84
|
+
requireProfile(profileId?: string | null): SlatesProfileRecord;
|
|
85
|
+
upsertProfile(d: {
|
|
86
|
+
profileId?: string;
|
|
87
|
+
name: string;
|
|
88
|
+
target: SlatesProfileTarget;
|
|
89
|
+
config?: SlatesProfileRecord['config'];
|
|
90
|
+
session?: SlatesProfileRecord['session'];
|
|
91
|
+
metadata?: SlatesProfileRecord['metadata'];
|
|
92
|
+
}): SlatesProfileRecord;
|
|
93
|
+
upsertOAuthCredential(d: {
|
|
94
|
+
credentialId?: string;
|
|
95
|
+
name: string;
|
|
96
|
+
authMethodId: string;
|
|
97
|
+
clientId: string;
|
|
98
|
+
clientSecret: string;
|
|
99
|
+
}): SlatesOAuthCredentialRecord;
|
|
100
|
+
setCurrentProfile(profileId: string): void;
|
|
101
|
+
removeProfile(profileId: string): void;
|
|
102
|
+
setProfileConfig(profileId: string, config: SlatesProfileRecord['config']): SlatesProfileRecord;
|
|
103
|
+
setProfileSession(profileId: string, session: SlatesProfileRecord['session']): SlatesProfileRecord;
|
|
104
|
+
setProfileMetadata(profileId: string, metadata: Partial<SlatesProfileRecord['metadata']>): SlatesProfileRecord;
|
|
105
|
+
upsertAuth(profileId: string, auth: Omit<SlatesStoredAuth, 'id' | 'createdAt' | 'updatedAt'> & {
|
|
106
|
+
id?: string;
|
|
107
|
+
}): SlatesStoredAuth;
|
|
108
|
+
getAuth(profileId: string, authMethodId?: string | null): SlatesStoredAuth;
|
|
109
|
+
listAuth(profileId: string): SlatesStoredAuth[];
|
|
110
|
+
}
|
|
111
|
+
declare let openSlatesCliStore: (opts?: {
|
|
112
|
+
cwd?: string;
|
|
113
|
+
scope?: SlatesCliStoreScope;
|
|
114
|
+
storePath?: string;
|
|
115
|
+
}) => Promise<SlatesCliStore>;
|
|
116
|
+
|
|
117
|
+
declare let createSlatesClientFromProfile: (profile: SlatesProfileRecord, opts?: {
|
|
118
|
+
cwd?: string;
|
|
119
|
+
store?: SlatesCliStore;
|
|
120
|
+
}) => Promise<_slates_client.SlatesProtocolClient>;
|
|
121
|
+
|
|
122
|
+
export { SlatesCliStore, type SlatesCliStoreData, type SlatesCliStoreScope, type SlatesLocalProfileTarget, type SlatesOAuthCredentialRecord, type SlatesProfileRecord, type SlatesProfileTarget, type SlatesStoredAuth, createSlatesClientFromProfile, openSlatesCliStore, resolveSlatesCliDir, resolveSlatesCliProfilesDir, resolveSlatesCliRoot };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import * as _slates_client from '@slates/client';
|
|
2
|
+
import { SlatesJsonObject } from '@slates/client';
|
|
3
|
+
import { SlateAuthenticationMethod, SlatesAction } from '@slates/proto';
|
|
4
|
+
|
|
5
|
+
interface SlatesStoredAuth {
|
|
6
|
+
id: string;
|
|
7
|
+
authMethodId: string;
|
|
8
|
+
authMethodName?: string;
|
|
9
|
+
authType: SlateAuthenticationMethod['type'];
|
|
10
|
+
input: SlatesJsonObject;
|
|
11
|
+
output: SlatesJsonObject;
|
|
12
|
+
scopes: string[];
|
|
13
|
+
oauthCredentialId?: string;
|
|
14
|
+
clientId?: string;
|
|
15
|
+
clientSecret?: string;
|
|
16
|
+
callbackState?: SlatesJsonObject | null;
|
|
17
|
+
profile?: SlatesJsonObject | null;
|
|
18
|
+
createdAt: string;
|
|
19
|
+
updatedAt: string;
|
|
20
|
+
}
|
|
21
|
+
interface SlatesOAuthCredentialRecord {
|
|
22
|
+
id: string;
|
|
23
|
+
name: string;
|
|
24
|
+
authMethodId: string;
|
|
25
|
+
clientId: string;
|
|
26
|
+
clientSecret: string;
|
|
27
|
+
createdAt: string;
|
|
28
|
+
updatedAt: string;
|
|
29
|
+
}
|
|
30
|
+
interface SlatesLocalProfileTarget {
|
|
31
|
+
type: 'local';
|
|
32
|
+
entry: string;
|
|
33
|
+
exportName?: string;
|
|
34
|
+
}
|
|
35
|
+
type SlatesProfileTarget = SlatesLocalProfileTarget;
|
|
36
|
+
interface SlatesCliStoreScope {
|
|
37
|
+
key: string;
|
|
38
|
+
name?: string;
|
|
39
|
+
}
|
|
40
|
+
interface SlatesProfileRecord {
|
|
41
|
+
id: string;
|
|
42
|
+
name: string;
|
|
43
|
+
target: SlatesProfileTarget;
|
|
44
|
+
config: SlatesJsonObject | null;
|
|
45
|
+
auth: Record<string, SlatesStoredAuth>;
|
|
46
|
+
session: {
|
|
47
|
+
id: string;
|
|
48
|
+
state: SlatesJsonObject;
|
|
49
|
+
} | null;
|
|
50
|
+
metadata: {
|
|
51
|
+
provider?: SlatesJsonObject | null;
|
|
52
|
+
actions?: SlatesAction[] | null;
|
|
53
|
+
};
|
|
54
|
+
createdAt: string;
|
|
55
|
+
updatedAt: string;
|
|
56
|
+
}
|
|
57
|
+
interface SlatesCliStoreData {
|
|
58
|
+
version: 3;
|
|
59
|
+
currentProfileId: string | null;
|
|
60
|
+
profiles: Record<string, SlatesProfileRecord>;
|
|
61
|
+
oauthCredentials: Record<string, SlatesOAuthCredentialRecord>;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
declare let resolveSlatesCliRoot: (cwd?: string) => string;
|
|
65
|
+
declare let resolveSlatesCliDir: (cwd?: string) => string;
|
|
66
|
+
declare let resolveSlatesCliProfilesDir: (cwd?: string) => string;
|
|
67
|
+
declare class SlatesCliStore {
|
|
68
|
+
readonly rootDir: string;
|
|
69
|
+
readonly dirPath: string;
|
|
70
|
+
readonly storePath: string;
|
|
71
|
+
readonly scope: SlatesCliStoreScope | null;
|
|
72
|
+
readonly data: SlatesCliStoreData;
|
|
73
|
+
constructor(rootDir: string, dirPath: string, storePath: string, scope: SlatesCliStoreScope | null, data: SlatesCliStoreData);
|
|
74
|
+
static open(opts?: {
|
|
75
|
+
cwd?: string;
|
|
76
|
+
scope?: SlatesCliStoreScope;
|
|
77
|
+
storePath?: string;
|
|
78
|
+
}): Promise<SlatesCliStore>;
|
|
79
|
+
save(): Promise<void>;
|
|
80
|
+
listProfiles(): SlatesProfileRecord[];
|
|
81
|
+
listOAuthCredentials(authMethodId?: string): SlatesOAuthCredentialRecord[];
|
|
82
|
+
getOAuthCredential(credentialId?: string | null, authMethodId?: string | null): SlatesOAuthCredentialRecord;
|
|
83
|
+
getProfile(profileId?: string | null): SlatesProfileRecord;
|
|
84
|
+
requireProfile(profileId?: string | null): SlatesProfileRecord;
|
|
85
|
+
upsertProfile(d: {
|
|
86
|
+
profileId?: string;
|
|
87
|
+
name: string;
|
|
88
|
+
target: SlatesProfileTarget;
|
|
89
|
+
config?: SlatesProfileRecord['config'];
|
|
90
|
+
session?: SlatesProfileRecord['session'];
|
|
91
|
+
metadata?: SlatesProfileRecord['metadata'];
|
|
92
|
+
}): SlatesProfileRecord;
|
|
93
|
+
upsertOAuthCredential(d: {
|
|
94
|
+
credentialId?: string;
|
|
95
|
+
name: string;
|
|
96
|
+
authMethodId: string;
|
|
97
|
+
clientId: string;
|
|
98
|
+
clientSecret: string;
|
|
99
|
+
}): SlatesOAuthCredentialRecord;
|
|
100
|
+
setCurrentProfile(profileId: string): void;
|
|
101
|
+
removeProfile(profileId: string): void;
|
|
102
|
+
setProfileConfig(profileId: string, config: SlatesProfileRecord['config']): SlatesProfileRecord;
|
|
103
|
+
setProfileSession(profileId: string, session: SlatesProfileRecord['session']): SlatesProfileRecord;
|
|
104
|
+
setProfileMetadata(profileId: string, metadata: Partial<SlatesProfileRecord['metadata']>): SlatesProfileRecord;
|
|
105
|
+
upsertAuth(profileId: string, auth: Omit<SlatesStoredAuth, 'id' | 'createdAt' | 'updatedAt'> & {
|
|
106
|
+
id?: string;
|
|
107
|
+
}): SlatesStoredAuth;
|
|
108
|
+
getAuth(profileId: string, authMethodId?: string | null): SlatesStoredAuth;
|
|
109
|
+
listAuth(profileId: string): SlatesStoredAuth[];
|
|
110
|
+
}
|
|
111
|
+
declare let openSlatesCliStore: (opts?: {
|
|
112
|
+
cwd?: string;
|
|
113
|
+
scope?: SlatesCliStoreScope;
|
|
114
|
+
storePath?: string;
|
|
115
|
+
}) => Promise<SlatesCliStore>;
|
|
116
|
+
|
|
117
|
+
declare let createSlatesClientFromProfile: (profile: SlatesProfileRecord, opts?: {
|
|
118
|
+
cwd?: string;
|
|
119
|
+
store?: SlatesCliStore;
|
|
120
|
+
}) => Promise<_slates_client.SlatesProtocolClient>;
|
|
121
|
+
|
|
122
|
+
export { SlatesCliStore, type SlatesCliStoreData, type SlatesCliStoreScope, type SlatesLocalProfileTarget, type SlatesOAuthCredentialRecord, type SlatesProfileRecord, type SlatesProfileTarget, type SlatesStoredAuth, createSlatesClientFromProfile, openSlatesCliStore, resolveSlatesCliDir, resolveSlatesCliProfilesDir, resolveSlatesCliRoot };
|