Skip to content

Commit

Permalink
feat: add S3 support (#19)
Browse files Browse the repository at this point in the history
  • Loading branch information
naorpeled committed Jan 30, 2023
1 parent 502559c commit f6d94f1
Show file tree
Hide file tree
Showing 8 changed files with 613 additions and 222 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"bench:hotswap": "pnpm -r --filter @benchmark/infra run hotswap"
},
"dependencies": {
"@rgrove/parse-xml": "^4.0.1",
"aws-sdk": "2.1295.0"
},
"peerDependencies": {
Expand All @@ -42,8 +43,8 @@
"@types/prettier": "^2.7.2",
"esbuild": "0.17.2",
"esbuild-visualizer": "^0.4.0",
"node-fetch": "^3.3.0",
"jest": "^29",
"node-fetch": "^3.3.0",
"prettier": "^2.8.3",
"standard-version": "^9.5.0",
"ts-jest": "^29",
Expand Down
7 changes: 7 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

184 changes: 18 additions & 166 deletions scripts/gen-sdk-mappings.mts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import fs from "fs/promises";
import path from "path";
import { findService, loadSmithyFile, SmithyFile } from "./smithy.js";

const modelsDir = "aws-models";

await parseErrors(path.join(modelsDir, "dynamodb.json"));

const specifications = await Promise.all(
(await fs.readdir(modelsDir))
.map((file) => path.join(modelsDir, file))
Expand Down Expand Up @@ -87,169 +86,22 @@ async function parseServiceMappings(
}
}

async function parseErrors(serviceFile: string) {
const serviceSpec = preProcessSmithyFile(
JSON.parse((await fs.readFile(serviceFile)).toString("utf-8"))
);

const service = findService(serviceSpec);
const s3 = await loadSmithyFile(path.join(modelsDir, "s3.json"));

for (const [shapeFQN, shape] of Object.entries(serviceSpec.shapes)) {
if (shape.type === "structure" && shape.traits?.["smithy.api#error"]) {
delete shape.traits["smithy.api#documentation"];
// console.log(shape);
const s3Headers = Object.values(s3.shapes)
.flatMap((shape) =>
shape.type === "structure"
? Object.entries(shape.members).flatMap(([memberName, member]) =>
member.traits?.["smithy.api#httpHeader"]
? [[memberName, member.traits["smithy.api#httpHeader"]] as const]
: []
)
: []
)
.reduce((map: any, [k, v]) => {
if (k in map && map[k] !== v) {
console.log(k, v, map[k]);
}
}
}

async function loadSmithyFile(file: string): Promise<SmithyFile> {
return preProcessSmithyFile(
JSON.parse((await fs.readFile(file)).toString("utf-8"))
);
}

// adds the FQN onto each Shape
function preProcessSmithyFile(file: SmithyFile) {
Object.entries(file.shapes).forEach(([fqn, shape]) => (shape.fqn = fqn));
return file;
}

function findService(file: SmithyFile): ServiceShape | undefined {
const services = Object.values(file.shapes).filter(
(shape): shape is ServiceShape => shape.type === "service"
);
if (services.length === 0) {
return undefined;
} else if (services.length > 1) {
throw new Error(`could not resolve a single service for the file`);
} else {
return services[0]!;
}
}

interface SmithyFile {
shapes: {
[fqn: string]: Shape;
};
}

type Shape =
| BlobShape
| BooleanShape
| DoubleShape
| EnumShape
| IntegerShape
| ListShape
| LongShape
| MapShape
| OperationShape
| ServiceShape
| StringShape
| StructureShape
| TimestampShape
| UnionShape;

interface HasTraits {
traits?: Traits;
}

interface BaseShape extends HasTraits {
fqn: string;
}

interface Traits {
[traitFqn: string]: any;
"smithy.api#error"?: "server" | "client";
"smithy.api#documentation"?: string;
"aws.api#service"?: {
sdkId: string;
arnNamespace: string;
cloudFormationName: string;
cloudTrailEventSource: string;
endpointPrefix: string;
};
"aws.auth#sigv4"?: {
name: string;
};
"smithy.api#title"?: string;
"smithy.api#xmlNamespace"?: {
uri: string;
};
"aws.protocols#awsJson1_0"?: {};
"aws.protocols#awsJson1_1"?: {};
}

interface ServiceShape extends BaseShape {
type: "service";
version: string;
}

interface OperationShape extends BaseShape {
type: "operation";
}

interface StringShape extends BaseShape {
type: "string";
}

interface BlobShape extends BaseShape {
type: "blob";
}

interface IntegerShape extends BaseShape {
type: "integer";
}

interface LongShape extends BaseShape {
type: "long";
}

interface DoubleShape extends BaseShape {
type: "double";
}

interface BooleanShape extends BaseShape {
type: "boolean";
}

interface TimestampShape extends BaseShape {
type: "timestamp";
}

interface EnumShape extends BaseShape {
type: "enum";
}

interface StructureShape extends BaseShape {
type: "structure";
members: {
[memberName: string]: Member;
};
}

interface Member extends HasTraits {
target: string;
}

interface ListShape extends BaseShape {
type: "list";
member: {
target: string;
};
}
interface MapShape extends BaseShape {
type: "map";
key: {
target: string;
};
value: {
target: string;
};
}

interface UnionShape extends BaseShape {
type: "union";
members: {
[memberName: string]: Member;
};
}
map[k] = v;
return map;
}, {});
154 changes: 154 additions & 0 deletions scripts/smithy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
import fs from "fs/promises";

export async function loadSmithyFile(file: string): Promise<SmithyFile> {
return preProcessSmithyFile(
JSON.parse((await fs.readFile(file)).toString("utf-8"))
);
}

// adds the FQN onto each Shape
export function preProcessSmithyFile(file: SmithyFile) {
Object.entries(file.shapes).forEach(([fqn, shape]) => (shape.fqn = fqn));
return file;
}

export function findService(file: SmithyFile): ServiceShape | undefined {
const services = Object.values(file.shapes).filter(
(shape): shape is ServiceShape => shape.type === "service"
);
if (services.length === 0) {
return undefined;
} else if (services.length > 1) {
throw new Error(`could not resolve a single service for the file`);
} else {
return services[0]!;
}
}

export interface SmithyFile {
shapes: {
[fqn: string]: Shape;
};
}

export type Shape =
| BlobShape
| BooleanShape
| DoubleShape
| EnumShape
| IntegerShape
| ListShape
| LongShape
| MapShape
| OperationShape
| ServiceShape
| StringShape
| StructureShape
| TimestampShape
| UnionShape;

export interface HasTraits {
traits?: Traits;
}

export interface BaseShape extends HasTraits {
fqn: string;
}

export interface Traits {
[traitFqn: string]: any;
"smithy.api#error"?: "server" | "client";
"smithy.api#documentation"?: string;
"aws.api#service"?: {
sdkId: string;
arnNamespace: string;
cloudFormationName: string;
cloudTrailEventSource: string;
endpointPrefix: string;
};
"aws.auth#sigv4"?: {
name: string;
};
"smithy.api#title"?: string;
"smithy.api#xmlNamespace"?: {
uri: string;
};
"aws.protocols#awsJson1_0"?: {};
"aws.protocols#awsJson1_1"?: {};
"smithy.api#httpHeader"?: string;
}

export interface ServiceShape extends BaseShape {
type: "service";
version: string;
}

export interface OperationShape extends BaseShape {
type: "operation";
}

export interface StringShape extends BaseShape {
type: "string";
}

export interface BlobShape extends BaseShape {
type: "blob";
}

export interface IntegerShape extends BaseShape {
type: "integer";
}

export interface LongShape extends BaseShape {
type: "long";
}

export interface DoubleShape extends BaseShape {
type: "double";
}

export interface BooleanShape extends BaseShape {
type: "boolean";
}

export interface TimestampShape extends BaseShape {
type: "timestamp";
}

export interface EnumShape extends BaseShape {
type: "enum";
}

export interface StructureShape extends BaseShape {
type: "structure";
members: {
[memberName: string]: Member;
};
}

export interface Member extends HasTraits {
target: string;
}

export interface ListShape extends BaseShape {
type: "list";
member: {
target: string;
};
}
export interface MapShape extends BaseShape {
type: "map";
key: {
target: string;
};
value: {
target: string;
};
}

export interface UnionShape extends BaseShape {
type: "union";
members: {
[memberName: string]: Member;
};
}
Loading

0 comments on commit f6d94f1

Please sign in to comment.