instant-cli 0.22.177 → 0.22.178
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 +2 -2
- package/__tests__/e2e/cli.e2e.test.ts +3 -3
- package/__tests__/e2e/helpers.ts +1 -1
- package/__tests__/effectHelpers.ts +45 -0
- package/__tests__/mergeSchema.test.ts +2 -2
- package/dist/commands/claim.d.ts +6 -0
- package/dist/commands/claim.d.ts.map +1 -0
- package/dist/commands/claim.js +22 -0
- package/dist/commands/claim.js.map +1 -0
- package/dist/commands/explorer.d.ts +6 -0
- package/dist/commands/explorer.d.ts.map +1 -0
- package/dist/commands/explorer.js +13 -0
- package/dist/commands/explorer.js.map +1 -0
- package/dist/commands/info.d.ts +3 -0
- package/dist/commands/info.d.ts.map +1 -0
- package/dist/commands/info.js +24 -0
- package/dist/commands/info.js.map +1 -0
- package/dist/commands/init.d.ts +5 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +39 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/initWithoutFiles.d.ts +6 -0
- package/dist/commands/initWithoutFiles.d.ts.map +1 -0
- package/dist/commands/initWithoutFiles.js +64 -0
- package/dist/commands/initWithoutFiles.js.map +1 -0
- package/dist/commands/login.d.ts +9 -0
- package/dist/commands/login.d.ts.map +1 -0
- package/dist/commands/login.js +52 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/logout.d.ts +4 -0
- package/dist/commands/logout.d.ts.map +1 -0
- package/dist/commands/logout.js +21 -0
- package/dist/commands/logout.js.map +1 -0
- package/dist/commands/pull.d.ts +6 -0
- package/dist/commands/pull.d.ts.map +1 -0
- package/dist/commands/pull.js +16 -0
- package/dist/commands/pull.js.map +1 -0
- package/dist/commands/push.d.ts +6 -0
- package/dist/commands/push.d.ts.map +1 -0
- package/dist/commands/push.js +20 -0
- package/dist/commands/push.js.map +1 -0
- package/dist/commands/query.d.ts +7 -0
- package/dist/commands/query.d.ts.map +1 -0
- package/dist/commands/query.js +52 -0
- package/dist/commands/query.js.map +1 -0
- package/dist/context/authToken.d.ts +30 -0
- package/dist/context/authToken.d.ts.map +1 -0
- package/dist/context/authToken.js +86 -0
- package/dist/context/authToken.js.map +1 -0
- package/dist/context/currentApp.d.ts +37 -0
- package/dist/context/currentApp.d.ts.map +1 -0
- package/dist/context/currentApp.js +204 -0
- package/dist/context/currentApp.js.map +1 -0
- package/dist/context/globalOpts.d.ts +11 -0
- package/dist/context/globalOpts.d.ts.map +1 -0
- package/dist/context/globalOpts.js +13 -0
- package/dist/context/globalOpts.js.map +1 -0
- package/dist/context/platformApi.d.ts +19 -0
- package/dist/context/platformApi.d.ts.map +1 -0
- package/dist/context/platformApi.js +24 -0
- package/dist/context/platformApi.js.map +1 -0
- package/dist/context/projectInfo.d.ts +29 -0
- package/dist/context/projectInfo.d.ts.map +1 -0
- package/dist/context/projectInfo.js +149 -0
- package/dist/context/projectInfo.js.map +1 -0
- package/dist/errors.d.ts +10 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +6 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +41 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +169 -1781
- package/dist/index.js.map +1 -1
- package/dist/layer.d.ts +23 -0
- package/dist/layer.d.ts.map +1 -0
- package/dist/layer.js +68 -0
- package/dist/layer.js.map +1 -0
- package/dist/lib/createApp.d.ts +12 -0
- package/dist/lib/createApp.d.ts.map +1 -0
- package/dist/lib/createApp.js +15 -0
- package/dist/lib/createApp.js.map +1 -0
- package/dist/lib/handleEnv.d.ts +7 -0
- package/dist/lib/handleEnv.d.ts.map +1 -0
- package/dist/lib/handleEnv.js +91 -0
- package/dist/lib/handleEnv.js.map +1 -0
- package/dist/lib/http.d.ts +32 -0
- package/dist/lib/http.d.ts.map +1 -0
- package/dist/lib/http.js +67 -0
- package/dist/lib/http.js.map +1 -0
- package/dist/lib/login.d.ts +13 -0
- package/dist/lib/login.d.ts.map +1 -0
- package/dist/lib/login.js +39 -0
- package/dist/lib/login.js.map +1 -0
- package/dist/lib/pullPerms.d.ts +7 -0
- package/dist/lib/pullPerms.d.ts.map +1 -0
- package/dist/lib/pullPerms.js +41 -0
- package/dist/lib/pullPerms.js.map +1 -0
- package/dist/lib/pullSchema.d.ts +12 -0
- package/dist/lib/pullSchema.d.ts.map +1 -0
- package/dist/lib/pullSchema.js +62 -0
- package/dist/lib/pullSchema.js.map +1 -0
- package/dist/lib/pushPerms.d.ts +13 -0
- package/dist/lib/pushPerms.d.ts.map +1 -0
- package/dist/lib/pushPerms.js +54 -0
- package/dist/lib/pushPerms.js.map +1 -0
- package/dist/lib/pushSchema.d.ts +53 -0
- package/dist/lib/pushSchema.d.ts.map +1 -0
- package/dist/lib/pushSchema.js +160 -0
- package/dist/lib/pushSchema.js.map +1 -0
- package/dist/lib/ui.d.ts +16 -0
- package/dist/lib/ui.d.ts.map +1 -0
- package/dist/lib/ui.js +22 -0
- package/dist/lib/ui.js.map +1 -0
- package/dist/logging.d.ts +4 -0
- package/dist/logging.d.ts.map +1 -0
- package/dist/logging.js +17 -0
- package/dist/logging.js.map +1 -0
- package/dist/old.d.ts +14 -0
- package/dist/old.d.ts.map +1 -0
- package/dist/old.js +417 -0
- package/dist/old.js.map +1 -0
- package/dist/program.d.ts +3 -0
- package/dist/program.d.ts.map +1 -0
- package/dist/program.js +3 -0
- package/dist/program.js.map +1 -0
- package/dist/renderSchemaPlan.d.ts +3 -3
- package/dist/renderSchemaPlan.d.ts.map +1 -1
- package/dist/renderSchemaPlan.js +2 -14
- package/dist/renderSchemaPlan.js.map +1 -1
- package/dist/ui/index.d.ts +4 -3
- package/dist/ui/index.d.ts.map +1 -1
- package/dist/ui/index.js +2 -2
- package/dist/ui/index.js.map +1 -1
- package/dist/ui/lib.js +1 -0
- package/dist/ui/lib.js.map +1 -1
- package/dist/util/findConfigCandidates.d.ts +1 -1
- package/dist/util/findConfigCandidates.d.ts.map +1 -1
- package/dist/util/findConfigCandidates.js +1 -3
- package/dist/util/findConfigCandidates.js.map +1 -1
- package/dist/util/fs.d.ts +1 -1
- package/dist/util/fs.d.ts.map +1 -1
- package/dist/util/fs.js.map +1 -1
- package/dist/util/getAuthPaths.d.ts.map +1 -1
- package/dist/util/getAuthPaths.js.map +1 -1
- package/dist/util/isHeadlessEnvironment.d.ts +3 -1
- package/dist/util/isHeadlessEnvironment.d.ts.map +1 -1
- package/dist/util/isHeadlessEnvironment.js.map +1 -1
- package/dist/util/loadConfig.d.ts +1 -1
- package/dist/util/loadConfig.d.ts.map +1 -1
- package/dist/util/loadConfig.js +2 -2
- package/dist/util/loadConfig.js.map +1 -1
- package/dist/util/mergeSchema.d.ts +9 -1
- package/dist/util/mergeSchema.d.ts.map +1 -1
- package/dist/util/mergeSchema.js +4 -0
- package/dist/util/mergeSchema.js.map +1 -1
- package/dist/util/renamePrompt.d.ts +2 -1
- package/dist/util/renamePrompt.d.ts.map +1 -1
- package/dist/util/renamePrompt.js +1 -1
- package/dist/util/renamePrompt.js.map +1 -1
- package/package.json +17 -7
- package/src/commands/claim.ts +31 -0
- package/src/commands/explorer.ts +21 -0
- package/src/commands/info.ts +34 -0
- package/src/commands/init.ts +58 -0
- package/src/commands/initWithoutFiles.ts +107 -0
- package/src/commands/login.ts +76 -0
- package/src/commands/logout.ts +23 -0
- package/src/commands/pull.ts +23 -0
- package/src/commands/push.ts +25 -0
- package/src/commands/query.ts +61 -0
- package/src/context/authToken.ts +149 -0
- package/src/context/currentApp.ts +277 -0
- package/src/context/globalOpts.ts +22 -0
- package/src/context/platformApi.ts +35 -0
- package/src/context/projectInfo.ts +215 -0
- package/src/errors.ts +7 -0
- package/src/index.ts +428 -0
- package/src/layer.ts +155 -0
- package/src/lib/createApp.ts +28 -0
- package/src/lib/handleEnv.ts +115 -0
- package/src/lib/http.ts +148 -0
- package/src/lib/login.ts +54 -0
- package/src/lib/pullPerms.ts +50 -0
- package/src/lib/pullSchema.ts +95 -0
- package/src/lib/pushPerms.ts +80 -0
- package/src/lib/pushSchema.ts +240 -0
- package/src/lib/ui.ts +36 -0
- package/src/logging.ts +32 -0
- package/src/old.js +495 -0
- package/src/program.ts +3 -0
- package/src/renderSchemaPlan.ts +6 -18
- package/src/ui/index.ts +4 -3
- package/src/util/findConfigCandidates.ts +1 -2
- package/src/util/fs.ts +1 -1
- package/src/util/getAuthPaths.ts +1 -0
- package/src/util/isHeadlessEnvironment.ts +1 -1
- package/src/util/loadConfig.ts +3 -6
- package/src/util/{mergeSchema.js → mergeSchema.ts} +26 -16
- package/src/util/renamePrompt.ts +2 -1
- package/tsconfig.build.json +20 -0
- package/tsconfig.json +15 -5
- package/vitest.config.ts +2 -1
- package/dist/util/packageManager.d.ts +0 -3
- package/dist/util/packageManager.d.ts.map +0 -1
- package/dist/util/packageManager.js +0 -70
- package/dist/util/packageManager.js.map +0 -1
- package/dist/util/promptOk.d.ts +0 -4
- package/dist/util/promptOk.d.ts.map +0 -1
- package/dist/util/promptOk.js +0 -18
- package/dist/util/promptOk.js.map +0 -1
- package/src/index.js +0 -2333
- package/src/util/packageManager.js +0 -78
- package/src/util/promptOk.ts +0 -26
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { Effect } from 'effect';
|
|
2
|
+
import { 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
|
+
export const handleEnv = Effect.fn(function* (app) {
|
|
12
|
+
const opts = yield* GlobalOpts;
|
|
13
|
+
const { pkgDir } = yield* ProjectInfo;
|
|
14
|
+
const envType = yield* detectEnvType;
|
|
15
|
+
const envName = potentialEnvs[envType];
|
|
16
|
+
const envFile = opts.env ?? '.env';
|
|
17
|
+
const fs = yield* FileSystem.FileSystem;
|
|
18
|
+
const path = yield* Path.Path;
|
|
19
|
+
const hasEnvFile = yield* fs.exists(path.join(pkgDir, envFile));
|
|
20
|
+
const dashOrigin = yield* getDashUrl;
|
|
21
|
+
if (hasEnvFile) {
|
|
22
|
+
return printDotEnvInfo(envType, app.appId, dashOrigin);
|
|
23
|
+
}
|
|
24
|
+
yield* Effect.log(`\nLooks like you don't have a ${chalk.green(`\`${envFile}\``)} file yet.`);
|
|
25
|
+
yield* Effect.log(`If we set ${chalk.green(envName)} & ${chalk.green('INSTANT_APP_ADMIN_TOKEN')}, we can remember the app that you chose for all future commands.`);
|
|
26
|
+
const saveExtraInfo = envFile !== '.env' ? chalk.green(' (will create `' + envFile + '`)') : '';
|
|
27
|
+
const ok = yield* promptOk({
|
|
28
|
+
inline: true,
|
|
29
|
+
promptText: 'Want us to create this env file for you?' + saveExtraInfo,
|
|
30
|
+
modifyOutput: (a) => a,
|
|
31
|
+
}, true);
|
|
32
|
+
if (!ok) {
|
|
33
|
+
yield* Effect.log(`No .env file created. You can always set ${chalk.green('`' + envName + '`')} later. \n`);
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
const content = [
|
|
37
|
+
[envName, app.appId],
|
|
38
|
+
['INSTANT_APP_ADMIN_TOKEN', app.adminToken],
|
|
39
|
+
]
|
|
40
|
+
.map(([k, v]) => `${k}=${v}`)
|
|
41
|
+
.join('\n') + '\n';
|
|
42
|
+
yield* fs.writeFileString(path.join(pkgDir, envFile), content);
|
|
43
|
+
if (envFile !== '.env') {
|
|
44
|
+
yield* Effect.log(`Created ${chalk.green(envFile)}!`);
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
yield* Effect.log(`Created ${chalk.green('.env')} file!`);
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
const detectEnvType = Effect.gen(function* () {
|
|
51
|
+
const pkgJson = yield* Effect.tryPromise({
|
|
52
|
+
try: () => readPackage(),
|
|
53
|
+
catch: () => new ProjectInfoError({ message: "Couldn't read package.json" }),
|
|
54
|
+
});
|
|
55
|
+
if (pkgJson.dependencies?.next) {
|
|
56
|
+
return 'next';
|
|
57
|
+
}
|
|
58
|
+
if (pkgJson.devDependencies?.svelte) {
|
|
59
|
+
return 'svelte';
|
|
60
|
+
}
|
|
61
|
+
if (pkgJson.devDependencies?.vite) {
|
|
62
|
+
return 'vite';
|
|
63
|
+
}
|
|
64
|
+
if (pkgJson.dependencies?.expo) {
|
|
65
|
+
return 'expo';
|
|
66
|
+
}
|
|
67
|
+
if (pkgJson.dependencies?.nuxt) {
|
|
68
|
+
return 'nuxt';
|
|
69
|
+
}
|
|
70
|
+
if (pkgJson.dependencies?.['@types/bun']) {
|
|
71
|
+
return 'bun';
|
|
72
|
+
}
|
|
73
|
+
return 'catchall';
|
|
74
|
+
}).pipe(Effect.catchTag('ProjectInfoError', () => Effect.succeed('catchall')));
|
|
75
|
+
function printDotEnvInfo(envType, appId, dashOrigin) {
|
|
76
|
+
console.log(`\nPicked app ${chalk.green(appId)}!\n`);
|
|
77
|
+
console.log(`To use this app automatically from now on, update your ${chalk.green('`.env`')} file:`);
|
|
78
|
+
const picked = potentialEnvs[envType];
|
|
79
|
+
const rest = { ...potentialEnvs };
|
|
80
|
+
delete rest[envType];
|
|
81
|
+
console.log(` ${chalk.green(picked)}=${appId}`);
|
|
82
|
+
const otherEnvs = Object.values(rest);
|
|
83
|
+
otherEnvs.sort();
|
|
84
|
+
const otherEnvStr = otherEnvs.map((x) => ' ' + chalk.green(x)).join('\n');
|
|
85
|
+
console.log(`Alternative names: \n${otherEnvStr} \n`);
|
|
86
|
+
console.log(terminalLink('Dashboard:', appDashUrl(appId, dashOrigin)) + '\n');
|
|
87
|
+
}
|
|
88
|
+
function appDashUrl(id, instantOrigin) {
|
|
89
|
+
return `${instantOrigin}/dash?s=main&t=home&app=${id}`;
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=handleEnv.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handleEnv.js","sourceRoot":"","sources":["../../src/lib/handleEnv.ts"],"names":[],"mappings":"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","sourcesContent":["import { Effect } from 'effect';\nimport { potentialEnvs } from '../context/currentApp.ts';\nimport type { CurrentAppInfo } from '../context/currentApp.ts';\nimport { ProjectInfo, ProjectInfoError } from '../context/projectInfo.ts';\nimport { readPackage } from 'pkg-types';\nimport { GlobalOpts } from '../context/globalOpts.ts';\nimport { FileSystem, Path } from '@effect/platform';\nimport chalk from 'chalk';\nimport terminalLink from 'terminal-link';\nimport { getDashUrl } from './http.ts';\nimport { promptOk } from './ui.ts';\n\nexport const handleEnv = Effect.fn(function* (app: CurrentAppInfo) {\n const opts = yield* GlobalOpts;\n const { pkgDir } = yield* ProjectInfo;\n const envType = yield* detectEnvType;\n const envName = potentialEnvs[envType];\n const envFile = opts.env ?? '.env';\n const fs = yield* FileSystem.FileSystem;\n const path = yield* Path.Path;\n const hasEnvFile = yield* fs.exists(path.join(pkgDir, envFile));\n const dashOrigin = yield* getDashUrl;\n if (hasEnvFile) {\n return printDotEnvInfo(envType, app.appId, dashOrigin);\n }\n yield* Effect.log(\n `\\nLooks like you don't have a ${chalk.green(`\\`${envFile}\\``)} file yet.`,\n );\n yield* Effect.log(\n `If we set ${chalk.green(envName)} & ${chalk.green('INSTANT_APP_ADMIN_TOKEN')}, we can remember the app that you chose for all future commands.`,\n );\n const saveExtraInfo =\n envFile !== '.env' ? chalk.green(' (will create `' + envFile + '`)') : '';\n\n const ok = yield* promptOk(\n {\n inline: true,\n promptText: 'Want us to create this env file for you?' + saveExtraInfo,\n modifyOutput: (a) => a,\n },\n true,\n );\n if (!ok) {\n yield* Effect.log(\n `No .env file created. You can always set ${chalk.green('`' + envName + '`')} later. \\n`,\n );\n return;\n }\n const content =\n [\n [envName, app.appId],\n ['INSTANT_APP_ADMIN_TOKEN', app.adminToken],\n ]\n .map(([k, v]) => `${k}=${v}`)\n .join('\\n') + '\\n';\n\n yield* fs.writeFileString(path.join(pkgDir, envFile), content);\n\n if (envFile !== '.env') {\n yield* Effect.log(`Created ${chalk.green(envFile)}!`);\n } else {\n yield* Effect.log(`Created ${chalk.green('.env')} file!`);\n }\n});\n\nconst detectEnvType = Effect.gen(function* () {\n const pkgJson = yield* Effect.tryPromise({\n try: () => readPackage(),\n catch: () =>\n new ProjectInfoError({ message: \"Couldn't read package.json\" }),\n });\n if (pkgJson.dependencies?.next) {\n return 'next';\n }\n if (pkgJson.devDependencies?.svelte) {\n return 'svelte';\n }\n if (pkgJson.devDependencies?.vite) {\n return 'vite';\n }\n if (pkgJson.dependencies?.expo) {\n return 'expo';\n }\n if (pkgJson.dependencies?.nuxt) {\n return 'nuxt';\n }\n if (pkgJson.dependencies?.['@types/bun']) {\n return 'bun';\n }\n return 'catchall';\n}).pipe(Effect.catchTag('ProjectInfoError', () => Effect.succeed('catchall')));\n\nfunction printDotEnvInfo(\n envType: keyof typeof potentialEnvs,\n appId: string,\n dashOrigin: string,\n) {\n console.log(`\\nPicked app ${chalk.green(appId)}!\\n`);\n console.log(\n `To use this app automatically from now on, update your ${chalk.green('`.env`')} file:`,\n );\n const picked = potentialEnvs[envType];\n const rest = { ...potentialEnvs };\n delete rest[envType];\n console.log(` ${chalk.green(picked)}=${appId}`);\n const otherEnvs = Object.values(rest);\n otherEnvs.sort();\n const otherEnvStr = otherEnvs.map((x) => ' ' + chalk.green(x)).join('\\n');\n console.log(`Alternative names: \\n${otherEnvStr} \\n`);\n console.log(terminalLink('Dashboard:', appDashUrl(appId, dashOrigin)) + '\\n');\n}\n\nfunction appDashUrl(id: string, instantOrigin: string) {\n return `${instantOrigin}/dash?s=main&t=home&app=${id}`;\n}\n"]}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { HttpClient } from '@effect/platform';
|
|
2
|
+
import { Context, Effect, Layer, Schema } from 'effect';
|
|
3
|
+
import { AuthToken } from '../context/authToken.ts';
|
|
4
|
+
import { TimeoutException } from 'effect/Cause';
|
|
5
|
+
import { RequestError } from '@effect/platform/HttpClientError';
|
|
6
|
+
declare const InstantHttp_base: Context.TagClass<InstantHttp, "instant-cli/new/lib/http/InstantHttp", HttpClient.HttpClient.With<InstantHttpError | TimeoutException | RequestError, never>>;
|
|
7
|
+
export declare class InstantHttp extends InstantHttp_base {
|
|
8
|
+
}
|
|
9
|
+
declare const InstantHttpAuthed_base: Context.TagClass<InstantHttpAuthed, "instant-cli/new/lib/http/InstantHttpAuthed", HttpClient.HttpClient.With<InstantHttpError | TimeoutException | RequestError, never>>;
|
|
10
|
+
export declare class InstantHttpAuthed extends InstantHttpAuthed_base {
|
|
11
|
+
}
|
|
12
|
+
declare const InstantHttpError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => import("effect/Cause").YieldableError & {
|
|
13
|
+
readonly _tag: "InstantHttpError";
|
|
14
|
+
} & Readonly<A>;
|
|
15
|
+
export declare class InstantHttpError extends InstantHttpError_base<{
|
|
16
|
+
methodAndUrl: string;
|
|
17
|
+
} & typeof InstantTypicalHttpErrorResponse.Type> {
|
|
18
|
+
}
|
|
19
|
+
export declare const withCommand: (command: string) => (client: HttpClient.HttpClient.With<InstantHttpError | TimeoutException | RequestError>) => HttpClient.HttpClient.With<InstantHttpError | TimeoutException | RequestError, never>;
|
|
20
|
+
declare const InstantTypicalHttpErrorResponse_base: Schema.Struct<{
|
|
21
|
+
message: typeof Schema.String;
|
|
22
|
+
type: Schema.optional<typeof Schema.String>;
|
|
23
|
+
hint: Schema.optional<Schema.Record$<typeof Schema.String, typeof Schema.Any>>;
|
|
24
|
+
}>;
|
|
25
|
+
declare class InstantTypicalHttpErrorResponse extends InstantTypicalHttpErrorResponse_base {
|
|
26
|
+
}
|
|
27
|
+
export declare const InstantHttpLive: Layer.Layer<InstantHttp, import("effect/ConfigError").ConfigError, HttpClient.HttpClient>;
|
|
28
|
+
export declare const InstantHttpAuthedLive: Layer.Layer<InstantHttpAuthed, never, InstantHttp | AuthToken>;
|
|
29
|
+
export declare const getBaseUrl: Effect.Effect<string, import("effect/ConfigError").ConfigError, never>;
|
|
30
|
+
export declare const getDashUrl: Effect.Effect<"http://localhost:3000" | "https://instantdb.com", import("effect/ConfigError").ConfigError, never>;
|
|
31
|
+
export {};
|
|
32
|
+
//# sourceMappingURL=http.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/lib/http.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAqB,MAAM,kBAAkB,CAAC;AAEjE,OAAO,EAAU,OAAO,EAAQ,MAAM,EAAE,KAAK,EAAU,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9E,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;;AAEhE,qBAAa,WAAY,SAAQ,gBAK9B;CAAG;;AAEN,qBAAa,iBAAkB,SAAQ,sBAKpC;CAAG;;;;AAEN,qBAAa,gBAAiB,SAAQ,sBACpC;IACE,YAAY,EAAE,MAAM,CAAC;CACtB,GAAG,OAAO,+BAA+B,CAAC,IAAI,CAChD;CAAG;AAGJ,eAAO,MAAM,WAAW,GAAI,SAAS,MAAM,MAEvC,QAAQ,UAAU,CAAC,UAAU,CAAC,IAAI,CAChC,gBAAgB,GAAG,gBAAgB,GAAG,YAAY,CACnD,0FAOJ,CAAC;;;;;;AAEF,cAAM,+BAAgC,SAAQ,oCAM5C;CAAG;AAEL,eAAO,MAAM,eAAe,2FAwD3B,CAAC;AAEF,eAAO,MAAM,qBAAqB,gEAiBjC,CAAC;AAEF,eAAO,MAAM,UAAU,wEAcrB,CAAC;AAEH,eAAO,MAAM,UAAU,mHAKrB,CAAC"}
|
package/dist/lib/http.js
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { HttpClient, HttpClientRequest } from '@effect/platform';
|
|
2
|
+
import { version } from '@instantdb/version';
|
|
3
|
+
import { Config, Context, Data, Effect, Layer, Option, Schema } from 'effect';
|
|
4
|
+
import { AuthToken } from "../context/authToken.js";
|
|
5
|
+
import { TimeoutException } from 'effect/Cause';
|
|
6
|
+
import { RequestError } from '@effect/platform/HttpClientError';
|
|
7
|
+
export class InstantHttp extends Context.Tag('instant-cli/new/lib/http/InstantHttp')() {
|
|
8
|
+
}
|
|
9
|
+
export class InstantHttpAuthed extends Context.Tag('instant-cli/new/lib/http/InstantHttpAuthed')() {
|
|
10
|
+
}
|
|
11
|
+
export class InstantHttpError extends Data.TaggedError('InstantHttpError') {
|
|
12
|
+
}
|
|
13
|
+
// Pipe on an http client to set the command header
|
|
14
|
+
export const withCommand = (command) => {
|
|
15
|
+
return (client) => client.pipe(HttpClient.mapRequest((r) => r.pipe(HttpClientRequest.setHeader(`X-Instant-Command`, command))));
|
|
16
|
+
};
|
|
17
|
+
class InstantTypicalHttpErrorResponse extends Schema.Struct({
|
|
18
|
+
message: Schema.String,
|
|
19
|
+
type: Schema.String.pipe(Schema.optional),
|
|
20
|
+
hint: Schema.Record({ key: Schema.String, value: Schema.Any }).pipe(Schema.optional),
|
|
21
|
+
}) {
|
|
22
|
+
}
|
|
23
|
+
export const InstantHttpLive = Layer.effect(InstantHttp, Effect.gen(function* () {
|
|
24
|
+
const client = yield* HttpClient.HttpClient;
|
|
25
|
+
const baseUrl = yield* getBaseUrl;
|
|
26
|
+
return client.pipe(HttpClient.mapRequest((r) => r.pipe(HttpClientRequest.prependUrl(baseUrl), HttpClientRequest.setHeader('X-Instant-Source', 'instant-cli'), HttpClientRequest.setHeader('X-Instant-Version', version))), HttpClient.transformResponse((r) => r.pipe(Effect.timeout('5 minutes'))), HttpClient.filterStatusOk, // makes non 2xx http codes error
|
|
27
|
+
// parses the non 2xx errors into known instant error shape
|
|
28
|
+
HttpClient.transformResponse((r) => r.pipe(Effect.catchTag('ResponseError', (requestError) => Effect.gen(function* () {
|
|
29
|
+
const jsonBody = yield* requestError.response.json.pipe(Effect.andThen(Schema.decodeUnknown(InstantTypicalHttpErrorResponse)), Effect.mapError((e) => new InstantHttpError({
|
|
30
|
+
message: 'Error making request to ' + requestError.methodAndUrl,
|
|
31
|
+
type: e._tag,
|
|
32
|
+
methodAndUrl: requestError.methodAndUrl,
|
|
33
|
+
})));
|
|
34
|
+
// The hint.message is usually better error message
|
|
35
|
+
let message = jsonBody.message;
|
|
36
|
+
if (jsonBody.hint?.message &&
|
|
37
|
+
typeof jsonBody.hint.message === 'string') {
|
|
38
|
+
message = jsonBody.hint.message;
|
|
39
|
+
}
|
|
40
|
+
return yield* new InstantHttpError({
|
|
41
|
+
message: message,
|
|
42
|
+
methodAndUrl: requestError.methodAndUrl,
|
|
43
|
+
hint: jsonBody.hint,
|
|
44
|
+
type: jsonBody.type || 'Unknown type',
|
|
45
|
+
});
|
|
46
|
+
})))));
|
|
47
|
+
}));
|
|
48
|
+
export const InstantHttpAuthedLive = Layer.effect(InstantHttpAuthed, Effect.gen(function* () {
|
|
49
|
+
const http = yield* InstantHttp;
|
|
50
|
+
const authToken = yield* AuthToken;
|
|
51
|
+
return http.pipe(HttpClient.mapRequestEffect((r) => authToken.getAuthToken.pipe(Effect.map((token) => r.pipe(HttpClientRequest.setHeader('Authorization', `Bearer ${token}`))))));
|
|
52
|
+
}));
|
|
53
|
+
export const getBaseUrl = Effect.gen(function* () {
|
|
54
|
+
const setEnv = yield* Config.string('INSTANT_CLI_API_URI').pipe(Config.option);
|
|
55
|
+
const dev = yield* Config.boolean('INSTANT_CLI_DEV').pipe(Config.withDefault(false));
|
|
56
|
+
return Option.match(setEnv, {
|
|
57
|
+
onSome: (url) => url,
|
|
58
|
+
onNone: () => {
|
|
59
|
+
return dev ? 'http://localhost:8888' : 'https://api.instantdb.com';
|
|
60
|
+
},
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
export const getDashUrl = Effect.gen(function* () {
|
|
64
|
+
const dev = Option.getOrNull(yield* Config.boolean('INSTANT_CLI_DEV').pipe(Config.option));
|
|
65
|
+
return dev ? 'http://localhost:3000' : 'https://instantdb.com';
|
|
66
|
+
});
|
|
67
|
+
//# sourceMappingURL=http.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../../src/lib/http.ts"],"names":[],"mappings":"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","sourcesContent":["import { HttpClient, HttpClientRequest } from '@effect/platform';\nimport { version } from '@instantdb/version';\nimport { Config, Context, Data, Effect, Layer, Option, Schema } from 'effect';\nimport { AuthToken } from '../context/authToken.ts';\nimport { TimeoutException } from 'effect/Cause';\nimport { RequestError } from '@effect/platform/HttpClientError';\n\nexport class InstantHttp extends Context.Tag(\n 'instant-cli/new/lib/http/InstantHttp',\n)<\n InstantHttp,\n HttpClient.HttpClient.With<InstantHttpError | TimeoutException | RequestError>\n>() {}\n\nexport class InstantHttpAuthed extends Context.Tag(\n 'instant-cli/new/lib/http/InstantHttpAuthed',\n)<\n InstantHttpAuthed,\n HttpClient.HttpClient.With<InstantHttpError | TimeoutException | RequestError>\n>() {}\n\nexport class InstantHttpError extends Data.TaggedError('InstantHttpError')<\n {\n methodAndUrl: string;\n } & typeof InstantTypicalHttpErrorResponse.Type\n> {}\n\n// Pipe on an http client to set the command header\nexport const withCommand = (command: string) => {\n return (\n client: HttpClient.HttpClient.With<\n InstantHttpError | TimeoutException | RequestError\n >,\n ) =>\n client.pipe(\n HttpClient.mapRequest((r) =>\n r.pipe(HttpClientRequest.setHeader(`X-Instant-Command`, command)),\n ),\n );\n};\n\nclass InstantTypicalHttpErrorResponse extends Schema.Struct({\n message: Schema.String,\n type: Schema.String.pipe(Schema.optional),\n hint: Schema.Record({ key: Schema.String, value: Schema.Any }).pipe(\n Schema.optional,\n ),\n}) {}\n\nexport const InstantHttpLive = Layer.effect(\n InstantHttp,\n Effect.gen(function* () {\n const client = yield* HttpClient.HttpClient;\n const baseUrl = yield* getBaseUrl;\n return client.pipe(\n HttpClient.mapRequest((r) =>\n r.pipe(\n HttpClientRequest.prependUrl(baseUrl),\n HttpClientRequest.setHeader('X-Instant-Source', 'instant-cli'),\n HttpClientRequest.setHeader('X-Instant-Version', version),\n ),\n ),\n HttpClient.transformResponse((r) => r.pipe(Effect.timeout('5 minutes'))),\n HttpClient.filterStatusOk, // makes non 2xx http codes error\n // parses the non 2xx errors into known instant error shape\n HttpClient.transformResponse((r) =>\n r.pipe(\n Effect.catchTag('ResponseError', (requestError) =>\n Effect.gen(function* () {\n const jsonBody = yield* requestError.response.json.pipe(\n Effect.andThen(\n Schema.decodeUnknown(InstantTypicalHttpErrorResponse),\n ),\n Effect.mapError(\n (e) =>\n new InstantHttpError({\n message:\n 'Error making request to ' + requestError.methodAndUrl,\n type: e._tag,\n methodAndUrl: requestError.methodAndUrl,\n }),\n ),\n );\n\n // The hint.message is usually better error message\n let message = jsonBody.message;\n if (\n jsonBody.hint?.message &&\n typeof jsonBody.hint.message === 'string'\n ) {\n message = jsonBody.hint.message;\n }\n\n return yield* new InstantHttpError({\n message: message,\n methodAndUrl: requestError.methodAndUrl,\n hint: jsonBody.hint,\n type: jsonBody.type || 'Unknown type',\n });\n }),\n ),\n ),\n ),\n );\n }),\n);\n\nexport const InstantHttpAuthedLive = Layer.effect(\n InstantHttpAuthed,\n Effect.gen(function* () {\n const http = yield* InstantHttp;\n const authToken = yield* AuthToken;\n return http.pipe(\n HttpClient.mapRequestEffect((r) =>\n authToken.getAuthToken.pipe(\n Effect.map((token) =>\n r.pipe(\n HttpClientRequest.setHeader('Authorization', `Bearer ${token}`),\n ),\n ),\n ),\n ),\n );\n }),\n);\n\nexport const getBaseUrl = Effect.gen(function* () {\n const setEnv = yield* Config.string('INSTANT_CLI_API_URI').pipe(\n Config.option,\n );\n const dev = yield* Config.boolean('INSTANT_CLI_DEV').pipe(\n Config.withDefault(false),\n );\n\n return Option.match(setEnv, {\n onSome: (url) => url,\n onNone: () => {\n return dev ? 'http://localhost:8888' : 'https://api.instantdb.com';\n },\n });\n});\n\nexport const getDashUrl = Effect.gen(function* () {\n const dev = Option.getOrNull(\n yield* Config.boolean('INSTANT_CLI_DEV').pipe(Config.option),\n );\n return dev ? 'http://localhost:3000' : 'https://instantdb.com';\n});\n"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Effect } from 'effect';
|
|
2
|
+
import { InstantHttp } from './http.ts';
|
|
3
|
+
import { FileSystem } from '@effect/platform';
|
|
4
|
+
export declare const getLoginTicketAndSecret: Effect.Effect<{
|
|
5
|
+
readonly secret: string;
|
|
6
|
+
readonly ticket: string;
|
|
7
|
+
}, import("./http.ts").InstantHttpError | import("effect/Cause").TimeoutException | import("@effect/platform/HttpClientError").RequestError | import("effect/ParseResult").ParseError | import("@effect/platform/HttpClientError").ResponseError, InstantHttp>;
|
|
8
|
+
export declare const waitForAuthToken: (secret: string) => Effect.Effect<{
|
|
9
|
+
readonly token: string;
|
|
10
|
+
readonly email: string;
|
|
11
|
+
}, import("./http.ts").InstantHttpError | import("effect/Cause").TimeoutException | import("@effect/platform/HttpClientError").RequestError | import("effect/ParseResult").ParseError | import("@effect/platform/HttpClientError").ResponseError, InstantHttp>;
|
|
12
|
+
export declare const saveConfigAuthToken: (token: string) => Effect.Effect<void, import("@effect/platform/Error").PlatformError, FileSystem.FileSystem>;
|
|
13
|
+
//# sourceMappingURL=login.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../src/lib/login.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAoB,MAAM,QAAQ,CAAC;AAClD,OAAO,EAAE,WAAW,EAAe,MAAM,WAAW,CAAC;AACrD,OAAO,EAGL,UAAU,EACX,MAAM,kBAAkB,CAAC;AAa1B,eAAO,MAAM,uBAAuB;;;8PAOlC,CAAC;AAEH,eAAO,MAAM,gBAAgB;;;8PAiB3B,CAAC;AAEH,eAAO,MAAM,mBAAmB,+GAM9B,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { Effect, Schedule, Schema } from 'effect';
|
|
2
|
+
import { InstantHttp, withCommand } from "./http.js";
|
|
3
|
+
import { HttpClientRequest, HttpClientResponse, FileSystem, } from '@effect/platform';
|
|
4
|
+
import { getAuthPaths } from "../util/getAuthPaths.js";
|
|
5
|
+
const LoginInfo = Schema.Struct({
|
|
6
|
+
secret: Schema.String,
|
|
7
|
+
ticket: Schema.String,
|
|
8
|
+
});
|
|
9
|
+
const TokenResult = Schema.Struct({
|
|
10
|
+
token: Schema.String,
|
|
11
|
+
email: Schema.String,
|
|
12
|
+
});
|
|
13
|
+
export const getLoginTicketAndSecret = Effect.gen(function* () {
|
|
14
|
+
const http = yield* InstantHttp;
|
|
15
|
+
const res = yield* http
|
|
16
|
+
.pipe(withCommand('login'))
|
|
17
|
+
.post('/dash/cli/auth/register')
|
|
18
|
+
.pipe(Effect.flatMap(HttpClientResponse.schemaBodyJson(LoginInfo)));
|
|
19
|
+
return res;
|
|
20
|
+
});
|
|
21
|
+
export const waitForAuthToken = Effect.fn(function* (secret) {
|
|
22
|
+
const http = (yield* InstantHttp).pipe(withCommand('login'));
|
|
23
|
+
const res = yield* HttpClientRequest.post('/dash/cli/auth/check').pipe(HttpClientRequest.bodyUnsafeJson({
|
|
24
|
+
secret,
|
|
25
|
+
}), http.execute, Effect.flatMap(HttpClientResponse.schemaBodyJson(TokenResult)), Effect.retry({
|
|
26
|
+
while: (e) => e._tag === 'InstantHttpError' &&
|
|
27
|
+
e.hint?.errors?.at(0)?.issue === 'waiting-for-user',
|
|
28
|
+
schedule: Schedule.fixed('1 seconds'),
|
|
29
|
+
times: 120,
|
|
30
|
+
}));
|
|
31
|
+
return res;
|
|
32
|
+
});
|
|
33
|
+
export const saveConfigAuthToken = Effect.fn(function* (token) {
|
|
34
|
+
const authPaths = getAuthPaths();
|
|
35
|
+
const fs = yield* FileSystem.FileSystem;
|
|
36
|
+
yield* fs.makeDirectory(authPaths.appConfigDirPath, { recursive: true });
|
|
37
|
+
yield* fs.writeFileString(authPaths.authConfigFilePath, token);
|
|
38
|
+
});
|
|
39
|
+
//# sourceMappingURL=login.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/lib/login.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACrD,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,UAAU,GACX,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAEvD,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC;IAC9B,MAAM,EAAE,MAAM,CAAC,MAAM;IACrB,MAAM,EAAE,MAAM,CAAC,MAAM;CACtB,CAAC,CAAC;AAEH,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC;IAChC,KAAK,EAAE,MAAM,CAAC,MAAM;IACpB,KAAK,EAAE,MAAM,CAAC,MAAM;CACrB,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,uBAAuB,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IACzD,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,WAAW,CAAC;IAChC,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,IAAI;SACpB,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;SAC1B,IAAI,CAAC,yBAAyB,CAAC;SAC/B,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,kBAAkB,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;IACtE,OAAO,GAAG,CAAC;AACb,CAAC,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,gBAAgB,GAAG,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,MAAc;IACjE,MAAM,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC;IAC7D,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC,IAAI,CACpE,iBAAiB,CAAC,cAAc,CAAC;QAC/B,MAAM;KACP,CAAC,EACF,IAAI,CAAC,OAAO,EACZ,MAAM,CAAC,OAAO,CAAC,kBAAkB,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC,EAC9D,MAAM,CAAC,KAAK,CAAC;QACX,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CACX,CAAC,CAAC,IAAI,KAAK,kBAAkB;YAC7B,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,KAAK,kBAAkB;QACrD,QAAQ,EAAE,QAAQ,CAAC,KAAK,CAAC,WAAW,CAAC;QACrC,KAAK,EAAE,GAAG;KACX,CAAC,CACH,CAAC;IACF,OAAO,GAAG,CAAC;AACb,CAAC,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,mBAAmB,GAAG,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,KAAa;IACnE,MAAM,SAAS,GAAG,YAAY,EAAE,CAAC;IAEjC,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC;IACxC,KAAK,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC,SAAS,CAAC,gBAAgB,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACzE,KAAK,CAAC,CAAC,EAAE,CAAC,eAAe,CAAC,SAAS,CAAC,kBAAkB,EAAE,KAAK,CAAC,CAAC;AACjE,CAAC,CAAC,CAAC","sourcesContent":["import { Effect, Schedule, Schema } from 'effect';\nimport { InstantHttp, withCommand } from './http.ts';\nimport {\n HttpClientRequest,\n HttpClientResponse,\n FileSystem,\n} from '@effect/platform';\nimport { getAuthPaths } from '../util/getAuthPaths.ts';\n\nconst LoginInfo = Schema.Struct({\n secret: Schema.String,\n ticket: Schema.String,\n});\n\nconst TokenResult = Schema.Struct({\n token: Schema.String,\n email: Schema.String,\n});\n\nexport const getLoginTicketAndSecret = Effect.gen(function* () {\n const http = yield* InstantHttp;\n const res = yield* http\n .pipe(withCommand('login'))\n .post('/dash/cli/auth/register')\n .pipe(Effect.flatMap(HttpClientResponse.schemaBodyJson(LoginInfo)));\n return res;\n});\n\nexport const waitForAuthToken = Effect.fn(function* (secret: string) {\n const http = (yield* InstantHttp).pipe(withCommand('login'));\n const res = yield* HttpClientRequest.post('/dash/cli/auth/check').pipe(\n HttpClientRequest.bodyUnsafeJson({\n secret,\n }),\n http.execute,\n Effect.flatMap(HttpClientResponse.schemaBodyJson(TokenResult)),\n Effect.retry({\n while: (e) =>\n e._tag === 'InstantHttpError' &&\n e.hint?.errors?.at(0)?.issue === 'waiting-for-user',\n schedule: Schedule.fixed('1 seconds'),\n times: 120,\n }),\n );\n return res;\n});\n\nexport const saveConfigAuthToken = Effect.fn(function* (token: string) {\n const authPaths = getAuthPaths();\n\n const fs = yield* FileSystem.FileSystem;\n yield* fs.makeDirectory(authPaths.appConfigDirPath, { recursive: true });\n yield* fs.writeFileString(authPaths.authConfigFilePath, token);\n});\n"]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Effect } from 'effect';
|
|
2
|
+
import { CurrentApp } from '../context/currentApp.ts';
|
|
3
|
+
import { InstantHttpAuthed } from './http.ts';
|
|
4
|
+
import { ProjectInfo } from '../context/projectInfo.ts';
|
|
5
|
+
import { Path } from '@effect/platform';
|
|
6
|
+
export declare const pullPerms: Effect.Effect<void, import("effect/Cause").UnknownException | import("./http.ts").InstantHttpError | import("effect/Cause").TimeoutException | import("@effect/platform/HttpClientError").RequestError | import("effect/ParseResult").ParseError | import("@effect/platform/HttpClientError").ResponseError | import("@effect/platform/Error").PlatformError, import("../context/globalOpts.ts").GlobalOpts | ProjectInfo | import("@effect/platform/FileSystem").FileSystem | InstantHttpAuthed | Path.Path | CurrentApp>;
|
|
7
|
+
//# sourceMappingURL=pullPerms.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pullPerms.d.ts","sourceRoot":"","sources":["../../src/lib/pullPerms.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAkB,MAAM,QAAQ,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAe,MAAM,WAAW,CAAC;AAQ3D,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAExC,eAAO,MAAM,SAAS,4fAoCpB,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { Effect, Option, Schema } from 'effect';
|
|
2
|
+
import { CurrentApp } from "../context/currentApp.js";
|
|
3
|
+
import { InstantHttpAuthed, withCommand } from "./http.js";
|
|
4
|
+
import { HttpClientResponse } from '@effect/platform';
|
|
5
|
+
import { readLocalPermsFile } from '../old.js';
|
|
6
|
+
import { getPermsPathToWrite } from "../util/findConfigCandidates.js";
|
|
7
|
+
import { promptOk } from "./ui.js";
|
|
8
|
+
import { UI } from "../ui/index.js";
|
|
9
|
+
import { writeTypescript } from "./pullSchema.js";
|
|
10
|
+
import { generatePermsTypescriptFile } from '@instantdb/platform';
|
|
11
|
+
import { ProjectInfo } from "../context/projectInfo.js";
|
|
12
|
+
import { Path } from '@effect/platform';
|
|
13
|
+
export const pullPerms = Effect.gen(function* () {
|
|
14
|
+
yield* Effect.log('\nPulling perms...');
|
|
15
|
+
const { appId } = yield* CurrentApp;
|
|
16
|
+
const http = yield* InstantHttpAuthed;
|
|
17
|
+
const permsResponse = yield* http
|
|
18
|
+
.pipe(withCommand('pull'))
|
|
19
|
+
.get(`/dash/apps/${appId}/perms/pull`)
|
|
20
|
+
.pipe(Effect.flatMap(HttpClientResponse.schemaBodyJson(Schema.Any))); // parse result body into "any"
|
|
21
|
+
const prevPermsFile = yield* Effect.tryPromise(readLocalPermsFile).pipe(Effect.map(Option.fromNullable));
|
|
22
|
+
const shortPermsPath = Option.match(prevPermsFile, {
|
|
23
|
+
onSome: (file) => file.path,
|
|
24
|
+
onNone: () => getPermsPathToWrite(),
|
|
25
|
+
});
|
|
26
|
+
if (Option.isSome(prevPermsFile)) {
|
|
27
|
+
const shouldContinue = yield* promptOk({
|
|
28
|
+
promptText: `This will overwrite your local ${shortPermsPath} file, OK to proceed?`,
|
|
29
|
+
modifyOutput: UI.modifiers.yPadding,
|
|
30
|
+
inline: true,
|
|
31
|
+
});
|
|
32
|
+
if (!shouldContinue)
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
const { instantModuleName, pkgDir } = yield* ProjectInfo;
|
|
36
|
+
const fileContent = generatePermsTypescriptFile(permsResponse?.perms || {}, instantModuleName);
|
|
37
|
+
const path = yield* Path.Path;
|
|
38
|
+
yield* writeTypescript(path.join(pkgDir, shortPermsPath), fileContent);
|
|
39
|
+
yield* Effect.log('✅ Wrote permissions to ' + shortPermsPath);
|
|
40
|
+
});
|
|
41
|
+
//# sourceMappingURL=pullPerms.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pullPerms.js","sourceRoot":"","sources":["../../src/lib/pullPerms.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AACtE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,EAAE,EAAE,MAAM,gBAAgB,CAAC;AACpC,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAC;AAClE,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAExC,MAAM,CAAC,MAAM,SAAS,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAC3C,KAAK,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;IACxC,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,CAAC,CAAC,UAAU,CAAC;IACpC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,iBAAiB,CAAC;IACtC,MAAM,aAAa,GAAG,KAAK,CAAC,CAAC,IAAI;SAC9B,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;SACzB,GAAG,CAAC,cAAc,KAAK,aAAa,CAAC;SACrC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,kBAAkB,CAAC,cAAc,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,+BAA+B;IAEvG,MAAM,aAAa,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,kBAAkB,CAAC,CAAC,IAAI,CACrE,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,YAAY,CAAC,CAChC,CAAC;IAEF,MAAM,cAAc,GAAG,MAAM,CAAC,KAAK,CAAC,aAAa,EAAE;QACjD,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI;QAC3B,MAAM,EAAE,GAAG,EAAE,CAAC,mBAAmB,EAAE;KACpC,CAAC,CAAC;IAEH,IAAI,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,CAAC;QACjC,MAAM,cAAc,GAAG,KAAK,CAAC,CAAC,QAAQ,CAAC;YACrC,UAAU,EAAE,kCAAkC,cAAc,uBAAuB;YACnF,YAAY,EAAE,EAAE,CAAC,SAAS,CAAC,QAAQ;YACnC,MAAM,EAAE,IAAI;SACb,CAAC,CAAC;QACH,IAAI,CAAC,cAAc;YAAE,OAAO;IAC9B,CAAC;IACD,MAAM,EAAE,iBAAiB,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,WAAW,CAAC;IACzD,MAAM,WAAW,GAAG,2BAA2B,CAC7C,aAAa,EAAE,KAAK,IAAI,EAAE,EAC1B,iBAAiB,CAClB,CAAC;IAEF,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;IAE9B,KAAK,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,cAAc,CAAC,EAAE,WAAW,CAAC,CAAC;IACvE,KAAK,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,yBAAyB,GAAG,cAAc,CAAC,CAAC;AAChE,CAAC,CAAC,CAAC","sourcesContent":["import { Effect, Option, Schema } from 'effect';\nimport { CurrentApp } from '../context/currentApp.ts';\nimport { InstantHttpAuthed, withCommand } from './http.ts';\nimport { HttpClientResponse } from '@effect/platform';\nimport { readLocalPermsFile } from '../old.js';\nimport { getPermsPathToWrite } from '../util/findConfigCandidates.ts';\nimport { promptOk } from './ui.ts';\nimport { UI } from '../ui/index.ts';\nimport { writeTypescript } from './pullSchema.ts';\nimport { generatePermsTypescriptFile } from '@instantdb/platform';\nimport { ProjectInfo } from '../context/projectInfo.ts';\nimport { Path } from '@effect/platform';\n\nexport const pullPerms = Effect.gen(function* () {\n yield* Effect.log('\\nPulling perms...');\n const { appId } = yield* CurrentApp;\n const http = yield* InstantHttpAuthed;\n const permsResponse = yield* http\n .pipe(withCommand('pull'))\n .get(`/dash/apps/${appId}/perms/pull`)\n .pipe(Effect.flatMap(HttpClientResponse.schemaBodyJson(Schema.Any))); // parse result body into \"any\"\n\n const prevPermsFile = yield* Effect.tryPromise(readLocalPermsFile).pipe(\n Effect.map(Option.fromNullable),\n );\n\n const shortPermsPath = Option.match(prevPermsFile, {\n onSome: (file) => file.path,\n onNone: () => getPermsPathToWrite(),\n });\n\n if (Option.isSome(prevPermsFile)) {\n const shouldContinue = yield* promptOk({\n promptText: `This will overwrite your local ${shortPermsPath} file, OK to proceed?`,\n modifyOutput: UI.modifiers.yPadding,\n inline: true,\n });\n if (!shouldContinue) return;\n }\n const { instantModuleName, pkgDir } = yield* ProjectInfo;\n const fileContent = generatePermsTypescriptFile(\n permsResponse?.perms || {},\n instantModuleName,\n );\n\n const path = yield* Path.Path;\n\n yield* writeTypescript(path.join(pkgDir, shortPermsPath), fileContent);\n yield* Effect.log('✅ Wrote permissions to ' + shortPermsPath);\n});\n"]}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { FileSystem, Path } from '@effect/platform';
|
|
2
|
+
import { Effect } from 'effect';
|
|
3
|
+
import { CurrentApp } from '../context/currentApp.ts';
|
|
4
|
+
import { ProjectInfo } from '../context/projectInfo.ts';
|
|
5
|
+
import { InstantHttpAuthed } from './http.ts';
|
|
6
|
+
import { ReadSchemaFileError } from './pushSchema.ts';
|
|
7
|
+
import { MergeSchemaError } from '../util/mergeSchema.ts';
|
|
8
|
+
export declare const pullSchema: ({ experimentalTypePreservation, }: {
|
|
9
|
+
experimentalTypePreservation?: boolean;
|
|
10
|
+
}) => Effect.Effect<void, import("effect/Cause").UnknownException | import("./http.ts").InstantHttpError | import("effect/Cause").TimeoutException | import("@effect/platform/HttpClientError").RequestError | import("effect/ParseResult").ParseError | import("@effect/platform/HttpClientError").ResponseError | import("@effect/platform/Error").PlatformError | ReadSchemaFileError | MergeSchemaError, import("../context/globalOpts.ts").GlobalOpts | ProjectInfo | FileSystem.FileSystem | InstantHttpAuthed | Path.Path | CurrentApp>;
|
|
11
|
+
export declare const writeTypescript: (path: string, content: string) => Effect.Effect<void, import("effect/Cause").UnknownException | import("@effect/platform/Error").PlatformError, FileSystem.FileSystem>;
|
|
12
|
+
//# sourceMappingURL=pullSchema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pullSchema.d.ts","sourceRoot":"","sources":["../../src/lib/pullSchema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAsB,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAKxE,OAAO,EAAE,MAAM,EAAU,MAAM,QAAQ,CAAC;AAKxC,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAe,MAAM,WAAW,CAAC;AAE3D,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAAe,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAEvE,eAAO,MAAM,UAAU,GAAI,mCAExB;IACD,4BAA4B,CAAC,EAAE,OAAO,CAAC;CACxC,6gBA0DG,CAAC;AAEL,eAAO,MAAM,eAAe,GAAI,MAAM,MAAM,EAAE,SAAS,MAAM,yIAazD,CAAC"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { FileSystem, HttpClientResponse, Path } from '@effect/platform';
|
|
2
|
+
import { apiSchemaToInstantSchemaDef, generateSchemaTypescriptFile, } from '@instantdb/platform';
|
|
3
|
+
import { Effect, Schema } from 'effect';
|
|
4
|
+
import prettier from 'prettier';
|
|
5
|
+
import { countEntities, readLocalSchemaFile } from '../old.js';
|
|
6
|
+
import { UI } from "../ui/index.js";
|
|
7
|
+
import { getSchemaPathToWrite } from "../util/findConfigCandidates.js";
|
|
8
|
+
import { CurrentApp } from "../context/currentApp.js";
|
|
9
|
+
import { ProjectInfo } from "../context/projectInfo.js";
|
|
10
|
+
import { InstantHttpAuthed, withCommand } from "./http.js";
|
|
11
|
+
import { promptOk } from "./ui.js";
|
|
12
|
+
import { ReadSchemaFileError } from "./pushSchema.js";
|
|
13
|
+
import { mergeSchema, MergeSchemaError } from "../util/mergeSchema.js";
|
|
14
|
+
export const pullSchema = ({ experimentalTypePreservation, }) => Effect.gen(function* () {
|
|
15
|
+
yield* Effect.log('Pulling schema...');
|
|
16
|
+
const { appId } = yield* CurrentApp;
|
|
17
|
+
const http = yield* InstantHttpAuthed;
|
|
18
|
+
const schemaResponse = yield* http
|
|
19
|
+
.pipe(withCommand('pull'))
|
|
20
|
+
.get(`/dash/apps/${appId}/schema/pull`)
|
|
21
|
+
.pipe(Effect.flatMap(HttpClientResponse.schemaBodyJson(Schema.Any))); // parse result body into "any"
|
|
22
|
+
if (!countEntities(schemaResponse.schema.refs) &&
|
|
23
|
+
!countEntities(schemaResponse.schema.blobs)) {
|
|
24
|
+
yield* Effect.log('Schema is empty. Skipping.');
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
const prevSchemaFile = yield* Effect.tryPromise(readLocalSchemaFile).pipe(Effect.mapError((err) => ReadSchemaFileError.make({
|
|
28
|
+
message: `Error reading local schema file: ${err}`,
|
|
29
|
+
cause: err,
|
|
30
|
+
})));
|
|
31
|
+
const shortSchemaPath = getSchemaPathToWrite(prevSchemaFile?.path);
|
|
32
|
+
const path = yield* Path.Path;
|
|
33
|
+
const { pkgDir, instantModuleName } = yield* ProjectInfo;
|
|
34
|
+
const schemaPath = path.join(pkgDir, shortSchemaPath);
|
|
35
|
+
if (prevSchemaFile) {
|
|
36
|
+
const shouldContinue = yield* promptOk({
|
|
37
|
+
promptText: `This will overwrite your local ${shortSchemaPath} file, OK to proceed?`,
|
|
38
|
+
modifyOutput: UI.modifiers.yPadding,
|
|
39
|
+
inline: true,
|
|
40
|
+
});
|
|
41
|
+
if (!shouldContinue)
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
let newSchemaContent = generateSchemaTypescriptFile(prevSchemaFile?.schema, apiSchemaToInstantSchemaDef(schemaResponse.schema), instantModuleName);
|
|
45
|
+
if (prevSchemaFile && experimentalTypePreservation) {
|
|
46
|
+
const fs = yield* FileSystem.FileSystem;
|
|
47
|
+
const oldSchemaContent = yield* fs.readFileString(prevSchemaFile.path);
|
|
48
|
+
newSchemaContent = yield* Effect.try(() => mergeSchema(oldSchemaContent, newSchemaContent)).pipe(Effect.mapError((e) => new MergeSchemaError({ message: e.message })));
|
|
49
|
+
}
|
|
50
|
+
yield* writeTypescript(schemaPath, newSchemaContent);
|
|
51
|
+
yield* Effect.log('✅ Wrote schema to ' + shortSchemaPath);
|
|
52
|
+
});
|
|
53
|
+
export const writeTypescript = (path, content) => Effect.gen(function* () {
|
|
54
|
+
const prettierConfig = yield* Effect.tryPromise(() => prettier.resolveConfig(path));
|
|
55
|
+
const formattedCode = yield* Effect.tryPromise(() => prettier.format(content, {
|
|
56
|
+
...prettierConfig,
|
|
57
|
+
parser: 'typescript',
|
|
58
|
+
}));
|
|
59
|
+
const fs = yield* FileSystem.FileSystem;
|
|
60
|
+
yield* fs.writeFileString(path, formattedCode);
|
|
61
|
+
});
|
|
62
|
+
//# sourceMappingURL=pullSchema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pullSchema.js","sourceRoot":"","sources":["../../src/lib/pullSchema.ts"],"names":[],"mappings":"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","sourcesContent":["import { FileSystem, HttpClientResponse, Path } from '@effect/platform';\nimport {\n apiSchemaToInstantSchemaDef,\n generateSchemaTypescriptFile,\n} from '@instantdb/platform';\nimport { Effect, Schema } from 'effect';\nimport prettier from 'prettier';\nimport { countEntities, readLocalSchemaFile } from '../old.js';\nimport { UI } from '../ui/index.ts';\nimport { getSchemaPathToWrite } from '../util/findConfigCandidates.ts';\nimport { CurrentApp } from '../context/currentApp.ts';\nimport { ProjectInfo } from '../context/projectInfo.ts';\nimport { InstantHttpAuthed, withCommand } from './http.ts';\nimport { promptOk } from './ui.ts';\nimport { ReadSchemaFileError } from './pushSchema.ts';\nimport { mergeSchema, MergeSchemaError } from '../util/mergeSchema.ts';\n\nexport const pullSchema = ({\n experimentalTypePreservation,\n}: {\n experimentalTypePreservation?: boolean;\n}) =>\n Effect.gen(function* () {\n yield* Effect.log('Pulling schema...');\n const { appId } = yield* CurrentApp;\n const http = yield* InstantHttpAuthed;\n\n const schemaResponse = yield* http\n .pipe(withCommand('pull'))\n .get(`/dash/apps/${appId}/schema/pull`)\n .pipe(Effect.flatMap(HttpClientResponse.schemaBodyJson(Schema.Any))); // parse result body into \"any\"\n\n if (\n !countEntities(schemaResponse.schema.refs) &&\n !countEntities(schemaResponse.schema.blobs)\n ) {\n yield* Effect.log('Schema is empty. Skipping.');\n return;\n }\n\n const prevSchemaFile = yield* Effect.tryPromise(readLocalSchemaFile).pipe(\n Effect.mapError((err) =>\n ReadSchemaFileError.make({\n message: `Error reading local schema file: ${err}`,\n cause: err,\n }),\n ),\n );\n const shortSchemaPath = getSchemaPathToWrite(prevSchemaFile?.path);\n const path = yield* Path.Path;\n const { pkgDir, instantModuleName } = yield* ProjectInfo;\n const schemaPath = path.join(pkgDir, shortSchemaPath);\n\n if (prevSchemaFile) {\n const shouldContinue = yield* promptOk({\n promptText: `This will overwrite your local ${shortSchemaPath} file, OK to proceed?`,\n modifyOutput: UI.modifiers.yPadding,\n inline: true,\n });\n if (!shouldContinue) return;\n }\n\n let newSchemaContent = generateSchemaTypescriptFile(\n prevSchemaFile?.schema,\n apiSchemaToInstantSchemaDef(schemaResponse.schema),\n instantModuleName,\n );\n\n if (prevSchemaFile && experimentalTypePreservation) {\n const fs = yield* FileSystem.FileSystem;\n const oldSchemaContent = yield* fs.readFileString(prevSchemaFile.path);\n newSchemaContent = yield* Effect.try(() =>\n mergeSchema(oldSchemaContent, newSchemaContent),\n ).pipe(\n Effect.mapError((e) => new MergeSchemaError({ message: e.message })),\n );\n }\n yield* writeTypescript(schemaPath, newSchemaContent);\n yield* Effect.log('✅ Wrote schema to ' + shortSchemaPath);\n });\n\nexport const writeTypescript = (path: string, content: string) =>\n Effect.gen(function* () {\n const prettierConfig = yield* Effect.tryPromise(() =>\n prettier.resolveConfig(path),\n );\n const formattedCode = yield* Effect.tryPromise(() =>\n prettier.format(content, {\n ...prettierConfig,\n parser: 'typescript',\n }),\n );\n const fs = yield* FileSystem.FileSystem;\n yield* fs.writeFileString(path, formattedCode);\n });\n"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Effect, Schema } from 'effect';
|
|
2
|
+
import { InstantHttpAuthed } from './http.ts';
|
|
3
|
+
import { CurrentApp } from '../context/currentApp.ts';
|
|
4
|
+
declare const NoPermsFileError_base: Schema.TaggedErrorClass<NoPermsFileError, "NoPermsFileError", {
|
|
5
|
+
readonly _tag: Schema.tag<"NoPermsFileError">;
|
|
6
|
+
} & {
|
|
7
|
+
message: typeof Schema.String;
|
|
8
|
+
}>;
|
|
9
|
+
export declare class NoPermsFileError extends NoPermsFileError_base {
|
|
10
|
+
}
|
|
11
|
+
export declare const pushPerms: Effect.Effect<void, import("./http.ts").InstantHttpError | import("effect/Cause").TimeoutException | import("@effect/platform/HttpClientError").RequestError | import("effect/ParseResult").ParseError | import("@effect/platform/HttpClientError").ResponseError | import("@effect/platform/HttpBody").HttpBodyError | NoPermsFileError, import("../context/globalOpts.ts").GlobalOpts | InstantHttpAuthed | CurrentApp>;
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=pushPerms.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pushPerms.d.ts","sourceRoot":"","sources":["../../src/lib/pushPerms.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAU,MAAM,EAAE,MAAM,QAAQ,CAAC;AAGhD,OAAO,EAAE,iBAAiB,EAAe,MAAM,WAAW,CAAC;AAM3D,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;;;;;;AAKtD,qBAAa,gBAAiB,SAAQ,qBAIpC;CAAG;AAML,eAAO,MAAM,SAAS,2ZAuDpB,CAAC"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { Effect, Option, Schema } from 'effect';
|
|
2
|
+
import jsonDiff from 'json-diff';
|
|
3
|
+
import { readLocalPermsFile } from '../old.js';
|
|
4
|
+
import { InstantHttpAuthed, withCommand } from "./http.js";
|
|
5
|
+
import { HttpClient, HttpClientRequest, HttpClientResponse, } from '@effect/platform';
|
|
6
|
+
import { CurrentApp } from "../context/currentApp.js";
|
|
7
|
+
import { promptOk } from "./ui.js";
|
|
8
|
+
import boxen from 'boxen';
|
|
9
|
+
import chalk from 'chalk';
|
|
10
|
+
export class NoPermsFileError extends Schema.TaggedError('NoPermsFileError')('NoPermsFileError', {
|
|
11
|
+
message: Schema.String,
|
|
12
|
+
}) {
|
|
13
|
+
}
|
|
14
|
+
const PullPermsResponse = Schema.Struct({
|
|
15
|
+
perms: Schema.Any.pipe(Schema.optional),
|
|
16
|
+
});
|
|
17
|
+
export const pushPerms = Effect.gen(function* () {
|
|
18
|
+
yield* Effect.log('Planning perms...');
|
|
19
|
+
const { appId } = yield* CurrentApp;
|
|
20
|
+
const http = yield* InstantHttpAuthed;
|
|
21
|
+
const permsFile = yield* Effect.tryPromise(readLocalPermsFile).pipe(Effect.flatMap(Option.fromNullable), Effect.mapError(() => NoPermsFileError.make({
|
|
22
|
+
message: `We couldn't find your ${chalk.yellow('`instant.perms.ts`')} file. Make sure it's in the root directory. (Hint: You can use an INSTANT_PERMS_FILE_PATH environment variable to specify it.)`,
|
|
23
|
+
})));
|
|
24
|
+
const prodPerms = yield* http
|
|
25
|
+
.pipe(withCommand('push'))
|
|
26
|
+
.get(`/dash/apps/${appId}/perms/pull`)
|
|
27
|
+
.pipe(Effect.flatMap(HttpClientResponse.schemaBodyJson(PullPermsResponse))); // parse result body into "any"
|
|
28
|
+
const diffedStr = jsonDiff.diffString(prodPerms.perms || {}, permsFile.perms || {});
|
|
29
|
+
if (!diffedStr.length) {
|
|
30
|
+
yield* Effect.log('No perms changes detected. Skipping.');
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
const okPush = yield* promptOk({
|
|
34
|
+
promptText: 'Push these changes to your perms?',
|
|
35
|
+
modifyOutput: (output) => {
|
|
36
|
+
let both = diffedStr + '\n' + output;
|
|
37
|
+
return boxen(both, {
|
|
38
|
+
dimBorder: true,
|
|
39
|
+
padding: {
|
|
40
|
+
left: 1,
|
|
41
|
+
right: 1,
|
|
42
|
+
},
|
|
43
|
+
});
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
if (!okPush)
|
|
47
|
+
return;
|
|
48
|
+
yield* http
|
|
49
|
+
.pipe(withCommand('push'), HttpClient.mapRequestInputEffect(HttpClientRequest.bodyJson({ code: permsFile.perms })))
|
|
50
|
+
.post(`/dash/apps/${appId}/rules`)
|
|
51
|
+
.pipe(Effect.flatMap(HttpClientResponse.schemaBodyJson(Schema.Any)));
|
|
52
|
+
yield* Effect.log(chalk.green('Permissions updated!'));
|
|
53
|
+
});
|
|
54
|
+
//# sourceMappingURL=pushPerms.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pushPerms.js","sourceRoot":"","sources":["../../src/lib/pushPerms.ts"],"names":[],"mappings":"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","sourcesContent":["import { Effect, Option, Schema } from 'effect';\nimport jsonDiff from 'json-diff';\nimport { readLocalPermsFile } from '../old.js';\nimport { InstantHttpAuthed, withCommand } from './http.ts';\nimport {\n HttpClient,\n HttpClientRequest,\n HttpClientResponse,\n} from '@effect/platform';\nimport { CurrentApp } from '../context/currentApp.ts';\nimport { promptOk } from './ui.ts';\nimport boxen from 'boxen';\nimport chalk from 'chalk';\n\nexport class NoPermsFileError extends Schema.TaggedError<NoPermsFileError>(\n 'NoPermsFileError',\n)('NoPermsFileError', {\n message: Schema.String,\n}) {}\n\nconst PullPermsResponse = Schema.Struct({\n perms: Schema.Any.pipe(Schema.optional),\n});\n\nexport const pushPerms = Effect.gen(function* () {\n yield* Effect.log('Planning perms...');\n const { appId } = yield* CurrentApp;\n const http = yield* InstantHttpAuthed;\n\n const permsFile = yield* Effect.tryPromise(readLocalPermsFile).pipe(\n Effect.flatMap(Option.fromNullable),\n Effect.mapError(() =>\n NoPermsFileError.make({\n message: `We couldn't find your ${chalk.yellow('`instant.perms.ts`')} file. Make sure it's in the root directory. (Hint: You can use an INSTANT_PERMS_FILE_PATH environment variable to specify it.)`,\n }),\n ),\n );\n\n const prodPerms = yield* http\n .pipe(withCommand('push'))\n .get(`/dash/apps/${appId}/perms/pull`)\n .pipe(Effect.flatMap(HttpClientResponse.schemaBodyJson(PullPermsResponse))); // parse result body into \"any\"\n\n const diffedStr = jsonDiff.diffString(\n prodPerms.perms || {},\n permsFile.perms || {},\n );\n\n if (!diffedStr.length) {\n yield* Effect.log('No perms changes detected. Skipping.');\n return;\n }\n\n const okPush = yield* promptOk({\n promptText: 'Push these changes to your perms?',\n modifyOutput: (output) => {\n let both = diffedStr + '\\n' + output;\n return boxen(both, {\n dimBorder: true,\n padding: {\n left: 1,\n right: 1,\n },\n });\n },\n });\n if (!okPush) return;\n\n yield* http\n .pipe(\n withCommand('push'),\n HttpClient.mapRequestInputEffect(\n HttpClientRequest.bodyJson({ code: permsFile.perms }),\n ),\n )\n .post(`/dash/apps/${appId}/rules`)\n .pipe(Effect.flatMap(HttpClientResponse.schemaBodyJson(Schema.Any)));\n\n yield* Effect.log(chalk.green('Permissions updated!'));\n});\n"]}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { Effect, Schema } from 'effect';
|
|
2
|
+
import { CurrentApp } from '../context/currentApp.ts';
|
|
3
|
+
import { InstantHttpAuthed } from './http.ts';
|
|
4
|
+
import { GlobalOpts } from '../context/globalOpts.ts';
|
|
5
|
+
import { pushDef } from '../index.ts';
|
|
6
|
+
import type { OptsFromCommand } from '../index.ts';
|
|
7
|
+
import { AuthToken } from '../context/authToken.ts';
|
|
8
|
+
declare const ReadSchemaFileError_base: Schema.TaggedErrorClass<ReadSchemaFileError, "ReadSchemaFileError", {
|
|
9
|
+
readonly _tag: Schema.tag<"ReadSchemaFileError">;
|
|
10
|
+
} & {
|
|
11
|
+
message: typeof Schema.String;
|
|
12
|
+
cause: Schema.optional<typeof Schema.Any>;
|
|
13
|
+
}>;
|
|
14
|
+
export declare class ReadSchemaFileError extends ReadSchemaFileError_base {
|
|
15
|
+
}
|
|
16
|
+
declare const SchemaDiffError_base: Schema.TaggedErrorClass<SchemaDiffError, "SchemaDiffError", {
|
|
17
|
+
readonly _tag: Schema.tag<"SchemaDiffError">;
|
|
18
|
+
} & {
|
|
19
|
+
message: typeof Schema.String;
|
|
20
|
+
}>;
|
|
21
|
+
export declare class SchemaDiffError extends SchemaDiffError_base {
|
|
22
|
+
}
|
|
23
|
+
declare const GetSchemaError_base: Schema.TaggedErrorClass<GetSchemaError, "GetSchemaError", {
|
|
24
|
+
readonly _tag: Schema.tag<"GetSchemaError">;
|
|
25
|
+
} & {
|
|
26
|
+
message: typeof Schema.String;
|
|
27
|
+
}>;
|
|
28
|
+
export declare class GetSchemaError extends GetSchemaError_base {
|
|
29
|
+
}
|
|
30
|
+
declare const SchemaValidationError_base: Schema.TaggedErrorClass<SchemaValidationError, "SchemaValidationError", {
|
|
31
|
+
readonly _tag: Schema.tag<"SchemaValidationError">;
|
|
32
|
+
} & {
|
|
33
|
+
message: typeof Schema.String;
|
|
34
|
+
}>;
|
|
35
|
+
export declare class SchemaValidationError extends SchemaValidationError_base {
|
|
36
|
+
}
|
|
37
|
+
export declare const pushSchema: (rename?: OptsFromCommand<typeof pushDef>["rename"]) => Effect.Effect<undefined, import("./http.ts").InstantHttpError | import("effect/Cause").TimeoutException | import("@effect/platform/HttpClientError").RequestError | import("effect/ParseResult").ParseError | import("@effect/platform/HttpClientError").ResponseError | import("@effect/platform/HttpBody").HttpBodyError | ReadSchemaFileError | SchemaDiffError | GetSchemaError | SchemaValidationError | WaitForJobsError | CancelSchemaError, GlobalOpts | AuthToken | InstantHttpAuthed | CurrentApp>;
|
|
38
|
+
declare const WaitForJobsError_base: Schema.TaggedErrorClass<WaitForJobsError, "WaitForJobsError", {
|
|
39
|
+
readonly _tag: Schema.tag<"WaitForJobsError">;
|
|
40
|
+
} & {
|
|
41
|
+
message: typeof Schema.String;
|
|
42
|
+
}>;
|
|
43
|
+
export declare class WaitForJobsError extends WaitForJobsError_base {
|
|
44
|
+
}
|
|
45
|
+
declare const CancelSchemaError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => import("effect/Cause").YieldableError & {
|
|
46
|
+
readonly _tag: "CancelSchemaError";
|
|
47
|
+
} & Readonly<A>;
|
|
48
|
+
export declare class CancelSchemaError extends CancelSchemaError_base<{
|
|
49
|
+
message: string;
|
|
50
|
+
}> {
|
|
51
|
+
}
|
|
52
|
+
export {};
|
|
53
|
+
//# sourceMappingURL=pushSchema.d.ts.map
|