instant-cli 0.22.120 → 0.22.121-experimental.drewh-clief.21610676979.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.
- package/.turbo/turbo-build.log +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/new/commands/init.d.ts +9 -0
- package/dist/new/commands/init.d.ts.map +1 -0
- package/dist/new/commands/init.js +9 -0
- package/dist/new/commands/init.js.map +1 -0
- package/dist/new/commands/initWithoutFiles.d.ts +10 -0
- package/dist/new/commands/initWithoutFiles.d.ts.map +1 -0
- package/dist/new/commands/initWithoutFiles.js +36 -0
- package/dist/new/commands/initWithoutFiles.js.map +1 -0
- package/dist/new/commands/login.d.ts +9 -0
- package/dist/new/commands/login.d.ts.map +1 -0
- package/dist/new/commands/login.js +51 -0
- package/dist/new/commands/login.js.map +1 -0
- package/dist/new/commands/logout.d.ts +4 -0
- package/dist/new/commands/logout.d.ts.map +1 -0
- package/dist/new/commands/logout.js +22 -0
- package/dist/new/commands/logout.js.map +1 -0
- package/dist/new/context/authToken.d.ts +19 -0
- package/dist/new/context/authToken.d.ts.map +1 -0
- package/dist/new/context/authToken.js +51 -0
- package/dist/new/context/authToken.js.map +1 -0
- package/dist/new/context/currentApp.d.ts +36 -0
- package/dist/new/context/currentApp.d.ts.map +1 -0
- package/dist/new/context/currentApp.js +145 -0
- package/dist/new/context/currentApp.js.map +1 -0
- package/dist/new/context/globalOpts.d.ts +11 -0
- package/dist/new/context/globalOpts.d.ts.map +1 -0
- package/dist/new/context/globalOpts.js +10 -0
- package/dist/new/context/globalOpts.js.map +1 -0
- package/dist/new/context/platformApi.d.ts +19 -0
- package/dist/new/context/platformApi.d.ts.map +1 -0
- package/dist/new/context/platformApi.js +24 -0
- package/dist/new/context/platformApi.js.map +1 -0
- package/dist/new/context/projectInfo.d.ts +25 -0
- package/dist/new/context/projectInfo.d.ts.map +1 -0
- package/dist/new/context/projectInfo.js +120 -0
- package/dist/new/context/projectInfo.js.map +1 -0
- package/dist/new/errors.d.ts +10 -0
- package/dist/new/errors.d.ts.map +1 -0
- package/dist/new/errors.js +6 -0
- package/dist/new/errors.js.map +1 -0
- package/dist/new/index.d.ts +17 -0
- package/dist/new/index.d.ts.map +1 -0
- package/dist/new/index.js +159 -0
- package/dist/new/index.js.map +1 -0
- package/dist/new/layer.d.ts +15 -0
- package/dist/new/layer.d.ts.map +1 -0
- package/dist/new/layer.js +41 -0
- package/dist/new/layer.js.map +1 -0
- package/dist/new/lib/createApp.d.ts +4 -0
- package/dist/new/lib/createApp.d.ts.map +1 -0
- package/dist/new/lib/createApp.js +13 -0
- package/dist/new/lib/createApp.js.map +1 -0
- package/dist/new/lib/handleEnv.d.ts +7 -0
- package/dist/new/lib/handleEnv.d.ts.map +1 -0
- package/dist/new/lib/handleEnv.js +88 -0
- package/dist/new/lib/handleEnv.js.map +1 -0
- package/dist/new/lib/http.d.ts +15 -0
- package/dist/new/lib/http.d.ts.map +1 -0
- package/dist/new/lib/http.js +32 -0
- package/dist/new/lib/http.js.map +1 -0
- package/dist/new/lib/login.d.ts +13 -0
- package/dist/new/lib/login.d.ts.map +1 -0
- package/dist/new/lib/login.js +36 -0
- package/dist/new/lib/login.js.map +1 -0
- package/dist/new/lib/ui.d.ts +16 -0
- package/dist/new/lib/ui.d.ts.map +1 -0
- package/dist/new/lib/ui.js +30 -0
- package/dist/new/lib/ui.js.map +1 -0
- package/dist/new/logging.d.ts +3 -0
- package/dist/new/logging.d.ts.map +1 -0
- package/dist/new/logging.js +8 -0
- package/dist/new/logging.js.map +1 -0
- package/dist/ui/index.d.ts +1 -1
- package/dist/ui/index.d.ts.map +1 -1
- package/dist/ui/index.js.map +1 -1
- package/dist/util/getAuthPaths.d.ts.map +1 -1
- package/dist/util/getAuthPaths.js.map +1 -1
- package/package.json +14 -5
- package/src/index.js +1 -1
- package/src/new/commands/init.ts +12 -0
- package/src/new/commands/initWithoutFiles.ts +44 -0
- package/src/new/commands/login.ts +73 -0
- package/src/new/commands/logout.ts +23 -0
- package/src/new/context/authToken.ts +77 -0
- package/src/new/context/currentApp.ts +207 -0
- package/src/new/context/globalOpts.ts +22 -0
- package/src/new/context/platformApi.ts +35 -0
- package/src/new/context/projectInfo.ts +172 -0
- package/src/new/errors.ts +7 -0
- package/src/new/index.ts +245 -0
- package/src/new/layer.ts +78 -0
- package/src/new/lib/createApp.ts +18 -0
- package/src/new/lib/handleEnv.ts +107 -0
- package/src/new/lib/http.ts +63 -0
- package/src/new/lib/login.ts +50 -0
- package/src/new/lib/ui.ts +45 -0
- package/src/new/logging.ts +9 -0
- package/src/ui/index.ts +1 -1
- package/src/util/getAuthPaths.ts +1 -0
- package/tsconfig.json +7 -2
package/src/new/layer.ts
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { NodeContext, NodeHttpClient } from '@effect/platform-node';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import { Cause, Console, Effect, Layer } from 'effect';
|
|
4
|
+
import { InstantHttpAuthedLive, InstantHttpLive } from './lib/http.js';
|
|
5
|
+
import { AuthTokenLive } from './context/authToken.js';
|
|
6
|
+
import { PlatformApi } from './context/platformApi.js';
|
|
7
|
+
import { GlobalOptsLive } from './context/globalOpts.js';
|
|
8
|
+
import {
|
|
9
|
+
PACKAGE_ALIAS_AND_FULL_NAMES,
|
|
10
|
+
ProjectInfoLive,
|
|
11
|
+
} from './context/projectInfo.js';
|
|
12
|
+
import { CurrentAppLive } from './context/currentApp.js';
|
|
13
|
+
|
|
14
|
+
export const printRedErrors = Effect.catchAllCause((cause) => {
|
|
15
|
+
const failure = Cause.failureOption(cause);
|
|
16
|
+
|
|
17
|
+
// Print just the message if the error has a message attribute and no cause
|
|
18
|
+
if (
|
|
19
|
+
failure._tag === 'Some' &&
|
|
20
|
+
typeof failure.value === 'object' &&
|
|
21
|
+
failure.value !== null &&
|
|
22
|
+
'message' in failure.value &&
|
|
23
|
+
!('cause' in failure.value)
|
|
24
|
+
) {
|
|
25
|
+
return Console.error(
|
|
26
|
+
chalk.red((failure.value as { message: string }).message),
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
return Console.error(
|
|
30
|
+
chalk.red(Cause.pretty(cause, { renderErrorCause: true })),
|
|
31
|
+
);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Note:
|
|
36
|
+
Avoid Duplicate Layer Creation
|
|
37
|
+
|
|
38
|
+
Layers are memoized using reference equality. Therefore, if you have a layer that is created by calling a function like f(), you should only call that f once and re-use the resulting layer so that you are always using the same instance.
|
|
39
|
+
*/
|
|
40
|
+
|
|
41
|
+
// Base layers
|
|
42
|
+
const AuthTokenLayer = Layer.provide(AuthTokenLive, NodeContext.layer);
|
|
43
|
+
const InstantHttpLayer = Layer.provide(InstantHttpLive, NodeHttpClient.layer);
|
|
44
|
+
|
|
45
|
+
// Unauthenticated layer with InstantHttp + PlatformApi + GlobalOpts + NodeContext
|
|
46
|
+
export const BaseLayerLive = Layer.provideMerge(
|
|
47
|
+
Layer.mergeAll(InstantHttpLayer, PlatformApi.Default, GlobalOptsLive),
|
|
48
|
+
NodeContext.layer,
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
// Authenticated layer extends BaseLayerLive with InstantHttpAuthed
|
|
52
|
+
export const AuthLayerLive = Layer.provideMerge(
|
|
53
|
+
Layer.provideMerge(
|
|
54
|
+
InstantHttpAuthedLive,
|
|
55
|
+
Layer.merge(AuthTokenLayer, InstantHttpLayer),
|
|
56
|
+
),
|
|
57
|
+
BaseLayerLive,
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
export const WithAppLayer = (args: {
|
|
61
|
+
appId?: string;
|
|
62
|
+
title?: string;
|
|
63
|
+
coerce: boolean;
|
|
64
|
+
packageName: keyof typeof PACKAGE_ALIAS_AND_FULL_NAMES;
|
|
65
|
+
applyEnv?: boolean;
|
|
66
|
+
}) =>
|
|
67
|
+
Layer.mergeAll(
|
|
68
|
+
CurrentAppLive({
|
|
69
|
+
coerce: args.coerce,
|
|
70
|
+
appId: args.appId,
|
|
71
|
+
title: args.title,
|
|
72
|
+
applyEnv: args.applyEnv,
|
|
73
|
+
}),
|
|
74
|
+
).pipe(
|
|
75
|
+
Layer.provideMerge(GlobalOptsLive),
|
|
76
|
+
Layer.provideMerge(AuthLayerLive),
|
|
77
|
+
Layer.provideMerge(ProjectInfoLive(args.coerce, args.packageName)),
|
|
78
|
+
);
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { randomUUID } from 'crypto';
|
|
2
|
+
import { Effect } from 'effect';
|
|
3
|
+
import { InstantHttpAuthed } from './http.js';
|
|
4
|
+
import { HttpClientRequest } from '@effect/platform';
|
|
5
|
+
|
|
6
|
+
export const createApp = Effect.fn(function* (title: string, orgId?: string) {
|
|
7
|
+
const http = yield* InstantHttpAuthed;
|
|
8
|
+
const id = randomUUID();
|
|
9
|
+
const token = randomUUID();
|
|
10
|
+
const app = { id, title, admin_token: token, org_id: orgId };
|
|
11
|
+
|
|
12
|
+
const res = yield* HttpClientRequest.post('/dash/apps').pipe(
|
|
13
|
+
HttpClientRequest.bodyJson(app),
|
|
14
|
+
Effect.flatMap(http.execute),
|
|
15
|
+
Effect.flatMap((res) => res.json),
|
|
16
|
+
);
|
|
17
|
+
return res;
|
|
18
|
+
});
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { Effect } from 'effect';
|
|
2
|
+
import { CurrentAppInfo, potentialEnvs } from '../context/currentApp.js';
|
|
3
|
+
import { ProjectInfo, ProjectInfoError } from '../context/projectInfo.js';
|
|
4
|
+
import { readPackage } from 'pkg-types';
|
|
5
|
+
import { GlobalOpts } from '../context/globalOpts.js';
|
|
6
|
+
import { FileSystem, Path } from '@effect/platform';
|
|
7
|
+
import chalk from 'chalk';
|
|
8
|
+
import terminalLink from 'terminal-link';
|
|
9
|
+
import { getDashUrl } from './http.js';
|
|
10
|
+
import { promptOk } from './ui.js';
|
|
11
|
+
|
|
12
|
+
export const handleEnv = Effect.fn(function* (app: CurrentAppInfo) {
|
|
13
|
+
const opts = yield* GlobalOpts;
|
|
14
|
+
const { pkgDir } = yield* ProjectInfo;
|
|
15
|
+
const envType = yield* detectEnvType;
|
|
16
|
+
const envName = potentialEnvs[envType];
|
|
17
|
+
const envFile = opts.env ?? '.env';
|
|
18
|
+
const fs = yield* FileSystem.FileSystem;
|
|
19
|
+
const path = yield* Path.Path;
|
|
20
|
+
const hasEnvFile = yield* fs.exists(path.join(pkgDir, envFile));
|
|
21
|
+
const dashOrigin = yield* getDashUrl;
|
|
22
|
+
if (hasEnvFile) {
|
|
23
|
+
return printDotEnvInfo(envType, app.appId, dashOrigin);
|
|
24
|
+
}
|
|
25
|
+
console.log(
|
|
26
|
+
`\nLooks like you don't have a ${chalk.green(`\`${envFile}\``)} file yet.`,
|
|
27
|
+
);
|
|
28
|
+
console.log(
|
|
29
|
+
`If we set ${chalk.green(envName)} & ${chalk.green('INSTANT_APP_ADMIN_TOKEN')}, we can remember the app that you chose for all future commands.`,
|
|
30
|
+
);
|
|
31
|
+
const saveExtraInfo =
|
|
32
|
+
envFile !== '.env' ? chalk.green(' (will create `' + envFile + '`)') : '';
|
|
33
|
+
|
|
34
|
+
const ok = yield* promptOk(
|
|
35
|
+
{
|
|
36
|
+
inline: true,
|
|
37
|
+
promptText: 'Want us to create this env file for you?' + saveExtraInfo,
|
|
38
|
+
modifyOutput: (a) => a,
|
|
39
|
+
},
|
|
40
|
+
true,
|
|
41
|
+
);
|
|
42
|
+
if (!ok) {
|
|
43
|
+
console.log(
|
|
44
|
+
`No .env file created. You can always set ${chalk.green('`' + envName + '`')} later. \n`,
|
|
45
|
+
);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
const content =
|
|
49
|
+
[
|
|
50
|
+
[envName, app.appId],
|
|
51
|
+
['INSTANT_APP_ADMIN_TOKEN', app.adminToken],
|
|
52
|
+
]
|
|
53
|
+
.map(([k, v]) => `${k}=${v}`)
|
|
54
|
+
.join('\n') + '\n';
|
|
55
|
+
|
|
56
|
+
yield* fs.writeFileString(path.join(pkgDir, envFile), content);
|
|
57
|
+
|
|
58
|
+
if (envFile !== '.env') {
|
|
59
|
+
console.log(`Created ${chalk.green(envFile)}!`);
|
|
60
|
+
} else {
|
|
61
|
+
console.log(`Created ${chalk.green('.env')} file!`);
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
const detectEnvType = Effect.gen(function* () {
|
|
66
|
+
const pkgJson = yield* Effect.tryPromise({
|
|
67
|
+
try: () => readPackage(),
|
|
68
|
+
catch: () =>
|
|
69
|
+
new ProjectInfoError({ message: "Couldn't read package.json" }),
|
|
70
|
+
});
|
|
71
|
+
if (pkgJson.dependencies?.next) {
|
|
72
|
+
return 'next';
|
|
73
|
+
}
|
|
74
|
+
if (pkgJson.devDependencies?.svelte) {
|
|
75
|
+
return 'svelte';
|
|
76
|
+
}
|
|
77
|
+
if (pkgJson.devDependencies?.vite) {
|
|
78
|
+
return 'vite';
|
|
79
|
+
}
|
|
80
|
+
if (pkgJson.dependencies?.expo) {
|
|
81
|
+
return 'expo';
|
|
82
|
+
}
|
|
83
|
+
if (pkgJson.dependencies?.nuxt) {
|
|
84
|
+
return 'nuxt';
|
|
85
|
+
}
|
|
86
|
+
return 'catchall';
|
|
87
|
+
}).pipe(Effect.catchTag('ProjectInfoError', () => Effect.succeed('catchall')));
|
|
88
|
+
|
|
89
|
+
function printDotEnvInfo(envType, appId, dashOrigin: string) {
|
|
90
|
+
console.log(`\nPicked app ${chalk.green(appId)}!\n`);
|
|
91
|
+
console.log(
|
|
92
|
+
`To use this app automatically from now on, update your ${chalk.green('`.env`')} file:`,
|
|
93
|
+
);
|
|
94
|
+
const picked = potentialEnvs[envType];
|
|
95
|
+
const rest = { ...potentialEnvs };
|
|
96
|
+
delete rest[envType];
|
|
97
|
+
console.log(` ${chalk.green(picked)}=${appId}`);
|
|
98
|
+
const otherEnvs = Object.values(rest);
|
|
99
|
+
otherEnvs.sort();
|
|
100
|
+
const otherEnvStr = otherEnvs.map((x) => ' ' + chalk.green(x)).join('\n');
|
|
101
|
+
console.log(`Alternative names: \n${otherEnvStr} \n`);
|
|
102
|
+
console.log(terminalLink('Dashboard:', appDashUrl(appId, dashOrigin)) + '\n');
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function appDashUrl(id, instantOrigin: string) {
|
|
106
|
+
return `${instantOrigin}/dash?s=main&t=home&app=${id}`;
|
|
107
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { HttpClient, HttpClientRequest } from '@effect/platform';
|
|
2
|
+
import { Config, Context, Effect, Layer, Option } from 'effect';
|
|
3
|
+
import { AuthToken } from '../context/authToken.js';
|
|
4
|
+
|
|
5
|
+
export class InstantHttp extends Context.Tag(
|
|
6
|
+
'instant-cli/new/lib/http/InstantHttp',
|
|
7
|
+
)<InstantHttp, HttpClient.HttpClient>() {}
|
|
8
|
+
|
|
9
|
+
export class InstantHttpAuthed extends Context.Tag(
|
|
10
|
+
'instant-cli/new/lib/http/InstantHttpAuthed',
|
|
11
|
+
)<InstantHttpAuthed, HttpClient.HttpClient>() {}
|
|
12
|
+
|
|
13
|
+
export const InstantHttpLive = Layer.effect(
|
|
14
|
+
InstantHttp,
|
|
15
|
+
Effect.gen(function* () {
|
|
16
|
+
const client = yield* HttpClient.HttpClient;
|
|
17
|
+
const baseUrl = yield* getBaseUrl;
|
|
18
|
+
return client.pipe(
|
|
19
|
+
HttpClient.mapRequest((r) =>
|
|
20
|
+
r.pipe(HttpClientRequest.prependUrl(baseUrl)),
|
|
21
|
+
),
|
|
22
|
+
HttpClient.filterStatusOk, // makes non 2xx http codes error
|
|
23
|
+
);
|
|
24
|
+
}),
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
export const InstantHttpAuthedLive = Layer.effect(
|
|
28
|
+
InstantHttpAuthed,
|
|
29
|
+
Effect.gen(function* () {
|
|
30
|
+
const http = yield* InstantHttp;
|
|
31
|
+
const { authToken } = yield* AuthToken;
|
|
32
|
+
return http.pipe(
|
|
33
|
+
HttpClient.mapRequest((r) =>
|
|
34
|
+
r.pipe(
|
|
35
|
+
HttpClientRequest.setHeader('Authorization', `Bearer ${authToken}`),
|
|
36
|
+
),
|
|
37
|
+
),
|
|
38
|
+
);
|
|
39
|
+
}),
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
export const getBaseUrl = Effect.gen(function* () {
|
|
43
|
+
const setEnv = yield* Config.string('INSTANT_CLI_API_URI').pipe(
|
|
44
|
+
Config.option,
|
|
45
|
+
);
|
|
46
|
+
const dev = yield* Config.boolean('INSTANT_CLI_DEV').pipe(
|
|
47
|
+
Config.withDefault(false),
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
return Option.match(setEnv, {
|
|
51
|
+
onSome: (url) => url,
|
|
52
|
+
onNone: () => {
|
|
53
|
+
return dev ? 'http://localhost:8888' : 'https://api.instantdb.com';
|
|
54
|
+
},
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
export const getDashUrl = Effect.gen(function* () {
|
|
59
|
+
const dev = Option.getOrNull(
|
|
60
|
+
yield* Config.boolean('INSTANT_CLI_DEV').pipe(Config.option),
|
|
61
|
+
);
|
|
62
|
+
return dev ? 'http://localhost:3000' : 'https://instantdb.com';
|
|
63
|
+
});
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { Effect, Schedule, Schema } from 'effect';
|
|
2
|
+
import { InstantHttp } from './http.js';
|
|
3
|
+
import {
|
|
4
|
+
HttpClientRequest,
|
|
5
|
+
HttpClientResponse,
|
|
6
|
+
FileSystem,
|
|
7
|
+
} from '@effect/platform';
|
|
8
|
+
import { getAuthPaths } from '../../util/getAuthPaths.js';
|
|
9
|
+
|
|
10
|
+
const LoginInfo = Schema.Struct({
|
|
11
|
+
secret: Schema.String,
|
|
12
|
+
ticket: Schema.String,
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
const TokenResult = Schema.Struct({
|
|
16
|
+
token: Schema.String,
|
|
17
|
+
email: Schema.String,
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
export const getLoginTicketAndSecret = Effect.gen(function* () {
|
|
21
|
+
const http = yield* InstantHttp;
|
|
22
|
+
const res = yield* http
|
|
23
|
+
.post('/dash/cli/auth/register')
|
|
24
|
+
.pipe(Effect.flatMap(HttpClientResponse.schemaBodyJson(LoginInfo)));
|
|
25
|
+
return res;
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
export const waitForAuthToken = Effect.fn(function* (secret: string) {
|
|
29
|
+
const http = yield* InstantHttp;
|
|
30
|
+
const res = yield* HttpClientRequest.post('/dash/cli/auth/check').pipe(
|
|
31
|
+
HttpClientRequest.bodyJson({
|
|
32
|
+
secret,
|
|
33
|
+
}),
|
|
34
|
+
Effect.flatMap(http.execute),
|
|
35
|
+
Effect.flatMap(HttpClientResponse.schemaBodyJson(TokenResult)),
|
|
36
|
+
Effect.retry({
|
|
37
|
+
schedule: Schedule.fixed('1 seconds'),
|
|
38
|
+
times: 12,
|
|
39
|
+
}),
|
|
40
|
+
);
|
|
41
|
+
return res;
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
export const saveConfigAuthToken = Effect.fn(function* (token: string) {
|
|
45
|
+
const authPaths = getAuthPaths();
|
|
46
|
+
|
|
47
|
+
const fs = yield* FileSystem.FileSystem;
|
|
48
|
+
yield* fs.makeDirectory(authPaths.appConfigDirPath, { recursive: true });
|
|
49
|
+
yield* fs.writeFileString(authPaths.authConfigFilePath, token);
|
|
50
|
+
});
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Data, Effect } from 'effect';
|
|
2
|
+
import { GlobalOpts } from '../context/globalOpts.js';
|
|
3
|
+
import { Prompt, renderUnwrap } from '../../ui/lib.js';
|
|
4
|
+
import boxen from 'boxen';
|
|
5
|
+
import { UI } from '../../ui/index.js';
|
|
6
|
+
|
|
7
|
+
export class UIError extends Data.TaggedError('UIError')<{
|
|
8
|
+
message: string;
|
|
9
|
+
cause?: unknown;
|
|
10
|
+
}> {}
|
|
11
|
+
|
|
12
|
+
export const promptOk = Effect.fn('promptOk')(function* (
|
|
13
|
+
props: UI.ConfirmationProps,
|
|
14
|
+
defaultValue: boolean = true,
|
|
15
|
+
) {
|
|
16
|
+
const opts = yield* GlobalOpts;
|
|
17
|
+
if (opts.yes) {
|
|
18
|
+
return defaultValue;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const ok = yield* Effect.tryPromise(() =>
|
|
22
|
+
renderUnwrap(
|
|
23
|
+
new UI.Confirmation({
|
|
24
|
+
...props,
|
|
25
|
+
modifyOutput: (out) =>
|
|
26
|
+
boxen(out, {
|
|
27
|
+
dimBorder: true,
|
|
28
|
+
padding: {
|
|
29
|
+
left: 1,
|
|
30
|
+
right: 1,
|
|
31
|
+
},
|
|
32
|
+
}),
|
|
33
|
+
defaultValue,
|
|
34
|
+
}),
|
|
35
|
+
),
|
|
36
|
+
).pipe(Effect.orElseSucceed(() => defaultValue));
|
|
37
|
+
|
|
38
|
+
return ok;
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
export const runUIEffect = <P>(prompt: Prompt<P>) =>
|
|
42
|
+
Effect.tryPromise({
|
|
43
|
+
try: () => renderUnwrap(prompt),
|
|
44
|
+
catch: (error) => new UIError({ message: 'UI Error', cause: error }),
|
|
45
|
+
});
|
package/src/ui/index.ts
CHANGED
package/src/util/getAuthPaths.ts
CHANGED
package/tsconfig.json
CHANGED
|
@@ -5,9 +5,14 @@
|
|
|
5
5
|
"rootDir": "src",
|
|
6
6
|
"sourceMap": true,
|
|
7
7
|
"skipLibCheck": true, // `unconfig` currently imports a broken type from `@antfu/utils`,
|
|
8
|
-
"
|
|
8
|
+
"plugins": [
|
|
9
|
+
{
|
|
10
|
+
"name": "@effect/language-service",
|
|
11
|
+
},
|
|
12
|
+
],
|
|
13
|
+
"strictNullChecks": true,
|
|
9
14
|
// remove once fixed
|
|
10
15
|
},
|
|
11
16
|
"include": ["src"],
|
|
12
|
-
"exclude": ["node_modules", "dist"]
|
|
17
|
+
"exclude": ["node_modules", "dist"],
|
|
13
18
|
}
|