alchemy 0.0.7 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +23 -22
- package/src/alchemize.ts +151 -0
- package/src/apply.ts +117 -0
- package/src/components/agent/agent.ts +45 -0
- package/src/components/agent/anthropic.ts +27 -0
- package/src/components/agent/index.ts +4 -0
- package/src/components/agent/model.ts +22 -0
- package/src/components/agent/openai.ts +44 -0
- package/src/components/agent/package.ts +126 -0
- package/src/components/agent/requirements.ts +111 -0
- package/src/components/agent/scrape.ts +47 -0
- package/src/components/agent/tsconfig.ts +150 -0
- package/src/components/agent/typescript.ts +177 -0
- package/src/components/aws/bucket.ts +168 -0
- package/src/components/aws/function.ts +302 -0
- package/src/components/aws/index.ts +6 -0
- package/src/components/aws/policy.ts +245 -0
- package/src/components/aws/queue.ts +222 -0
- package/src/components/aws/role.ts +245 -0
- package/src/components/aws/table.ts +172 -0
- package/src/components/esbuild.ts +128 -0
- package/src/components/fs.ts +45 -0
- package/src/destroy.ts +63 -0
- package/src/error.ts +16 -0
- package/src/global.ts +72 -0
- package/src/index.ts +6 -0
- package/src/input.ts +16 -0
- package/src/main.ts +34 -0
- package/src/output.ts +49 -0
- package/src/resource.ts +313 -0
- package/src/state.ts +100 -0
- package/test/aws/function.test.ts +144 -0
- package/test/aws/queue.test.ts +85 -0
- package/test/aws/role.test.ts +153 -0
- package/test/aws/table.test.ts +73 -0
- package/test/esbuild.test.ts +41 -0
- package/test/handler.ts +9 -0
- package/tsconfig.json +7 -0
- package/Column.js +0 -1
- package/Create.js +0 -1
- package/Delete.js +0 -1
- package/Drop.js +0 -1
- package/Insert.js +0 -1
- package/Makefile +0 -8
- package/README.md +0 -0
- package/Select.js +0 -1
- package/Table.js +0 -1
- package/Transaction.js +0 -1
- package/Types.js +0 -1
- package/Update.js +0 -1
- package/alchemy.js +0 -57
- package/alchemy.sublime-project +0 -9
- package/alchemy.sublime-workspace +0 -2304
- package/config/app.js +0 -8
- package/config/db.js +0 -20
- package/copy.js +0 -1
- package/defaultEngine.js +0 -8
- package/engine.js +0 -282
- package/getInstantiatorFunction.js +0 -28
- package/index.js +0 -52
- package/jstest.js +0 -3
- package/loggerFactory.js +0 -27
- package/logs/alchemy.log +0 -46
- package/logs/sql.log +0 -41
- package/sql/Column.js +0 -158
- package/sql/Columnable.js +0 -21
- package/sql/Create.js +0 -15
- package/sql/Delete.js +0 -34
- package/sql/Drop.js +0 -36
- package/sql/Insert.js +0 -96
- package/sql/SchemaElement.js +0 -11
- package/sql/Select.js +0 -192
- package/sql/SqlBase.js +0 -134
- package/sql/SqlStatement.js +0 -80
- package/sql/Table.js +0 -96
- package/sql/Transaction.js +0 -45
- package/sql/Update.js +0 -105
- package/sql/defineElement.js +0 -26
- package/sql/defineStatement.js +0 -26
- package/sql/types/BaseType.js +0 -43
- package/sql/types/BigSerialType.js +0 -5
- package/sql/types/IntegerType.js +0 -5
- package/sql/types/JsonType.js +0 -5
- package/sql/types/SerialType.js +0 -5
- package/sql/types/StringType.js +0 -31
- package/sql/types/TimestampType.js +0 -5
- package/sql/types/UUIDType.js +0 -5
- package/sql/types/defineType.js +0 -25
- package/sql/types/getType.js +0 -12
- package/sql/types/index.js +0 -11
- package/sql/where.js +0 -31
- package/sql/whereToString.js +0 -29
- package/test/ColumnTests.js +0 -80
- package/test/CreateTable.js +0 -54
- package/test/DeleteTests.js +0 -28
- package/test/DropTests.js +0 -23
- package/test/GetTypeTests.js +0 -56
- package/test/InsertTests.js +0 -86
- package/test/SelectExistsTests.js +0 -26
- package/test/SelectTests.js +0 -130
- package/test/TableTests.js +0 -46
- package/test.js +0 -8
- package/test.ls +0 -4
- package/validate.js +0 -26
- package/x.js +0 -5
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import {
|
|
2
|
+
GetRoleCommand,
|
|
3
|
+
IAMClient,
|
|
4
|
+
NoSuchEntityException,
|
|
5
|
+
} from "@aws-sdk/client-iam";
|
|
6
|
+
import { describe, expect, test } from "bun:test";
|
|
7
|
+
import { apply } from "../../src/apply";
|
|
8
|
+
import type { PolicyDocument } from "../../src/components/aws";
|
|
9
|
+
import { Role, type RoleProps } from "../../src/components/aws/role";
|
|
10
|
+
import { destroy } from "../../src/destroy";
|
|
11
|
+
|
|
12
|
+
// Verify role was deleted
|
|
13
|
+
const iam = new IAMClient({});
|
|
14
|
+
|
|
15
|
+
describe("AWS Resources", () => {
|
|
16
|
+
describe("Role", () => {
|
|
17
|
+
const assumeRolePolicy: PolicyDocument = {
|
|
18
|
+
Version: "2012-10-17",
|
|
19
|
+
Statement: [
|
|
20
|
+
{
|
|
21
|
+
Effect: "Allow",
|
|
22
|
+
Principal: {
|
|
23
|
+
Service: "lambda.amazonaws.com",
|
|
24
|
+
},
|
|
25
|
+
Action: "sts:AssumeRole",
|
|
26
|
+
},
|
|
27
|
+
],
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const inlinePolicy: PolicyDocument = {
|
|
31
|
+
Version: "2012-10-17",
|
|
32
|
+
Statement: [
|
|
33
|
+
{
|
|
34
|
+
Effect: "Allow",
|
|
35
|
+
Action: [
|
|
36
|
+
"logs:CreateLogGroup",
|
|
37
|
+
"logs:CreateLogStream",
|
|
38
|
+
"logs:PutLogEvents",
|
|
39
|
+
],
|
|
40
|
+
Resource: "*",
|
|
41
|
+
},
|
|
42
|
+
],
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
test("create role", async () => {
|
|
46
|
+
const role = new Role("alchemy-test-create-role", {
|
|
47
|
+
roleName: "alchemy-test-create-role",
|
|
48
|
+
assumeRolePolicy,
|
|
49
|
+
description: "Test role for IAC",
|
|
50
|
+
tags: {
|
|
51
|
+
Environment: "test",
|
|
52
|
+
},
|
|
53
|
+
policies: [
|
|
54
|
+
{
|
|
55
|
+
policyName: "logs",
|
|
56
|
+
policyDocument: inlinePolicy,
|
|
57
|
+
},
|
|
58
|
+
],
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
const output = await apply(role);
|
|
62
|
+
expect(output.id).toBe("alchemy-test-create-role");
|
|
63
|
+
expect(output.arn).toMatch(
|
|
64
|
+
/^arn:aws:iam::\d+:role\/alchemy-test-create-role$/,
|
|
65
|
+
);
|
|
66
|
+
expect(output.uniqueId).toBeTruthy();
|
|
67
|
+
expect(output.roleId).toBeTruthy();
|
|
68
|
+
expect(output.createDate).toBeInstanceOf(Date);
|
|
69
|
+
|
|
70
|
+
await destroy(role);
|
|
71
|
+
|
|
72
|
+
await assertRoleNotExists("alchemy-test-create-role");
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
test("update role", async () => {
|
|
76
|
+
const roleProps: RoleProps = {
|
|
77
|
+
roleName: "alchemy-test-update-role",
|
|
78
|
+
assumeRolePolicy,
|
|
79
|
+
description: "Updated test role for IAC",
|
|
80
|
+
maxSessionDuration: 7200,
|
|
81
|
+
tags: {
|
|
82
|
+
Environment: "test",
|
|
83
|
+
Updated: "true",
|
|
84
|
+
},
|
|
85
|
+
policies: [
|
|
86
|
+
{
|
|
87
|
+
policyName: "logs",
|
|
88
|
+
policyDocument: inlinePolicy,
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
policyName: "extra",
|
|
92
|
+
policyDocument: {
|
|
93
|
+
Version: "2012-10-17",
|
|
94
|
+
Statement: [
|
|
95
|
+
{
|
|
96
|
+
Effect: "Allow",
|
|
97
|
+
Action: "s3:ListBucket",
|
|
98
|
+
Resource: "*",
|
|
99
|
+
},
|
|
100
|
+
],
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
],
|
|
104
|
+
};
|
|
105
|
+
let role = new Role("alchemy-test-update-role", roleProps);
|
|
106
|
+
|
|
107
|
+
let output = await apply(role);
|
|
108
|
+
expect(output.id).toBe("alchemy-test-update-role");
|
|
109
|
+
expect(output.description).toBe("Updated test role for IAC");
|
|
110
|
+
expect(output.maxSessionDuration).toBe(7200);
|
|
111
|
+
expect(output.tags).toEqual({
|
|
112
|
+
Environment: "test",
|
|
113
|
+
Updated: "true",
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
role = new Role("alchemy-test-update-role", {
|
|
117
|
+
...roleProps,
|
|
118
|
+
description: "Updated test role for IAC",
|
|
119
|
+
policies: [
|
|
120
|
+
{
|
|
121
|
+
policyName: "logs",
|
|
122
|
+
policyDocument: inlinePolicy,
|
|
123
|
+
},
|
|
124
|
+
// 1 policy removed
|
|
125
|
+
],
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
output = await apply(role);
|
|
129
|
+
|
|
130
|
+
expect(output.description).toBe("Updated test role for IAC");
|
|
131
|
+
expect(output.policies).toEqual([
|
|
132
|
+
{
|
|
133
|
+
policyName: "logs",
|
|
134
|
+
policyDocument: inlinePolicy,
|
|
135
|
+
},
|
|
136
|
+
]);
|
|
137
|
+
|
|
138
|
+
await destroy(role);
|
|
139
|
+
|
|
140
|
+
await assertRoleNotExists("alchemy-test-update-role");
|
|
141
|
+
});
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
async function assertRoleNotExists(roleName: string) {
|
|
146
|
+
await expect(
|
|
147
|
+
iam.send(
|
|
148
|
+
new GetRoleCommand({
|
|
149
|
+
RoleName: "alchemy-test-create-role",
|
|
150
|
+
}),
|
|
151
|
+
),
|
|
152
|
+
).rejects.toThrow(NoSuchEntityException);
|
|
153
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DescribeTableCommand,
|
|
3
|
+
DynamoDBClient,
|
|
4
|
+
ResourceNotFoundException,
|
|
5
|
+
} from "@aws-sdk/client-dynamodb";
|
|
6
|
+
import { describe, expect, test } from "bun:test";
|
|
7
|
+
import { apply } from "../../src/apply";
|
|
8
|
+
import { Table } from "../../src/components/aws/table";
|
|
9
|
+
import { destroy } from "../../src/destroy";
|
|
10
|
+
|
|
11
|
+
const dynamo = new DynamoDBClient({});
|
|
12
|
+
|
|
13
|
+
describe("AWS Resources", () => {
|
|
14
|
+
describe("Table", () => {
|
|
15
|
+
test("create table", async () => {
|
|
16
|
+
const table = new Table("alchemy-test-create-table", {
|
|
17
|
+
tableName: "alchemy-test-create-table",
|
|
18
|
+
partitionKey: {
|
|
19
|
+
name: "id",
|
|
20
|
+
type: "S",
|
|
21
|
+
},
|
|
22
|
+
sortKey: {
|
|
23
|
+
name: "timestamp",
|
|
24
|
+
type: "N",
|
|
25
|
+
},
|
|
26
|
+
tags: {
|
|
27
|
+
Environment: "test",
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
const output = await apply(table);
|
|
32
|
+
expect(output.id).toBe("alchemy-test-create-table");
|
|
33
|
+
expect(output.arn).toMatch(
|
|
34
|
+
/^arn:aws:dynamodb:[a-z0-9-]+:\d+:table\/alchemy-test-create-table$/,
|
|
35
|
+
);
|
|
36
|
+
expect(output.tableId).toBeTruthy();
|
|
37
|
+
expect(output.partitionKey).toEqual({
|
|
38
|
+
name: "id",
|
|
39
|
+
type: "S",
|
|
40
|
+
});
|
|
41
|
+
expect(output.sortKey).toEqual({
|
|
42
|
+
name: "timestamp",
|
|
43
|
+
type: "N",
|
|
44
|
+
});
|
|
45
|
+
expect(output.tags).toEqual({
|
|
46
|
+
Environment: "test",
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
// Verify table exists and is active
|
|
50
|
+
const describeResponse = await dynamo.send(
|
|
51
|
+
new DescribeTableCommand({
|
|
52
|
+
TableName: "alchemy-test-create-table",
|
|
53
|
+
}),
|
|
54
|
+
);
|
|
55
|
+
expect(describeResponse.Table?.TableStatus).toBe("ACTIVE");
|
|
56
|
+
|
|
57
|
+
await destroy(table);
|
|
58
|
+
|
|
59
|
+
// Verify table is fully deleted
|
|
60
|
+
await assertTableNotExists("alchemy-test-create-table");
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
async function assertTableNotExists(tableName: string) {
|
|
66
|
+
await expect(
|
|
67
|
+
dynamo.send(
|
|
68
|
+
new DescribeTableCommand({
|
|
69
|
+
TableName: tableName,
|
|
70
|
+
}),
|
|
71
|
+
),
|
|
72
|
+
).rejects.toThrow(ResourceNotFoundException);
|
|
73
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { describe, expect, test } from "bun:test";
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { apply } from "../src/apply";
|
|
5
|
+
import { Bundle } from "../src/components/esbuild";
|
|
6
|
+
import { destroy } from "../src/destroy";
|
|
7
|
+
|
|
8
|
+
const __dirname = path.dirname(new URL(import.meta.url).pathname);
|
|
9
|
+
|
|
10
|
+
describe("esbuild", () => {
|
|
11
|
+
describe("Bundle", () => {
|
|
12
|
+
const outputDir = ".out";
|
|
13
|
+
const outputFile = path.join(outputDir, "handler.js");
|
|
14
|
+
|
|
15
|
+
test("bundle and cleanup", async () => {
|
|
16
|
+
const bundle = new Bundle("test-bundle", {
|
|
17
|
+
entryPoint: path.join(__dirname, "handler.ts"),
|
|
18
|
+
outdir: outputDir,
|
|
19
|
+
format: "esm",
|
|
20
|
+
platform: "node",
|
|
21
|
+
target: "node18",
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
// Apply the bundle
|
|
25
|
+
const output = await apply(bundle);
|
|
26
|
+
expect(output.path).toBe(outputFile);
|
|
27
|
+
expect(output.hash).toBeTruthy();
|
|
28
|
+
|
|
29
|
+
// Verify the file exists and contains our code
|
|
30
|
+
expect(fs.existsSync(outputFile)).toBe(true);
|
|
31
|
+
const contents = await fs.promises.readFile(outputFile, "utf-8");
|
|
32
|
+
expect(contents).toContain("Hello from bundled handler");
|
|
33
|
+
|
|
34
|
+
// Destroy the bundle
|
|
35
|
+
await destroy(bundle);
|
|
36
|
+
|
|
37
|
+
// Verify the file is deleted
|
|
38
|
+
expect(fs.existsSync(outputFile)).toBe(false);
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
});
|
package/test/handler.ts
ADDED
package/tsconfig.json
ADDED
package/Column.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
module.exports = require('./sql/Column')
|
package/Create.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
module.exports = require('./sql/Create')
|
package/Delete.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
module.exports = require('./sql/Delete')
|
package/Drop.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
module.exports = require('./sql/Drop')
|
package/Insert.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
module.exports = require('./sql/Insert')
|
package/Makefile
DELETED
package/README.md
DELETED
|
File without changes
|
package/Select.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
module.exports = require('./sql/Select')
|
package/Table.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
module.exports = require('./sql/Table')
|
package/Transaction.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
module.exports = require('./sql/Transaction')
|
package/Types.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
module.exports = require('./sql/types')
|
package/Update.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
module.exports = require('./sql/Update')
|
package/alchemy.js
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
var F = require('functionally')
|
|
2
|
-
var getType = require('./sql/types/getType')
|
|
3
|
-
|
|
4
|
-
module.exports = function(connString){
|
|
5
|
-
|
|
6
|
-
var engine = require('./engine')(connString)
|
|
7
|
-
|
|
8
|
-
require('./defaultEngine')(engine)
|
|
9
|
-
|
|
10
|
-
var SETTERS = {
|
|
11
|
-
'sql.logfile': function(value){
|
|
12
|
-
require('./config/app').logger.sql = value
|
|
13
|
-
},
|
|
14
|
-
'main.logfile': function(value){
|
|
15
|
-
require('./config/app').logger.main = value
|
|
16
|
-
ensureLogger()
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
var logger
|
|
21
|
-
var info
|
|
22
|
-
var error
|
|
23
|
-
|
|
24
|
-
function ensureLogger(){
|
|
25
|
-
if (!logger){
|
|
26
|
-
logger = require('./loggerFactory')('main')
|
|
27
|
-
info = logger.info
|
|
28
|
-
error = logger.error
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
return F.bindFunctionsOf({
|
|
33
|
-
|
|
34
|
-
set: function(key, value){
|
|
35
|
-
if (key in SETTERS){
|
|
36
|
-
SETTERS[key](value)
|
|
37
|
-
}
|
|
38
|
-
if (logger){
|
|
39
|
-
info('Set "' + key + '" to value ' + value + '.')
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
return this
|
|
43
|
-
},
|
|
44
|
-
|
|
45
|
-
getType: getType,
|
|
46
|
-
|
|
47
|
-
execute: function(query, callback){
|
|
48
|
-
return engine.query.apply(engine, arguments)
|
|
49
|
-
},
|
|
50
|
-
|
|
51
|
-
executeTransaction: function(query, callback){
|
|
52
|
-
return engine.transaction.apply(engine, arguments)
|
|
53
|
-
},
|
|
54
|
-
|
|
55
|
-
engine: engine
|
|
56
|
-
})
|
|
57
|
-
}
|