alchemy 0.2.1 → 0.2.3
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/lib/alchemy.d.ts +1 -0
- package/lib/alchemy.js +84 -8
- package/lib/apply.d.ts +1 -1
- package/lib/apply.js +13 -10
- package/lib/aws/bucket.d.ts +1 -1
- package/lib/aws/function.d.ts +1 -1
- package/lib/aws/oidc/oidc-provider.d.ts +1 -1
- package/lib/aws/policy-attachment.d.ts +1 -1
- package/lib/aws/policy.d.ts +1 -1
- package/lib/aws/queue.d.ts +1 -1
- package/lib/aws/role.d.ts +1 -1
- package/lib/aws/ses.d.ts +1 -1
- package/lib/aws/table.d.ts +1 -1
- package/lib/cloudflare/bucket.d.ts +1 -1
- package/lib/cloudflare/kv-namespace.d.ts +1 -1
- package/lib/cloudflare/static-site.d.ts +1 -1
- package/lib/cloudflare/worker.d.ts +1 -1
- package/lib/cloudflare/wrangler.json.d.ts +1 -1
- package/lib/cloudflare/zone.d.ts +1 -1
- package/lib/context.d.ts +9 -4
- package/lib/context.js +4 -2
- package/lib/destroy.js +8 -7
- package/lib/docs/document.d.ts +123 -0
- package/lib/docs/document.js +67 -0
- package/lib/docs/index.d.ts +1 -0
- package/lib/docs/index.js +1 -0
- package/lib/esbuild/bundle.d.ts +1 -1
- package/lib/fs/file.d.ts +30 -3
- package/lib/fs/file.js +63 -3
- package/lib/fs/folder.d.ts +3 -3
- package/lib/fs/folder.js +2 -1
- package/lib/github/secret.d.ts +1 -1
- package/lib/resource.d.ts +2 -2
- package/lib/resource.js +4 -0
- package/lib/scope.d.ts +1 -1
- package/lib/scope.js +6 -6
- package/lib/shadcn/component.d.ts +29 -0
- package/lib/shadcn/component.js +31 -0
- package/lib/shadcn/index.d.ts +1 -0
- package/lib/shadcn/index.js +1 -0
- package/lib/state.d.ts +1 -1
- package/lib/state.js +8 -1
- package/lib/stripe/price.d.ts +1 -1
- package/lib/stripe/product.d.ts +1 -1
- package/lib/stripe/webhook.d.ts +1 -1
- package/lib/util/serde.d.ts +3 -1
- package/lib/util/serde.js +6 -4
- package/lib/vite/vite.d.ts +90 -0
- package/lib/vite/vite.js +228 -0
- package/lib/vitepress/dependencies.d.ts +16 -0
- package/lib/vitepress/dependencies.js +35 -0
- package/lib/vitepress/home-page.d.ts +133 -0
- package/lib/vitepress/home-page.js +11 -0
- package/lib/vitepress/index.d.ts +2 -0
- package/lib/vitepress/index.js +2 -0
- package/lib/vitepress/vitepress.d.ts +60 -0
- package/lib/vitepress/vitepress.js +260 -0
- package/package.json +19 -11
- package/src/alchemy.ts +105 -13
- package/src/apply.ts +25 -13
- package/src/context.ts +30 -10
- package/src/destroy.ts +10 -7
- package/src/docs/document.ts +225 -0
- package/src/docs/index.ts +1 -0
- package/src/fs/file.ts +114 -6
- package/src/fs/folder.ts +2 -1
- package/src/resource.ts +7 -2
- package/src/scope.ts +9 -9
- package/src/shadcn/component.ts +80 -0
- package/src/shadcn/index.ts +1 -0
- package/src/state.ts +9 -2
- package/src/util/serde.ts +13 -4
- package/src/vite/vite.ts +406 -0
- package/src/vitepress/dependencies.ts +68 -0
- package/src/vitepress/home-page.ts +166 -0
- package/src/vitepress/index.md +75 -0
- package/src/vitepress/index.ts +2 -0
- package/src/vitepress/vitepress.ts +361 -0
- package/lib/project/vite.d.ts +0 -39
- package/lib/project/vite.js +0 -68
- package/src/project/vite.ts +0 -152
- /package/lib/{project → vite}/index.d.ts +0 -0
- /package/lib/{project → vite}/index.js +0 -0
- /package/src/{project → vite}/index.ts +0 -0
package/lib/fs/file.d.ts
CHANGED
|
@@ -1,13 +1,40 @@
|
|
|
1
1
|
import type { Context } from "../context";
|
|
2
2
|
import { Resource } from "../resource";
|
|
3
|
+
declare module "../alchemy" {
|
|
4
|
+
interface Alchemy {
|
|
5
|
+
file(path: string): Promise<FileRef>;
|
|
6
|
+
files(paths: string[]): Promise<FileCollection>;
|
|
7
|
+
files(path: string, ...paths: string[]): Promise<FileCollection>;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
export type FileRef = {
|
|
11
|
+
kind: "fs::FileRef";
|
|
12
|
+
path: string;
|
|
13
|
+
};
|
|
14
|
+
export declare function isFileRef(value: unknown): value is FileRef;
|
|
15
|
+
export type FileCollection = {
|
|
16
|
+
type: "fs::FileCollection";
|
|
17
|
+
files: {
|
|
18
|
+
[relativePath: string]: string;
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
export declare function isFileCollection(value: unknown): value is FileCollection;
|
|
3
22
|
export interface File extends Resource<"fs::File"> {
|
|
4
23
|
path: string;
|
|
5
24
|
content: string;
|
|
6
25
|
}
|
|
7
|
-
export declare const File: ((this: Context<File>, id: string,
|
|
26
|
+
export declare const File: ((this: Context<File>, id: string, props: {
|
|
8
27
|
path: string;
|
|
9
28
|
content: string;
|
|
10
|
-
}) => Promise<File>) | (((this: any, id: string, props
|
|
29
|
+
}) => Promise<File>) | (((this: any, id: string, props?: {
|
|
11
30
|
path: string;
|
|
12
31
|
content: string;
|
|
13
|
-
}) => never) & (new (_: never) => never));
|
|
32
|
+
} | undefined) => never) & (new (_: never) => never));
|
|
33
|
+
export type JsonFile = File;
|
|
34
|
+
export declare function JsonFile(id: string, content: any): Promise<JsonFile>;
|
|
35
|
+
export type TextFile = File;
|
|
36
|
+
export declare function TextFile(id: string, content: string): Promise<TextFile>;
|
|
37
|
+
export type YamlFile = File;
|
|
38
|
+
export declare function YamlFile(id: string, content: any): Promise<YamlFile>;
|
|
39
|
+
export type TypeScriptFile = File;
|
|
40
|
+
export declare function TypeScriptFile(id: string, content: string): Promise<TypeScriptFile>;
|
package/lib/fs/file.js
CHANGED
|
@@ -2,7 +2,35 @@ import fs from "node:fs";
|
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { Resource } from "../resource";
|
|
4
4
|
import { ignore } from "../util/ignore";
|
|
5
|
-
|
|
5
|
+
import { alchemy } from "../alchemy";
|
|
6
|
+
export function isFileRef(value) {
|
|
7
|
+
return (typeof value === "object" &&
|
|
8
|
+
value !== null &&
|
|
9
|
+
"kind" in value &&
|
|
10
|
+
value.kind === "fs::FileRef");
|
|
11
|
+
}
|
|
12
|
+
export function isFileCollection(value) {
|
|
13
|
+
return (typeof value === "object" &&
|
|
14
|
+
value !== null &&
|
|
15
|
+
"type" in value &&
|
|
16
|
+
value.type === "fs::FileCollection");
|
|
17
|
+
}
|
|
18
|
+
alchemy.file = async (path) => ({
|
|
19
|
+
kind: "fs::FileRef",
|
|
20
|
+
path,
|
|
21
|
+
});
|
|
22
|
+
alchemy.files = async (...args) => {
|
|
23
|
+
const paths = typeof args[0] === "string" ? args : args[0];
|
|
24
|
+
return {
|
|
25
|
+
type: "fs::FileCollection",
|
|
26
|
+
files: Object.fromEntries(await Promise.all(paths.map(async (path) => [
|
|
27
|
+
path,
|
|
28
|
+
await fs.promises.readFile(path, "utf-8"),
|
|
29
|
+
]))),
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
export const File = Resource("fs::File", async function (id, props) {
|
|
33
|
+
const filePath = props?.path ?? id;
|
|
6
34
|
if (this.phase === "delete") {
|
|
7
35
|
await ignore("ENOENT", async () => fs.promises.unlink(filePath));
|
|
8
36
|
return this.destroy();
|
|
@@ -11,10 +39,42 @@ export const File = Resource("fs::File", async function (id, { path: filePath, c
|
|
|
11
39
|
await fs.promises.mkdir(path.dirname(filePath), {
|
|
12
40
|
recursive: true,
|
|
13
41
|
});
|
|
14
|
-
await fs.promises.writeFile(filePath, content);
|
|
42
|
+
await fs.promises.writeFile(filePath, props.content);
|
|
15
43
|
}
|
|
16
44
|
return this({
|
|
17
45
|
path: filePath,
|
|
18
|
-
content,
|
|
46
|
+
content: props.content,
|
|
19
47
|
});
|
|
20
48
|
});
|
|
49
|
+
export function JsonFile(id, content) {
|
|
50
|
+
return File(id, {
|
|
51
|
+
path: id,
|
|
52
|
+
content: JSON.stringify(content, null, 2),
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
export function TextFile(id, content) {
|
|
56
|
+
return File(id, {
|
|
57
|
+
path: id,
|
|
58
|
+
content,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
export async function YamlFile(id, content) {
|
|
62
|
+
const yaml = await import("yaml");
|
|
63
|
+
return File(id, {
|
|
64
|
+
path: id,
|
|
65
|
+
content: yaml.stringify(content),
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
export async function TypeScriptFile(id, content) {
|
|
69
|
+
const prettier = await import("prettier");
|
|
70
|
+
return File(id, {
|
|
71
|
+
path: id,
|
|
72
|
+
content: await prettier.format(content, {
|
|
73
|
+
parser: "typescript",
|
|
74
|
+
editor: {
|
|
75
|
+
tabWidth: 2,
|
|
76
|
+
indentWidth: 2,
|
|
77
|
+
},
|
|
78
|
+
}),
|
|
79
|
+
});
|
|
80
|
+
}
|
package/lib/fs/folder.d.ts
CHANGED
|
@@ -3,8 +3,8 @@ import { Resource } from "../resource";
|
|
|
3
3
|
export interface Folder extends Resource<"fs::Folder"> {
|
|
4
4
|
path: string;
|
|
5
5
|
}
|
|
6
|
-
export declare const Folder: ((this: Context<Folder>, id: string,
|
|
6
|
+
export declare const Folder: ((this: Context<Folder>, id: string, props?: {
|
|
7
7
|
path: string;
|
|
8
|
-
}) => Promise<Folder>) | (((this: any, id: string, props
|
|
8
|
+
}) => Promise<Folder>) | (((this: any, id: string, props?: {
|
|
9
9
|
path: string;
|
|
10
|
-
}) => never) & (new (_: never) => never));
|
|
10
|
+
} | undefined) => never) & (new (_: never) => never));
|
package/lib/fs/folder.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import { Resource } from "../resource";
|
|
3
3
|
import { ignore } from "../util/ignore";
|
|
4
|
-
export const Folder = Resource("fs::Folder", async function (id,
|
|
4
|
+
export const Folder = Resource("fs::Folder", async function (id, props) {
|
|
5
|
+
const dirPath = props?.path ?? id;
|
|
5
6
|
if (this.phase === "delete") {
|
|
6
7
|
// we just do a best effort attempt
|
|
7
8
|
await ignore(["ENOENT", "ENOTEMPTY"], async () => fs.promises.rmdir(dirPath));
|
package/lib/github/secret.d.ts
CHANGED
|
@@ -42,4 +42,4 @@ export interface GitHubSecretOutput extends Resource<"github::Secret">, Omit<Git
|
|
|
42
42
|
/**
|
|
43
43
|
* Resource for managing GitHub repository secrets
|
|
44
44
|
*/
|
|
45
|
-
export declare const GitHubSecret: ((this: Context<GitHubSecretOutput>, id: string, props: GitHubSecretProps) => Promise<GitHubSecretOutput>) | (((this: any, id: string, props
|
|
45
|
+
export declare const GitHubSecret: ((this: Context<GitHubSecretOutput>, id: string, props: GitHubSecretProps) => Promise<GitHubSecretOutput>) | (((this: any, id: string, props?: GitHubSecretProps | undefined) => never) & (new (_: never) => never));
|
package/lib/resource.d.ts
CHANGED
|
@@ -36,8 +36,8 @@ export interface Resource<Kind extends ResourceKind = ResourceKind, ID extends R
|
|
|
36
36
|
type IsClass = {
|
|
37
37
|
new (_: never): never;
|
|
38
38
|
};
|
|
39
|
-
type ResourceLifecycleHandler = (this: Context<any>, id: string, props: any) => Promise<Resource<string>>;
|
|
40
|
-
type Handler<F extends (...args: any[]) => any> = F | (((this: any, id: string, props
|
|
39
|
+
type ResourceLifecycleHandler = (this: Context<any, any>, id: string, props: any) => Promise<Resource<string>>;
|
|
40
|
+
type Handler<F extends (...args: any[]) => any> = F | (((this: any, id: string, props?: Parameters<F>[1]) => never) & IsClass);
|
|
41
41
|
export declare function Resource<const Type extends string, F extends ResourceLifecycleHandler>(type: Type, fn: F): Handler<F>;
|
|
42
42
|
export declare function Resource<const Type extends string, F extends ResourceLifecycleHandler>(type: Type, options: Partial<ProviderOptions>, fn: F): Handler<F>;
|
|
43
43
|
export {};
|
package/lib/resource.js
CHANGED
|
@@ -8,6 +8,10 @@ export function Resource(type, ...args) {
|
|
|
8
8
|
const [options, handler] = args.length === 2 ? args : [undefined, args[0]];
|
|
9
9
|
const provider = ((resourceID, props) => {
|
|
10
10
|
const scope = _Scope.current;
|
|
11
|
+
if (resourceID.includes(":")) {
|
|
12
|
+
// we want to use : as an internal separator for resources
|
|
13
|
+
throw new Error(`ID cannot include colons: ${resourceID}`);
|
|
14
|
+
}
|
|
11
15
|
if (scope.resources.has(resourceID)) {
|
|
12
16
|
// TODO(sam): do we want to throw?
|
|
13
17
|
// it's kind of awesome that you can re-create a resource and call apply
|
package/lib/scope.d.ts
CHANGED
|
@@ -31,9 +31,9 @@ export declare class Scope {
|
|
|
31
31
|
init(): Promise<void>;
|
|
32
32
|
deinit(): Promise<void>;
|
|
33
33
|
fqn(resourceID: ResourceID): string;
|
|
34
|
-
finalize(): Promise<void>;
|
|
35
34
|
run<T>(fn: (scope: Scope) => Promise<T>): Promise<T>;
|
|
36
35
|
[Symbol.asyncDispose](): Promise<void>;
|
|
36
|
+
finalize(): Promise<void>;
|
|
37
37
|
/**
|
|
38
38
|
* Returns a string representation of the scope.
|
|
39
39
|
*/
|
package/lib/scope.js
CHANGED
|
@@ -68,6 +68,12 @@ export class Scope {
|
|
|
68
68
|
fqn(resourceID) {
|
|
69
69
|
return [...this.chain, resourceID].join("/");
|
|
70
70
|
}
|
|
71
|
+
async run(fn) {
|
|
72
|
+
return scopeStorage.run(this, () => fn(this));
|
|
73
|
+
}
|
|
74
|
+
[Symbol.asyncDispose]() {
|
|
75
|
+
return this.finalize();
|
|
76
|
+
}
|
|
71
77
|
async finalize() {
|
|
72
78
|
if (!this.isErrored) {
|
|
73
79
|
// TODO: need to detect if it is in error
|
|
@@ -84,12 +90,6 @@ export class Scope {
|
|
|
84
90
|
console.warn("Scope is in error, skipping finalize");
|
|
85
91
|
}
|
|
86
92
|
}
|
|
87
|
-
async run(fn) {
|
|
88
|
-
return scopeStorage.run(this, () => fn(this));
|
|
89
|
-
}
|
|
90
|
-
[Symbol.asyncDispose]() {
|
|
91
|
-
return this.finalize();
|
|
92
|
-
}
|
|
93
93
|
/**
|
|
94
94
|
* Returns a string representation of the scope.
|
|
95
95
|
*/
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { Context } from "../context";
|
|
2
|
+
import { Resource } from "../resource";
|
|
3
|
+
export interface ShadcnComponentProps {
|
|
4
|
+
/**
|
|
5
|
+
* The name of the component to install
|
|
6
|
+
*/
|
|
7
|
+
name: string;
|
|
8
|
+
/**
|
|
9
|
+
* The working directory where the component should be installed
|
|
10
|
+
*/
|
|
11
|
+
cwd: string;
|
|
12
|
+
/**
|
|
13
|
+
* Force overwrite of existing component
|
|
14
|
+
* @default false
|
|
15
|
+
*/
|
|
16
|
+
force?: boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Mute output
|
|
19
|
+
* @default false
|
|
20
|
+
*/
|
|
21
|
+
silent?: boolean;
|
|
22
|
+
}
|
|
23
|
+
export interface ShadcnComponent extends ShadcnComponentProps, Resource {
|
|
24
|
+
/**
|
|
25
|
+
* The name of the installed component
|
|
26
|
+
*/
|
|
27
|
+
name: string;
|
|
28
|
+
}
|
|
29
|
+
export declare const ShadcnComponent: ((this: Context<ShadcnComponent>, id: string, props: ShadcnComponentProps) => Promise<ShadcnComponent>) | (((this: any, id: string, props?: ShadcnComponentProps | undefined) => never) & (new (_: never) => never));
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { exec } from "child_process";
|
|
2
|
+
import fs from "fs/promises";
|
|
3
|
+
import path from "path";
|
|
4
|
+
import { promisify } from "util";
|
|
5
|
+
import { Resource } from "../resource";
|
|
6
|
+
const execAsync = promisify(exec);
|
|
7
|
+
export const ShadcnComponent = Resource("project::ShadcnComponent", async function (id, props) {
|
|
8
|
+
if (this.phase === "delete") {
|
|
9
|
+
const componentPath = path.join(props.cwd, "src", "components", "ui", `${props.name}.tsx`);
|
|
10
|
+
try {
|
|
11
|
+
await fs.unlink(componentPath);
|
|
12
|
+
}
|
|
13
|
+
catch (error) {
|
|
14
|
+
if (error.code !== "ENOENT") {
|
|
15
|
+
throw error;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return this.destroy();
|
|
19
|
+
}
|
|
20
|
+
// Build the shadcn add command with options
|
|
21
|
+
const addCommand = [
|
|
22
|
+
"bunx --bun shadcn@latest add",
|
|
23
|
+
props.name,
|
|
24
|
+
props.silent && "-s",
|
|
25
|
+
]
|
|
26
|
+
.filter(Boolean)
|
|
27
|
+
.join(" ");
|
|
28
|
+
// Execute the command in the specified directory
|
|
29
|
+
await execAsync(addCommand, { cwd: props.cwd });
|
|
30
|
+
return this(props);
|
|
31
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./component";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./component";
|
package/lib/state.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Resource, ResourceProps } from "./resource";
|
|
2
2
|
import type { Scope } from "./scope";
|
|
3
|
-
export interface State<Kind extends string = string, Props extends ResourceProps = ResourceProps, Out extends Resource = Resource> {
|
|
3
|
+
export interface State<Kind extends string = string, Props extends ResourceProps | undefined = ResourceProps | undefined, Out extends Resource = Resource> {
|
|
4
4
|
status: `creating` | `created` | `updating` | `updated` | `deleting` | `deleted`;
|
|
5
5
|
kind: Kind;
|
|
6
6
|
id: string;
|
package/lib/state.js
CHANGED
|
@@ -27,7 +27,8 @@ export class FileSystemStateStore {
|
|
|
27
27
|
});
|
|
28
28
|
return files
|
|
29
29
|
.filter((dirent) => dirent.isFile() && dirent.name.endsWith(".json"))
|
|
30
|
-
.map((dirent) => dirent.name.replace(/\.json$/, ""))
|
|
30
|
+
.map((dirent) => dirent.name.replace(/\.json$/, ""))
|
|
31
|
+
.map((key) => key.replaceAll(":", "/"));
|
|
31
32
|
}
|
|
32
33
|
catch (error) {
|
|
33
34
|
if (error.code === "ENOENT") {
|
|
@@ -72,6 +73,12 @@ export class FileSystemStateStore {
|
|
|
72
73
|
}))).flat());
|
|
73
74
|
}
|
|
74
75
|
async getPath(key) {
|
|
76
|
+
if (key.includes(":")) {
|
|
77
|
+
throw new Error(`ID cannot include colons: ${key}`);
|
|
78
|
+
}
|
|
79
|
+
if (key.includes("/")) {
|
|
80
|
+
key = key.replaceAll("/", ":");
|
|
81
|
+
}
|
|
75
82
|
const file = path.join(this.dir, `${key}.json`);
|
|
76
83
|
const dir = path.dirname(file);
|
|
77
84
|
await fs.promises.mkdir(dir, { recursive: true });
|
package/lib/stripe/price.d.ts
CHANGED
|
@@ -104,5 +104,5 @@ export interface Price extends Resource<"stripe::Price">, PriceProps {
|
|
|
104
104
|
*/
|
|
105
105
|
lookupKey?: string;
|
|
106
106
|
}
|
|
107
|
-
export declare const Price: ((this: Context<Price>, id: string, props: PriceProps) => Promise<Price>) | (((this: any, id: string, props
|
|
107
|
+
export declare const Price: ((this: Context<Price>, id: string, props: PriceProps) => Promise<Price>) | (((this: any, id: string, props?: PriceProps | undefined) => never) & (new (_: never) => never));
|
|
108
108
|
export {};
|
package/lib/stripe/product.d.ts
CHANGED
|
@@ -81,5 +81,5 @@ export interface Product extends Resource<"stripe::Product">, ProductProps {
|
|
|
81
81
|
width: number;
|
|
82
82
|
};
|
|
83
83
|
}
|
|
84
|
-
export declare const Product: ((this: Context<Product>, id: string, props: ProductProps) => Promise<Product>) | (((this: any, id: string, props
|
|
84
|
+
export declare const Product: ((this: Context<Product>, id: string, props: ProductProps) => Promise<Product>) | (((this: any, id: string, props?: ProductProps | undefined) => never) & (new (_: never) => never));
|
|
85
85
|
export {};
|
package/lib/stripe/webhook.d.ts
CHANGED
|
@@ -68,4 +68,4 @@ export interface WebhookEndpoint extends Resource<"stripe::WebhookEndpoint">, We
|
|
|
68
68
|
*/
|
|
69
69
|
status: string;
|
|
70
70
|
}
|
|
71
|
-
export declare const WebhookEndpoint: ((this: Context<WebhookEndpoint>, id: string, props: WebhookEndpointProps) => Promise<WebhookEndpoint>) | (((this: any, id: string, props
|
|
71
|
+
export declare const WebhookEndpoint: ((this: Context<WebhookEndpoint>, id: string, props: WebhookEndpointProps) => Promise<WebhookEndpoint>) | (((this: any, id: string, props?: WebhookEndpointProps | undefined) => never) & (new (_: never) => never));
|
package/lib/util/serde.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
import { Scope } from "../scope";
|
|
2
|
-
export declare function serialize(scope: Scope, value: any
|
|
2
|
+
export declare function serialize(scope: Scope, value: any, options?: {
|
|
3
|
+
encrypt?: boolean;
|
|
4
|
+
}): Promise<any>;
|
|
3
5
|
export declare function deserialize(scope: Scope, value: any): Promise<any>;
|
package/lib/util/serde.js
CHANGED
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
import { Scope } from "../scope";
|
|
2
2
|
import { Secret } from "../secret";
|
|
3
3
|
import { decryptWithKey, encryptWithKey } from "./encrypt";
|
|
4
|
-
export async function serialize(scope, value) {
|
|
4
|
+
export async function serialize(scope, value, options) {
|
|
5
5
|
if (Array.isArray(value)) {
|
|
6
|
-
return Promise.all(value.map((value) => serialize(scope, value)));
|
|
6
|
+
return Promise.all(value.map((value) => serialize(scope, value, options)));
|
|
7
7
|
}
|
|
8
8
|
else if (value instanceof Secret) {
|
|
9
9
|
if (!scope.password) {
|
|
10
10
|
throw new Error("Cannot serialize secret without password");
|
|
11
11
|
}
|
|
12
12
|
return {
|
|
13
|
-
"@secret":
|
|
13
|
+
"@secret": options?.encrypt !== false
|
|
14
|
+
? await encryptWithKey(value.unencrypted, scope.password)
|
|
15
|
+
: value.unencrypted,
|
|
14
16
|
};
|
|
15
17
|
}
|
|
16
18
|
else if (value instanceof Scope) {
|
|
@@ -19,7 +21,7 @@ export async function serialize(scope, value) {
|
|
|
19
21
|
else if (value && typeof value === "object") {
|
|
20
22
|
return Object.fromEntries(await Promise.all(Object.entries(value).map(async ([key, value]) => [
|
|
21
23
|
key,
|
|
22
|
-
await serialize(scope, value),
|
|
24
|
+
await serialize(scope, value, options),
|
|
23
25
|
])));
|
|
24
26
|
}
|
|
25
27
|
return value;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import type { Context } from "../context";
|
|
2
|
+
import { Resource } from "../resource";
|
|
3
|
+
type ViteTemplate = "vanilla" | "vanilla-ts" | "vue" | "vue-ts" | "react" | "react-ts" | "react-swc" | "react-swc-ts" | "preact" | "preact-ts" | "lit" | "lit-ts" | "svelte" | "svelte-ts" | "solid" | "solid-ts" | "qwik" | "qwik-ts";
|
|
4
|
+
export interface ViteProjectProps {
|
|
5
|
+
/**
|
|
6
|
+
* The name/path of the project
|
|
7
|
+
*/
|
|
8
|
+
name: string;
|
|
9
|
+
/**
|
|
10
|
+
* The Vite template to use
|
|
11
|
+
*/
|
|
12
|
+
template: ViteTemplate;
|
|
13
|
+
/**
|
|
14
|
+
* The extends to add to the tsconfig.json file
|
|
15
|
+
*/
|
|
16
|
+
extends?: string;
|
|
17
|
+
/**
|
|
18
|
+
* The references to add to the tsconfig.json file
|
|
19
|
+
*/
|
|
20
|
+
references?: string[];
|
|
21
|
+
/**
|
|
22
|
+
* Add Tailwind CSS to the project
|
|
23
|
+
* @default false
|
|
24
|
+
*/
|
|
25
|
+
tailwind?: boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Add Tanstack Router to the project
|
|
28
|
+
* @default false
|
|
29
|
+
*/
|
|
30
|
+
tanstack?: boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Add Shadcn UI to the project
|
|
33
|
+
* @default false
|
|
34
|
+
*/
|
|
35
|
+
shadcn?: {
|
|
36
|
+
/**
|
|
37
|
+
* The base color to use
|
|
38
|
+
* @default "neutral"
|
|
39
|
+
*/
|
|
40
|
+
baseColor?: "neutral" | "gray" | "zinc" | "stone" | "slate";
|
|
41
|
+
/**
|
|
42
|
+
* Use default configuration
|
|
43
|
+
* @default false
|
|
44
|
+
*/
|
|
45
|
+
defaults?: boolean;
|
|
46
|
+
/**
|
|
47
|
+
* Force overwrite of existing configuration
|
|
48
|
+
* @default false
|
|
49
|
+
*/
|
|
50
|
+
force?: boolean;
|
|
51
|
+
/**
|
|
52
|
+
* The working directory
|
|
53
|
+
* @default current directory
|
|
54
|
+
*/
|
|
55
|
+
cwd?: string;
|
|
56
|
+
/**
|
|
57
|
+
* Mute output
|
|
58
|
+
* @default false
|
|
59
|
+
*/
|
|
60
|
+
silent?: boolean;
|
|
61
|
+
/**
|
|
62
|
+
* Use the src directory when creating a new project
|
|
63
|
+
* @default false
|
|
64
|
+
*/
|
|
65
|
+
srcDir?: boolean;
|
|
66
|
+
/**
|
|
67
|
+
* Use css variables for theming
|
|
68
|
+
* @default true
|
|
69
|
+
*/
|
|
70
|
+
cssVariables?: boolean;
|
|
71
|
+
/**
|
|
72
|
+
* The components to add
|
|
73
|
+
*/
|
|
74
|
+
components?: string[];
|
|
75
|
+
};
|
|
76
|
+
/**
|
|
77
|
+
* Force overwrite the project config files during the update phase
|
|
78
|
+
*
|
|
79
|
+
* @default false
|
|
80
|
+
*/
|
|
81
|
+
overwrite?: boolean;
|
|
82
|
+
}
|
|
83
|
+
export interface ViteProject extends ViteProjectProps, Resource {
|
|
84
|
+
/**
|
|
85
|
+
* The name/path of the project
|
|
86
|
+
*/
|
|
87
|
+
name: string;
|
|
88
|
+
}
|
|
89
|
+
export declare const ViteProject: ((this: Context<ViteProject>, id: string, props: ViteProjectProps) => Promise<ViteProject>) | (((this: any, id: string, props?: ViteProjectProps | undefined) => never) & (new (_: never) => never));
|
|
90
|
+
export {};
|