-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(sdk): add Website resource type
- Loading branch information
Showing
20 changed files
with
456 additions
and
32 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
--- | ||
"@plutolang/pluto-infra": patch | ||
"@plutolang/pluto": patch | ||
--- | ||
|
||
feat(sdk): add Website resource type |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
import { glob } from "glob"; | ||
import * as path from "path"; | ||
import * as fs from "fs-extra"; | ||
import * as aws from "@pulumi/aws"; | ||
import * as mime from "mime-types"; | ||
import * as pulumi from "@pulumi/pulumi"; | ||
import { IResourceInfra } from "@plutolang/base"; | ||
import { genResourceId } from "@plutolang/base/utils"; | ||
import { Website as WebsiteProto, WebsiteOptions } from "@plutolang/pluto"; | ||
import { S3Bucket } from "./bucket.s3"; | ||
|
||
export class Website extends pulumi.ComponentResource implements IResourceInfra { | ||
public readonly id: string; | ||
|
||
private readonly envs: { [key: string]: pulumi.Output<string> | string } = {}; | ||
private readonly websiteDir: string; | ||
|
||
private readonly websiteBucket: S3Bucket; | ||
|
||
private readonly websiteEndpoint: pulumi.Output<string>; | ||
|
||
// eslint-disable-next-line | ||
public outputs?: pulumi.Output<any>; | ||
|
||
constructor(websiteRoot: string, name?: string, options?: WebsiteOptions) { | ||
name = name ?? "default"; | ||
super("pluto:website:aws/Website", name, options); | ||
this.id = genResourceId(WebsiteProto.fqn, name); | ||
|
||
const projectRoot = new pulumi.Config("pluto").require("projectRoot"); | ||
this.websiteDir = path.resolve(projectRoot, websiteRoot); | ||
if (!fs.existsSync(this.websiteDir)) { | ||
throw new Error(`The path ${this.websiteDir} does not exist.`); | ||
} | ||
|
||
this.websiteBucket = new S3Bucket(this.id); | ||
this.websiteBucket.setPublic(); | ||
this.websiteEndpoint = this.websiteBucket.configWebsite("index.html"); | ||
|
||
this.outputs = this.websiteEndpoint; | ||
} | ||
|
||
public addEnv(key: string, value: pulumi.Output<string> | string) { | ||
this.envs[key] = value; | ||
} | ||
|
||
public url(): string { | ||
return this.websiteEndpoint as any; | ||
} | ||
|
||
public grantPermission(op: string, resource?: IResourceInfra) { | ||
op; | ||
resource; | ||
throw new Error("Method should be called."); | ||
} | ||
|
||
public postProcess(): void { | ||
function dumpPlutoJs(filepath: string, envs: { [key: string]: string }) { | ||
const content = PLUTO_JS_TEMPALETE.replace("{placeholder}", JSON.stringify(envs, null, 2)); | ||
fs.writeFileSync(filepath, content); | ||
} | ||
|
||
function uploadFileToS3(bucket: S3Bucket, dirpath: string) { | ||
glob.sync(`${dirpath}/**/*`).forEach((file) => { | ||
const lambdaAssetName = file.replace(new RegExp(`${dirpath}/?`, "g"), ""); | ||
const mimeType = mime.lookup(file) || undefined; | ||
new aws.s3.BucketObjectv2(lambdaAssetName, { | ||
bucket: bucket.bucket.bucket, | ||
key: lambdaAssetName, | ||
contentType: mimeType, | ||
source: new pulumi.asset.FileAsset(file), | ||
}); | ||
}); | ||
} | ||
|
||
pulumi.output(this.envs).apply((envs) => { | ||
const filepath = path.join(this.websiteDir, "pluto.js"); | ||
// Developers may have previously constructed a `pluto.js` file to facilitate debugging | ||
// throughout the development process. Therefore, it's essential to back up the original | ||
// content of `pluto.js` and ensure it's restored after deployment. | ||
const originalPlutoJs = fs.existsSync(filepath) | ||
? fs.readFileSync(filepath, "utf8") | ||
: undefined; | ||
|
||
try { | ||
dumpPlutoJs(filepath, envs); | ||
uploadFileToS3(this.websiteBucket, this.websiteDir); | ||
// Remove the generated `pluto.js` file after deployment. | ||
fs.removeSync(filepath); | ||
} finally { | ||
// Restore original pluto.js content. | ||
if (originalPlutoJs) { | ||
fs.writeFileSync(filepath, originalPlutoJs); | ||
} | ||
} | ||
}); | ||
} | ||
} | ||
|
||
const PLUTO_JS_TEMPALETE = ` | ||
window.plutoEnv = {placeholder} | ||
`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import { ProvisionType, PlatformType, utils, IResourceInfra } from "@plutolang/base"; | ||
import { IWebsiteInfra, WebsiteOptions } from "@plutolang/pluto"; | ||
import { ImplClassMap } from "./utils"; | ||
|
||
type IWebsiteInfraImpl = IWebsiteInfra & IResourceInfra; | ||
|
||
// Construct a type for a class constructor. The key point is that the parameters of the constructor | ||
// must be consistent with the client class of this resource type. Use this type to ensure that | ||
// all implementation classes have the correct and same constructor signature. | ||
type WebsiteInfraImplClass = new ( | ||
path: string, | ||
name?: string, | ||
options?: WebsiteOptions | ||
) => IWebsiteInfraImpl; | ||
|
||
// Construct a map that contains all the implementation classes for this resource type. | ||
// The final selection will be determined at runtime, and the class will be imported lazily. | ||
const implClassMap = new ImplClassMap<IWebsiteInfraImpl, WebsiteInfraImplClass>( | ||
"@plutolang/pluto.Website", | ||
{ | ||
[ProvisionType.Pulumi]: { | ||
[PlatformType.AWS]: async () => (await import("./aws")).Website, | ||
}, | ||
} | ||
); | ||
|
||
/** | ||
* This is a factory class that provides an interface to create instances of this resource type | ||
* based on the target platform and provisioning engine. | ||
*/ | ||
export abstract class Website { | ||
/** | ||
* Asynchronously creates an instance of the Website infrastructure class. The parameters of this function | ||
* must be consistent with the constructor of both the client class and infrastructure class associated | ||
* with this resource type. | ||
*/ | ||
public static async createInstance( | ||
path: string, | ||
name?: string, | ||
options?: WebsiteOptions | ||
): Promise<IWebsiteInfraImpl> { | ||
return implClassMap.createInstanceOrThrow( | ||
utils.currentPlatformType(), | ||
utils.currentEngineType(), | ||
path, | ||
name, | ||
options | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# pluto-client | ||
|
||
## 0.0.10 | ||
|
||
feat(sdk): add Website resource type |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
from .router import RouterClient | ||
from .website import WebsiteClient |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
from typing import Optional | ||
from pluto_base.utils import gen_resource_id, get_env_val_for_property | ||
from ...website import IWebsiteClient, Website, WebsiteOptions | ||
|
||
|
||
class WebsiteClient(IWebsiteClient): | ||
def __init__( | ||
self, | ||
path: str, | ||
name: Optional[str] = None, | ||
opts: Optional[WebsiteOptions] = None, | ||
): | ||
name = name or "default" | ||
self.__id = gen_resource_id(Website.fqn, name) | ||
|
||
def url(self) -> str: | ||
return get_env_val_for_property(self.__id, "url") |
Oops, something went wrong.