@xanots/sdk 0.0.1

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.
Files changed (106) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +384 -0
  3. package/dist/agent-file-refresh-7XCACU34.js +95 -0
  4. package/dist/bin.d.ts +1 -0
  5. package/dist/bin.js +184 -0
  6. package/dist/capture-HUV5BNTC.js +32 -0
  7. package/dist/chunk-26CNBZE2.js +963 -0
  8. package/dist/chunk-33ND6LKO.js +78 -0
  9. package/dist/chunk-3DUAGYGP.js +1550 -0
  10. package/dist/chunk-3IGNIP6R.js +89 -0
  11. package/dist/chunk-47WDWMBJ.js +14 -0
  12. package/dist/chunk-4BXJGVZ3.js +318 -0
  13. package/dist/chunk-4HT3BNZ7.js +675 -0
  14. package/dist/chunk-4YMD2OOZ.js +23 -0
  15. package/dist/chunk-5WGEURVI.js +156 -0
  16. package/dist/chunk-5YTBTF25.js +29 -0
  17. package/dist/chunk-6DHBYBTO.js +166 -0
  18. package/dist/chunk-76QBEIGO.js +66 -0
  19. package/dist/chunk-7DKX2SPN.js +100 -0
  20. package/dist/chunk-7REDODS2.js +468 -0
  21. package/dist/chunk-C56BC2FY.js +254 -0
  22. package/dist/chunk-DGSF2Q5H.js +60 -0
  23. package/dist/chunk-EMCAWMHC.js +3982 -0
  24. package/dist/chunk-EZG76F7R.js +159 -0
  25. package/dist/chunk-FJ6ZS5KB.js +3607 -0
  26. package/dist/chunk-GNPVYOPB.js +17 -0
  27. package/dist/chunk-HJPTWBLH.js +38 -0
  28. package/dist/chunk-IZW6MK3U.js +248 -0
  29. package/dist/chunk-LH6Z6KFV.js +247 -0
  30. package/dist/chunk-MZUI3JNX.js +93 -0
  31. package/dist/chunk-NDZFBZHC.js +167 -0
  32. package/dist/chunk-NOO35BQ2.js +37 -0
  33. package/dist/chunk-NUQCEOKA.js +13 -0
  34. package/dist/chunk-QTNO2WD6.js +56 -0
  35. package/dist/chunk-RVB7ITKN.js +49 -0
  36. package/dist/chunk-TRU5OHQ5.js +6904 -0
  37. package/dist/chunk-VKFQJEMW.js +814 -0
  38. package/dist/chunk-VTIL47DT.js +125 -0
  39. package/dist/chunk-WHOJWOSV.js +112 -0
  40. package/dist/chunk-WKP4D5MO.js +1692 -0
  41. package/dist/chunk-X4DVXBFY.js +38 -0
  42. package/dist/chunk-XQ22GLYS.js +118 -0
  43. package/dist/chunk-YDZYMZBE.js +670 -0
  44. package/dist/chunk-YGPIY3WT.js +1146 -0
  45. package/dist/chunk-YYRDLFSJ.js +602 -0
  46. package/dist/chunk-ZUTSMMAG.js +46 -0
  47. package/dist/cli.d.ts +331 -0
  48. package/dist/cli.js +33 -0
  49. package/dist/codegen-command-OOKK6AZK.js +40 -0
  50. package/dist/codegen.d.ts +114 -0
  51. package/dist/codegen.js +71 -0
  52. package/dist/completion-TIPPZN7H.js +298 -0
  53. package/dist/config-NL33PN4D.js +84 -0
  54. package/dist/deploy-command-4EQ7XX5G.js +451 -0
  55. package/dist/env-target-IFJ5QDHC.js +16 -0
  56. package/dist/ephemeral-command-3X3I4ULC.js +242 -0
  57. package/dist/index.d.ts +4477 -0
  58. package/dist/index.js +300 -0
  59. package/dist/init-command-R6H7ZXW5.js +27 -0
  60. package/dist/internal.d.ts +74 -0
  61. package/dist/internal.js +2065 -0
  62. package/dist/io-AMIKRLPC.js +11 -0
  63. package/dist/live-diff-Y3AKETHE.js +196 -0
  64. package/dist/lock-3CVKALKT.js +37 -0
  65. package/dist/lock-commands-XTR2YKLY.js +232 -0
  66. package/dist/login-command-ACJF6KWQ.js +167 -0
  67. package/dist/logout-command-MX3MJS5U.js +68 -0
  68. package/dist/loop-OM3P2Z6O.js +93 -0
  69. package/dist/marketplace-command-RATXTKXN.js +379 -0
  70. package/dist/meta-client-OW5WKWW7.js +170 -0
  71. package/dist/node.d.ts +59 -0
  72. package/dist/node.js +442 -0
  73. package/dist/profile-command-SWJ3SPKR.js +77 -0
  74. package/dist/release-command-VV5UVZKL.js +427 -0
  75. package/dist/response-CVAE2kMj.d.ts +1915 -0
  76. package/dist/routes-manifest-SP3ZXLMR.js +244 -0
  77. package/dist/runtime-V4C3AC3A.js +13 -0
  78. package/dist/sandbox-details-command-HJE5SPVG.js +18 -0
  79. package/dist/sandbox-export-command-QCJY4GMV.js +24 -0
  80. package/dist/static-host-D6KS7X45.js +138 -0
  81. package/dist/store-BQ97nKIF.d.ts +7760 -0
  82. package/dist/test-command-TSPBQHBM.js +383 -0
  83. package/dist/validate-command-4ERHJSCO.js +122 -0
  84. package/dist/verify-rollout-FAVQ6EJY.js +40 -0
  85. package/dist/workspace-K72NP7SX.js +49 -0
  86. package/dist/workspace-command-OF23DPNI.js +156 -0
  87. package/dist/workspace-export-AJMGN3CQ.js +10 -0
  88. package/llms/fields.md +104 -0
  89. package/llms/filters.md +183 -0
  90. package/llms/kinds-agent-mcp.md +11 -0
  91. package/llms/kinds-core.md +68 -0
  92. package/llms/kinds-realtime.md +76 -0
  93. package/llms/lambda.md +111 -0
  94. package/llms/legacy.md +43 -0
  95. package/llms/object-kinds.md +31 -0
  96. package/llms/statements-calls.md +23 -0
  97. package/llms/statements-catalog.md +309 -0
  98. package/llms/statements-data.md +58 -0
  99. package/llms/statements-runtime.md +48 -0
  100. package/llms/tests.md +58 -0
  101. package/llms/triggers.md +22 -0
  102. package/llms/values.md +29 -0
  103. package/llms-full.txt +1672 -0
  104. package/llms.txt +483 -0
  105. package/manifest.json +9592 -0
  106. package/package.json +110 -0
@@ -0,0 +1,468 @@
1
+ import {
2
+ atomicWrite
3
+ } from "./chunk-GNPVYOPB.js";
4
+
5
+ // src/auth/oauth.ts
6
+ import * as client from "openid-client";
7
+
8
+ // src/auth/client-store.ts
9
+ import { existsSync, readFileSync, mkdirSync } from "fs";
10
+ import { homedir } from "os";
11
+ import { dirname, join } from "path";
12
+ function clientStorePath() {
13
+ return process.env.XANO_CLIENT_FILE ?? join(homedir(), ".xano", "xanots-clients.json");
14
+ }
15
+ function key(authHost, redirectUri) {
16
+ return `${authHost}|${redirectUri}`;
17
+ }
18
+ function readAll(path) {
19
+ if (!existsSync(path)) return {};
20
+ try {
21
+ const parsed = JSON.parse(readFileSync(path, "utf8"));
22
+ return typeof parsed === "object" && parsed !== null ? parsed : {};
23
+ } catch {
24
+ return {};
25
+ }
26
+ }
27
+ function writeAll(path, all) {
28
+ mkdirSync(dirname(path), { recursive: true });
29
+ atomicWrite(path, JSON.stringify(all, null, 2) + "\n", { mode: 384 });
30
+ }
31
+ async function getOrRegisterClient(params) {
32
+ const path = clientStorePath();
33
+ const all = readAll(path);
34
+ const k = key(params.authHost, params.redirectUri);
35
+ const cached = all[k];
36
+ if (cached?.client_id) return cached.client_id;
37
+ const { client_id } = await registerClient({
38
+ registrationEndpoint: params.registrationEndpoint,
39
+ redirectUri: params.redirectUri,
40
+ scope: params.scope
41
+ });
42
+ all[k] = { client_id };
43
+ writeAll(path, all);
44
+ return client_id;
45
+ }
46
+ function clearClient(params) {
47
+ const path = clientStorePath();
48
+ const all = readAll(path);
49
+ const k = key(params.authHost, params.redirectUri);
50
+ if (!(k in all)) return;
51
+ delete all[k];
52
+ writeAll(path, all);
53
+ }
54
+
55
+ // src/auth/oauth.ts
56
+ var CALLBACK_PATH = "/oauth/callback";
57
+ var DEFAULT_PORT = 47100;
58
+ var SOFTWARE_ID = "xanots";
59
+ var DEFAULT_AUTH_HOST = "https://app.xano.com";
60
+ var DEFAULT_SCOPE = "offline_access workspace:read workspace:write xano:dev";
61
+ var DISCOVERY_PATH = "/.well-known/oauth-authorization-server";
62
+ var NETWORK_TIMEOUT_MS = 3e4;
63
+ async function discover(authHost) {
64
+ const url = new URL(DISCOVERY_PATH, authHost).href;
65
+ const res = await fetch(url, { signal: AbortSignal.timeout(NETWORK_TIMEOUT_MS) });
66
+ if (!res.ok) {
67
+ throw new Error(
68
+ `OAuth discovery failed (${res.status} ${res.statusText}) at ${url}. Check --origin (currently ${authHost}).`
69
+ );
70
+ }
71
+ const doc = await res.json();
72
+ if (!doc.authorization_endpoint || !doc.token_endpoint) {
73
+ throw new Error(`OAuth discovery doc at ${url} is missing authorization/token endpoints.`);
74
+ }
75
+ return {
76
+ authorization_endpoint: doc.authorization_endpoint,
77
+ token_endpoint: doc.token_endpoint,
78
+ registration_endpoint: doc.registration_endpoint
79
+ };
80
+ }
81
+ async function registerClient(params) {
82
+ const res = await fetch(params.registrationEndpoint, {
83
+ method: "POST",
84
+ headers: { "Content-Type": "application/json" },
85
+ body: JSON.stringify({
86
+ client_name: "xanots CLI",
87
+ software_id: SOFTWARE_ID,
88
+ redirect_uris: [params.redirectUri],
89
+ grant_types: ["authorization_code", "refresh_token"],
90
+ response_types: ["code"],
91
+ token_endpoint_auth_method: "none",
92
+ scopes: params.scope.split(/\s+/).filter(Boolean)
93
+ }),
94
+ signal: AbortSignal.timeout(NETWORK_TIMEOUT_MS)
95
+ });
96
+ const text = await res.text();
97
+ if (res.status !== 200 && res.status !== 201) {
98
+ throw new Error(`Client registration failed (${res.status} ${res.statusText}):
99
+ ${text}`);
100
+ }
101
+ const doc = JSON.parse(text);
102
+ if (!doc.client_id) {
103
+ throw new Error(`Client registration response had no client_id:
104
+ ${text}`);
105
+ }
106
+ return { client_id: doc.client_id };
107
+ }
108
+ function decodeAudience(accessToken) {
109
+ const parts = accessToken.split(".");
110
+ if (parts.length < 2) return void 0;
111
+ try {
112
+ const payload = JSON.parse(Buffer.from(parts[1], "base64url").toString("utf8"));
113
+ return Array.isArray(payload.aud) ? payload.aud[0] : payload.aud;
114
+ } catch {
115
+ return void 0;
116
+ }
117
+ }
118
+ function oauthErrorCode(err) {
119
+ if (err && typeof err === "object" && "error" in err) {
120
+ const code = err.error;
121
+ if (typeof code === "string") return code;
122
+ }
123
+ return void 0;
124
+ }
125
+ var OpenIdProvider = class {
126
+ constructor(opts) {
127
+ this.opts = opts;
128
+ }
129
+ opts;
130
+ configPromise;
131
+ /** The client_id the resolved config uses — set once `build()` completes. */
132
+ resolvedClientId;
133
+ redirectUri() {
134
+ if (!this.opts.redirectUri) {
135
+ throw new Error("OpenIdProvider: redirectUri is required for the authorize/exchange flow.");
136
+ }
137
+ return this.opts.redirectUri;
138
+ }
139
+ /**
140
+ * The client_id this provider registered or reused. Only valid after the
141
+ * config has resolved (e.g. after `buildAuthUrl`/`exchange`); throws otherwise
142
+ * so a caller never records an empty client_id.
143
+ */
144
+ clientId() {
145
+ if (!this.resolvedClientId) {
146
+ throw new Error("OpenIdProvider.clientId() called before the configuration was resolved.");
147
+ }
148
+ return this.resolvedClientId;
149
+ }
150
+ async build() {
151
+ const server = new URL(this.opts.authHost);
152
+ const options = server.protocol === "http:" ? { execute: [client.allowInsecureRequests] } : void 0;
153
+ let clientId = this.opts.clientId;
154
+ if (!clientId) {
155
+ const { registration_endpoint } = await discover(this.opts.authHost);
156
+ if (!registration_endpoint) {
157
+ throw new Error(
158
+ `The OAuth server at ${this.opts.authHost} does not advertise a registration endpoint, so xanots can't register its loopback client. Check --origin.`
159
+ );
160
+ }
161
+ clientId = await getOrRegisterClient({
162
+ authHost: this.opts.authHost,
163
+ redirectUri: this.redirectUri(),
164
+ registrationEndpoint: registration_endpoint,
165
+ scope: this.opts.scope
166
+ });
167
+ }
168
+ this.resolvedClientId = clientId;
169
+ return client.discovery(
170
+ server,
171
+ clientId,
172
+ { token_endpoint_auth_method: "none" },
173
+ client.None(),
174
+ options
175
+ );
176
+ }
177
+ config() {
178
+ return this.configPromise ??= this.build();
179
+ }
180
+ async reset() {
181
+ this.configPromise = void 0;
182
+ this.resolvedClientId = void 0;
183
+ if (this.opts.redirectUri) {
184
+ clearClient({ authHost: this.opts.authHost, redirectUri: this.opts.redirectUri });
185
+ }
186
+ }
187
+ async buildAuthUrl({ verifier, state }) {
188
+ const config = await this.config();
189
+ const code_challenge = await client.calculatePKCECodeChallenge(verifier);
190
+ return client.buildAuthorizationUrl(config, {
191
+ redirect_uri: this.redirectUri(),
192
+ scope: this.opts.scope,
193
+ code_challenge,
194
+ code_challenge_method: "S256",
195
+ state
196
+ }).href;
197
+ }
198
+ async exchange(callbackUrl, { verifier, state }) {
199
+ const config = await this.config();
200
+ const tokens = await client.authorizationCodeGrant(config, new URL(callbackUrl), {
201
+ // We don't request `openid`, so no ID Token is expected.
202
+ pkceCodeVerifier: verifier,
203
+ expectedState: state,
204
+ idTokenExpected: false
205
+ });
206
+ return pick(tokens);
207
+ }
208
+ async refresh(refreshToken, opts) {
209
+ const config = await this.config();
210
+ const params = {};
211
+ if (opts?.scope) params.scope = opts.scope;
212
+ return pick(await client.refreshTokenGrant(config, refreshToken, params));
213
+ }
214
+ async revoke(refreshToken) {
215
+ const config = await this.config();
216
+ await client.tokenRevocation(config, refreshToken, { token_type_hint: "refresh_token" });
217
+ }
218
+ };
219
+ function pick(t) {
220
+ return {
221
+ access_token: t.access_token,
222
+ refresh_token: t.refresh_token,
223
+ expires_in: t.expires_in,
224
+ scope: t.scope
225
+ };
226
+ }
227
+
228
+ // src/auth/store.ts
229
+ import { readFileSync as readFileSync2, writeFileSync, existsSync as existsSync2, mkdirSync as mkdirSync2, rmSync } from "fs";
230
+ import { homedir as homedir2 } from "os";
231
+ import { dirname as dirname2, join as join2, relative, resolve } from "path";
232
+ var DEFAULT_AUTH_FILE = join2(".xano", "auth.json");
233
+ function globalAuthFilePath() {
234
+ return process.env.XANO_GLOBAL_CONFIG ?? join2(homedir2(), ".xanots", "auth.json");
235
+ }
236
+ function localAuthFilePath() {
237
+ return resolve(DEFAULT_AUTH_FILE);
238
+ }
239
+ function resolveAuthFilePath(args, mode = "read") {
240
+ const explicit = args.authFile ?? process.env.XANO_CONFIG;
241
+ if (explicit !== void 0) return resolve(explicit);
242
+ const local = localAuthFilePath();
243
+ if (args.local) return local;
244
+ const global = globalAuthFilePath();
245
+ if (mode === "write") return global;
246
+ if (existsSync2(local)) return local;
247
+ return global;
248
+ }
249
+ function readCredential(path) {
250
+ if (!existsSync2(path)) return null;
251
+ const text = readFileSync2(path, "utf8");
252
+ let parsed;
253
+ try {
254
+ parsed = JSON.parse(text);
255
+ } catch {
256
+ throw new Error(
257
+ `Credential file at ${path} is corrupt (invalid JSON). Delete it and run \`xanots login\` again.`
258
+ );
259
+ }
260
+ return parseCredential(parsed, path);
261
+ }
262
+ function isCredentialRecord(v) {
263
+ if (typeof v !== "object" || v === null) return false;
264
+ const record = v;
265
+ if (record.type === "oauth" || record.type === "token") return true;
266
+ return typeof record.access_token === "string" && typeof record.instance === "string";
267
+ }
268
+ function parseCredential(v, path) {
269
+ if (typeof v !== "object" || v === null || Array.isArray(v)) {
270
+ throw new Error(`Credential file at ${path} is not a JSON object. ${REAUTH_HINT}`);
271
+ }
272
+ const record = v;
273
+ const type = record.type;
274
+ if (type === void 0) {
275
+ throw new Error(
276
+ `Credential file at ${path} has no \`type\` field \u2014 it predates the typed credential format. Run \`xanots login\` again to replace it.`
277
+ );
278
+ }
279
+ if (type === "oauth") return parseOAuth(record, path);
280
+ if (type === "token") return parseToken(record, path);
281
+ throw new Error(
282
+ `Credential file at ${path} has an unrecognized \`type\` (${JSON.stringify(type)}). Expected "oauth" or "token".`
283
+ );
284
+ }
285
+ var REAUTH_HINT = "Delete it and run `xanots login` again.";
286
+ function parseOAuth(record, path) {
287
+ const at = `in the "oauth" credential at ${path}`;
288
+ if (typeof record.access_token !== "string" || record.access_token === "") {
289
+ throw new Error(`Missing \`access_token\` ${at}. ${REAUTH_HINT}`);
290
+ }
291
+ if (typeof record.instance !== "string" || record.instance === "") {
292
+ throw new Error(`Missing \`instance\` ${at}. ${REAUTH_HINT}`);
293
+ }
294
+ if (record.workspace_id === void 0) {
295
+ throw new Error(
296
+ `Missing \`workspace_id\` ${at} \u2014 it predates workspace pinning at login. ${REAUTH_HINT}`
297
+ );
298
+ }
299
+ if (typeof record.auth_host !== "string" || record.auth_host === "") {
300
+ throw new Error(`Missing \`auth_host\` ${at}. ${REAUTH_HINT}`);
301
+ }
302
+ if (typeof record.client_id !== "string" || record.client_id === "") {
303
+ throw new Error(`Missing \`client_id\` ${at}. ${REAUTH_HINT}`);
304
+ }
305
+ return {
306
+ type: "oauth",
307
+ access_token: record.access_token,
308
+ refresh_token: typeof record.refresh_token === "string" ? record.refresh_token : void 0,
309
+ // A missing expiry reads as "already expired", which triggers a refresh
310
+ // rather than handing out a token we cannot vouch for.
311
+ expires_at: typeof record.expires_at === "number" ? record.expires_at : 0,
312
+ scope: typeof record.scope === "string" ? record.scope : void 0,
313
+ instance: record.instance,
314
+ workspace_id: requireWorkspaceId(record.workspace_id, at),
315
+ auth_host: record.auth_host,
316
+ client_id: record.client_id
317
+ };
318
+ }
319
+ function parseToken(record, path) {
320
+ return buildTokenCredential(
321
+ {
322
+ instance: record.instance_base_url,
323
+ workspaceId: record.workspace_id,
324
+ token: record.meta_api_token
325
+ },
326
+ {
327
+ at: `in the "token" credential at ${path}`,
328
+ labels: {
329
+ instance: "instance_base_url",
330
+ workspace: "workspace_id",
331
+ token: "meta_api_token"
332
+ }
333
+ }
334
+ );
335
+ }
336
+ function buildTokenCredential(values, source) {
337
+ const { at, labels } = source;
338
+ const raw = values.instance;
339
+ if (typeof raw !== "string" || raw.trim() === "") {
340
+ throw new Error(
341
+ `Missing \`${labels.instance}\` ${at}. It must be the instance URL, e.g. "https://your-instance.xano.io".`
342
+ );
343
+ }
344
+ let origin;
345
+ try {
346
+ origin = new URL(raw.trim()).origin;
347
+ } catch {
348
+ throw new Error(
349
+ `\`${labels.instance}\` ${at} is not a valid URL ("${raw}"), e.g. "https://your-instance.xano.io".`
350
+ );
351
+ }
352
+ const token = values.token;
353
+ if (typeof token !== "string" || token.trim() === "") {
354
+ throw new Error(`Missing \`${labels.token}\` ${at}. It must be a meta API bearer token.`);
355
+ }
356
+ if (values.workspaceId === void 0) {
357
+ throw new Error(`Missing \`${labels.workspace}\` ${at}. It must be the numeric workspace id.`);
358
+ }
359
+ return {
360
+ type: "token",
361
+ instance_base_url: origin,
362
+ workspace_id: requireWorkspaceId(values.workspaceId, at, labels.workspace),
363
+ // A pasted token routinely carries stray whitespace or a newline.
364
+ meta_api_token: token.trim()
365
+ };
366
+ }
367
+ function requireWorkspaceId(value, at, label = "workspace_id") {
368
+ if (typeof value !== "number" || !Number.isInteger(value) || value < 1) {
369
+ throw new Error(`\`${label}\` ${at} must be a positive integer (got ${JSON.stringify(value)}).`);
370
+ }
371
+ return value;
372
+ }
373
+ function writeCredential(path, credential) {
374
+ assertOursIfPresent(path, "overwrite");
375
+ mkdirSync2(dirname2(path), { recursive: true });
376
+ atomicWrite(path, JSON.stringify(credential, null, 2) + "\n", { mode: 384 });
377
+ }
378
+ function assertOursIfPresent(path, verb) {
379
+ if (!existsSync2(path)) return;
380
+ let existing;
381
+ try {
382
+ existing = JSON.parse(readFileSync2(path, "utf8"));
383
+ } catch {
384
+ existing = void 0;
385
+ }
386
+ if (!isCredentialRecord(existing)) {
387
+ throw new Error(
388
+ `Refusing to ${verb} ${path}: it exists but is not a XanoTS credential file. Choose a different --config/$XANO_CONFIG path.`
389
+ );
390
+ }
391
+ }
392
+ function clearCredential(path) {
393
+ if (!existsSync2(path)) return false;
394
+ assertOursIfPresent(path, "delete");
395
+ rmSync(path);
396
+ return true;
397
+ }
398
+ function findGitRoot(startDir) {
399
+ let dir = resolve(startDir);
400
+ for (; ; ) {
401
+ if (existsSync2(join2(dir, ".git"))) return dir;
402
+ const parent = dirname2(dir);
403
+ if (parent === dir) return void 0;
404
+ dir = parent;
405
+ }
406
+ }
407
+ function ensureGitignored(authFilePath) {
408
+ const abs = resolve(authFilePath);
409
+ const root = findGitRoot(dirname2(abs)) ?? process.cwd();
410
+ const rel = relative(root, abs);
411
+ if (rel.startsWith("..")) return false;
412
+ const containingDir = dirname2(abs);
413
+ const entry = containingDir === root ? relForwardSlash(root, abs) : relForwardSlash(root, containingDir) + "/";
414
+ const gitignorePath = join2(root, ".gitignore");
415
+ const existing = existsSync2(gitignorePath) ? readFileSync2(gitignorePath, "utf8") : "";
416
+ if (ignoreCovers(existing, entry)) return false;
417
+ const prefix = existing.length === 0 || existing.endsWith("\n") ? existing : existing + "\n";
418
+ writeFileSync(gitignorePath, `${prefix}${entry}
419
+ `, "utf8");
420
+ return true;
421
+ }
422
+ function relForwardSlash(root, target) {
423
+ return relative(root, target).split(/[\\/]/).join("/");
424
+ }
425
+ function ignoreCovers(gitignore, entry) {
426
+ const want = entry.replace(/\/$/, "");
427
+ return gitignore.split(/\r?\n/).map((line) => line.trim().replace(/\/$/, "")).some((line) => line.length > 0 && !line.startsWith("#") && line === want);
428
+ }
429
+
430
+ // src/auth/config.ts
431
+ function resolveAuthHost(args, saved) {
432
+ return args.authHost ?? process.env.XANO_ORIGIN ?? saved ?? DEFAULT_AUTH_HOST;
433
+ }
434
+ function resolveScope(args) {
435
+ return args.scope ?? DEFAULT_SCOPE;
436
+ }
437
+ function assertHttpsOrigin(origin, label) {
438
+ let url;
439
+ try {
440
+ url = new URL(origin);
441
+ } catch {
442
+ throw new Error(`${label} is not a valid URL: "${origin}" (expected e.g. https://your-instance.xano.io).`);
443
+ }
444
+ const isLoopback = url.hostname === "localhost" || url.hostname === "127.0.0.1" || url.hostname === "::1";
445
+ if (url.protocol !== "https:" && !(url.protocol === "http:" && isLoopback)) {
446
+ throw new Error(`${label} must use https:// (got "${origin}"). Plain http is allowed only for localhost.`);
447
+ }
448
+ }
449
+
450
+ export {
451
+ CALLBACK_PATH,
452
+ DEFAULT_PORT,
453
+ decodeAudience,
454
+ oauthErrorCode,
455
+ OpenIdProvider,
456
+ globalAuthFilePath,
457
+ localAuthFilePath,
458
+ resolveAuthFilePath,
459
+ readCredential,
460
+ buildTokenCredential,
461
+ writeCredential,
462
+ clearCredential,
463
+ ensureGitignored,
464
+ resolveAuthHost,
465
+ resolveScope,
466
+ assertHttpsOrigin
467
+ };
468
+ //# sourceMappingURL=chunk-7REDODS2.js.map