typeorm-hasura 0.0.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/.env.example +9 -0
- package/LICENSE +21 -0
- package/dev-playground/UserRole.ts +5 -0
- package/dev-playground/action/currencyConverter.ts +60 -0
- package/dev-playground/data-source.ts +21 -0
- package/dev-playground/entity/Org.ts +52 -0
- package/dev-playground/entity/Product.ts +74 -0
- package/dev-playground/entity/User.ts +51 -0
- package/dev-playground/entity/index.ts +3 -0
- package/dev-playground/hasura.ts +35 -0
- package/dev-playground/index.ts +43 -0
- package/dev-playground/migration/1679166386871-next.ts +29 -0
- package/jest.config.js +6 -0
- package/package.json +70 -0
- package/random-notes.md +8 -0
- package/rollup.config.mjs +56 -0
- package/src/builders/Action.ts +27 -0
- package/src/builders/Metadata.ts +96 -0
- package/src/builders/index.ts +2 -0
- package/src/decorators/Column.ts +12 -0
- package/src/decorators/Entity.ts +12 -0
- package/src/decorators/index.ts +2 -0
- package/src/index.ts +5 -0
- package/src/internalStorage.ts +23 -0
- package/src/mappers/databaseUrl.spec.ts +33 -0
- package/src/mappers/databaseUrl.ts +19 -0
- package/src/mappers/graphql.spec.ts +124 -0
- package/src/mappers/graphql.ts +61 -0
- package/src/mappers/hasuraKind.spec.ts +12 -0
- package/src/mappers/hasuraKind.ts +11 -0
- package/src/mappers/index.ts +3 -0
- package/src/mappers/permissions.spec.ts +143 -0
- package/src/mappers/permissions.ts +84 -0
- package/src/mappers/relationships.ts +65 -0
- package/src/mappers/source.ts +29 -0
- package/src/mappers/table.ts +27 -0
- package/src/mappers/tableConfiguration.ts +45 -0
- package/src/mappers/whereClause.spec.ts +85 -0
- package/src/mappers/whereClause.ts +41 -0
- package/src/types/Action.ts +27 -0
- package/src/types/Column.ts +23 -0
- package/src/types/DataSourceOptions.ts +22 -0
- package/src/types/Entity.ts +53 -0
- package/src/types/base.ts +2 -0
- package/src/types/index.ts +7 -0
- package/src/types/permissions.ts +15 -0
- package/src/types/whereClause.ts +75 -0
- package/tsconfig.json +26 -0
package/.env.example
ADDED
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 Utyfua
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// based on https://hasura.io/docs/latest/actions/quickstart/
|
|
2
|
+
import gql from 'graphql-tag';
|
|
3
|
+
import { ActionBuilder } from '../../src/builders';
|
|
4
|
+
import { UserRole } from '../UserRole';
|
|
5
|
+
|
|
6
|
+
export const currencyConverterAction = ActionBuilder.buildV1({
|
|
7
|
+
comment: "Convert currency with real-time exchange rates.",
|
|
8
|
+
handler: "https://api.exchangerate.host/convert",
|
|
9
|
+
definitionType: gql`
|
|
10
|
+
type Query {
|
|
11
|
+
currencyConverter(CurrencyInfo: ConvertCurrencyInputParams!): ConvertedCurrency
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
input ConvertCurrencyInputParams {
|
|
15
|
+
from: String
|
|
16
|
+
to: String
|
|
17
|
+
amt: Int
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
type ConvertedCurrency {
|
|
21
|
+
date: String
|
|
22
|
+
info: ConvertedCurrencyInfo
|
|
23
|
+
query: ConvertedCurrencyQuery
|
|
24
|
+
result: Float
|
|
25
|
+
success: Boolean
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
type ConvertedCurrencyInfo {
|
|
29
|
+
rate: Float
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
type ConvertedCurrencyQuery {
|
|
33
|
+
amount: Int
|
|
34
|
+
from: String
|
|
35
|
+
to: String
|
|
36
|
+
}
|
|
37
|
+
`,
|
|
38
|
+
permissions: [
|
|
39
|
+
{ role: UserRole.user },
|
|
40
|
+
],
|
|
41
|
+
nativeDefinition: {
|
|
42
|
+
request_transform: {
|
|
43
|
+
method: "GET",
|
|
44
|
+
query_params: {
|
|
45
|
+
"amount": "{{$body.input.CurrencyInfo.amt}}",
|
|
46
|
+
"from": "{{$body.input.CurrencyInfo.from}}",
|
|
47
|
+
"to": "{{$body.input.CurrencyInfo.to}}"
|
|
48
|
+
},
|
|
49
|
+
request_headers: {
|
|
50
|
+
"add_headers": {},
|
|
51
|
+
"remove_headers": [
|
|
52
|
+
"content-type"
|
|
53
|
+
]
|
|
54
|
+
},
|
|
55
|
+
template_engine: "Kriti",
|
|
56
|
+
// @ts-ignore types are wrong!
|
|
57
|
+
version: 2,
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
})
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import "reflect-metadata"
|
|
2
|
+
import { DataSource } from "typeorm"
|
|
3
|
+
import * as entities from "./entity"
|
|
4
|
+
|
|
5
|
+
const { DB_URL, DB_HOST, DB_PORT, DB_USERNAME, DB_PASSWORD, DB_NAME, DB_SCHEMA } = process.env
|
|
6
|
+
|
|
7
|
+
export const AppDataSource = new DataSource({
|
|
8
|
+
type: "postgres",
|
|
9
|
+
url: DB_URL,
|
|
10
|
+
host: DB_HOST,
|
|
11
|
+
port: Number(DB_PORT),
|
|
12
|
+
username: DB_USERNAME,
|
|
13
|
+
password: DB_PASSWORD,
|
|
14
|
+
database: DB_NAME,
|
|
15
|
+
schema: DB_SCHEMA,
|
|
16
|
+
synchronize: false,
|
|
17
|
+
logging: false,
|
|
18
|
+
entities: Object.values(entities),
|
|
19
|
+
migrations: ['./test/migration/*.ts'],
|
|
20
|
+
subscribers: [],
|
|
21
|
+
})
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Entity,
|
|
3
|
+
PrimaryGeneratedColumn,
|
|
4
|
+
Column,
|
|
5
|
+
OneToMany,
|
|
6
|
+
BaseEntity
|
|
7
|
+
} from 'typeorm';
|
|
8
|
+
import { HasuraEntity, HasuraColumn } from '../../src';
|
|
9
|
+
import { Product } from './Product';
|
|
10
|
+
import { User } from './User';
|
|
11
|
+
import { UserRole } from '../UserRole';
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@Entity({ schema: 'public', name: 'Org' })
|
|
15
|
+
@HasuraEntity<Org>({
|
|
16
|
+
customName: 'Org',
|
|
17
|
+
permissions: {
|
|
18
|
+
[UserRole.user]: {
|
|
19
|
+
where: {
|
|
20
|
+
users: {
|
|
21
|
+
id: 'X-Hasura-User-Id'
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
select: true,
|
|
25
|
+
update: true,
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
})
|
|
29
|
+
export class Org extends BaseEntity {
|
|
30
|
+
@PrimaryGeneratedColumn('uuid')
|
|
31
|
+
@HasuraColumn({
|
|
32
|
+
permissions: {
|
|
33
|
+
[UserRole.user]: ['select']
|
|
34
|
+
}
|
|
35
|
+
})
|
|
36
|
+
id!: string;
|
|
37
|
+
|
|
38
|
+
@Column({ type: 'text', nullable: true })
|
|
39
|
+
@HasuraColumn({
|
|
40
|
+
// customName: 'myOrgName',
|
|
41
|
+
permissions: {
|
|
42
|
+
[UserRole.user]: ['select', 'update']
|
|
43
|
+
}
|
|
44
|
+
})
|
|
45
|
+
name!: string;
|
|
46
|
+
|
|
47
|
+
@OneToMany(() => User, (user) => user.org)
|
|
48
|
+
users!: User[];
|
|
49
|
+
|
|
50
|
+
@OneToMany(() => Product, (product) => product.org)
|
|
51
|
+
products!: Product[];
|
|
52
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Entity,
|
|
3
|
+
PrimaryGeneratedColumn,
|
|
4
|
+
Column, ManyToOne,
|
|
5
|
+
JoinColumn,
|
|
6
|
+
BaseEntity
|
|
7
|
+
} from 'typeorm';
|
|
8
|
+
import { HasuraColumn, HasuraEntity } from '../../src';
|
|
9
|
+
import { User } from './User';
|
|
10
|
+
import { Org } from "./Org";
|
|
11
|
+
import { UserRole } from '../UserRole';
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@Entity({ schema: 'public', name: 'Product' })
|
|
15
|
+
@HasuraEntity<Product>({
|
|
16
|
+
customName: 'Product',
|
|
17
|
+
permissions: {
|
|
18
|
+
[UserRole.user]: {
|
|
19
|
+
where: [
|
|
20
|
+
{ userId: 'X-Hasura-User-Id' },
|
|
21
|
+
{
|
|
22
|
+
org: {
|
|
23
|
+
users: {
|
|
24
|
+
id: 'X-Hasura-User-Id'
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
],
|
|
29
|
+
select: true,
|
|
30
|
+
update: true,
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
})
|
|
34
|
+
export class Product extends BaseEntity {
|
|
35
|
+
@PrimaryGeneratedColumn('uuid')
|
|
36
|
+
@HasuraColumn({
|
|
37
|
+
permissions: {
|
|
38
|
+
[UserRole.user]: ['select']
|
|
39
|
+
}
|
|
40
|
+
})
|
|
41
|
+
id!: string;
|
|
42
|
+
|
|
43
|
+
@Column({ type: 'text', nullable: true })
|
|
44
|
+
@HasuraColumn({
|
|
45
|
+
permissions: {
|
|
46
|
+
[UserRole.user]: ['select', 'update']
|
|
47
|
+
}
|
|
48
|
+
})
|
|
49
|
+
name!: string;
|
|
50
|
+
|
|
51
|
+
@Column({ name: 'orgId', type: 'uuid', nullable: true })
|
|
52
|
+
@HasuraColumn({
|
|
53
|
+
permissions: {
|
|
54
|
+
[UserRole.user]: ['select']
|
|
55
|
+
}
|
|
56
|
+
})
|
|
57
|
+
orgId!: string;
|
|
58
|
+
|
|
59
|
+
@ManyToOne(() => Org, (org) => org.products)
|
|
60
|
+
@JoinColumn({ name: 'orgId' })
|
|
61
|
+
org!: Org;
|
|
62
|
+
|
|
63
|
+
@Column({ name: 'userId', type: 'uuid', nullable: true })
|
|
64
|
+
@HasuraColumn({
|
|
65
|
+
permissions: {
|
|
66
|
+
[UserRole.user]: ['select']
|
|
67
|
+
}
|
|
68
|
+
})
|
|
69
|
+
userId!: string;
|
|
70
|
+
|
|
71
|
+
@ManyToOne(() => User, (user) => user.products)
|
|
72
|
+
@JoinColumn({ name: 'userId' })
|
|
73
|
+
user!: User;
|
|
74
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Entity,
|
|
3
|
+
PrimaryGeneratedColumn,
|
|
4
|
+
Column,
|
|
5
|
+
OneToMany,
|
|
6
|
+
ManyToOne,
|
|
7
|
+
JoinColumn,
|
|
8
|
+
BaseEntity,
|
|
9
|
+
} from 'typeorm';
|
|
10
|
+
import { HasuraColumn, HasuraEntity } from '../../src';
|
|
11
|
+
import { Org } from './Org';
|
|
12
|
+
import { Product } from './Product';
|
|
13
|
+
import { UserRole } from '../UserRole';
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@Entity({ schema: 'public', name: 'User' })
|
|
17
|
+
@HasuraEntity<User>({
|
|
18
|
+
customName: 'User',
|
|
19
|
+
permissions: {
|
|
20
|
+
[UserRole.user]: {
|
|
21
|
+
select: true,
|
|
22
|
+
update: {
|
|
23
|
+
where: {
|
|
24
|
+
id: 'X-Hasura-User-Id'
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
})
|
|
30
|
+
export class User extends BaseEntity {
|
|
31
|
+
@PrimaryGeneratedColumn('uuid')
|
|
32
|
+
@HasuraColumn({ permissions: { [UserRole.user]: ['select'] } })
|
|
33
|
+
id!: string;
|
|
34
|
+
|
|
35
|
+
@Column({ type: 'text', nullable: true })
|
|
36
|
+
@HasuraColumn({ permissions: { [UserRole.user]: ['select', 'update'] } })
|
|
37
|
+
name!: string;
|
|
38
|
+
|
|
39
|
+
@Column({ name: 'orgId', type: 'uuid', nullable: true })
|
|
40
|
+
@HasuraColumn({ permissions: { [UserRole.user]: ['select'] } })
|
|
41
|
+
orgId!: string;
|
|
42
|
+
|
|
43
|
+
@ManyToOne(() => Org, (org) => org.users)
|
|
44
|
+
@JoinColumn({ name: 'orgId' })
|
|
45
|
+
org!: Org;
|
|
46
|
+
|
|
47
|
+
@OneToMany(() => Product, (product) => product.user)
|
|
48
|
+
products!: Product[];
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { MetadataBuilder } from "../src";
|
|
2
|
+
import { currencyConverterAction } from "./action/currencyConverter";
|
|
3
|
+
import { AppDataSource } from "./data-source"
|
|
4
|
+
import { writeFile, mkdir } from "fs/promises"
|
|
5
|
+
|
|
6
|
+
async function convert() {
|
|
7
|
+
const metadata = await new MetadataBuilder()
|
|
8
|
+
.addSource({
|
|
9
|
+
name: "public",
|
|
10
|
+
dataSource: AppDataSource,
|
|
11
|
+
databaseUrl: process.env.HASURA_DATABASE_URL,
|
|
12
|
+
defaultSelectPermissionLimit: 50,
|
|
13
|
+
})
|
|
14
|
+
.addActions([
|
|
15
|
+
currencyConverterAction,
|
|
16
|
+
])
|
|
17
|
+
.getMetadata()
|
|
18
|
+
|
|
19
|
+
await mkdir("tmp/output", { recursive: true })
|
|
20
|
+
.catch(error => console.log(error));
|
|
21
|
+
await writeFile(
|
|
22
|
+
`tmp/output/metadata-${Date.now()}.json`,
|
|
23
|
+
JSON.stringify(metadata, null, 2)
|
|
24
|
+
)
|
|
25
|
+
AppDataSource.close();
|
|
26
|
+
console.log("Done and done");
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
AppDataSource.initialize()
|
|
30
|
+
.then(convert)
|
|
31
|
+
.catch(error => console.log(error))
|
|
32
|
+
|
|
33
|
+
if (process.env.DEV_KEEP_ALIVE) {
|
|
34
|
+
setInterval(() => 1, 1000 * 60 * 60)
|
|
35
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { AppDataSource } from "./data-source";
|
|
2
|
+
import { User, Org, Product } from "./entity";
|
|
3
|
+
|
|
4
|
+
async function main() {
|
|
5
|
+
try {
|
|
6
|
+
await AppDataSource.initialize();
|
|
7
|
+
|
|
8
|
+
console.log("Inserting a new organization into the database...");
|
|
9
|
+
const org = new Org();
|
|
10
|
+
org.name = "Example Organization";
|
|
11
|
+
await org.save();
|
|
12
|
+
console.log("Saved a new organization with id: " + org.id);
|
|
13
|
+
|
|
14
|
+
console.log("Inserting a new user into the database...");
|
|
15
|
+
const user = new User();
|
|
16
|
+
user.name = "John Doe";
|
|
17
|
+
user.orgId = org.id;
|
|
18
|
+
await user.save();
|
|
19
|
+
console.log("Saved a new user with id: " + user.id);
|
|
20
|
+
|
|
21
|
+
console.log("Inserting a new product into the database...");
|
|
22
|
+
const product = new Product();
|
|
23
|
+
product.name = "Example Product";
|
|
24
|
+
product.orgId = org.id;
|
|
25
|
+
product.userId = user.id;
|
|
26
|
+
await product.save();
|
|
27
|
+
console.log("Saved a new product with id: " + product.id);
|
|
28
|
+
|
|
29
|
+
console.log("Loading organizations, users, and products from the database...");
|
|
30
|
+
const organizations = await Org.find();
|
|
31
|
+
const users = await User.find();
|
|
32
|
+
const products = await Product.find();
|
|
33
|
+
console.log("Loaded organizations: ", organizations);
|
|
34
|
+
console.log("Loaded users: ", users);
|
|
35
|
+
console.log("Loaded products: ", products);
|
|
36
|
+
|
|
37
|
+
console.log("Here you can set up and run express / fastify / any other framework.");
|
|
38
|
+
} catch (error) {
|
|
39
|
+
console.log(error);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
main();
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { MigrationInterface, QueryRunner } from "typeorm";
|
|
2
|
+
|
|
3
|
+
const schema = process.env.DB_SCHEMA || "${schema}";
|
|
4
|
+
|
|
5
|
+
if (schema.includes('"') || schema.includes("'") || schema.includes("\\")) {
|
|
6
|
+
throw new Error("Invalid schema name");
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export class next1679166386871 implements MigrationInterface {
|
|
10
|
+
name = 'next1679166386871'
|
|
11
|
+
|
|
12
|
+
async up(queryRunner: QueryRunner): Promise<void> {
|
|
13
|
+
await queryRunner.query(`CREATE TABLE "${schema}"."User" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "name" text, "orgId" uuid, CONSTRAINT "PK_9862f679340fb2388436a5ab3e4" PRIMARY KEY ("id"))`);
|
|
14
|
+
await queryRunner.query(`CREATE TABLE "${schema}"."Product" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "name" text, "orgId" uuid, "userId" uuid, CONSTRAINT "PK_9fc040db7872192bbc26c515710" PRIMARY KEY ("id"))`);
|
|
15
|
+
await queryRunner.query(`CREATE TABLE "${schema}"."Org" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "name" text, CONSTRAINT "PK_cca1cae86d5c2eefca56675b245" PRIMARY KEY ("id"))`);
|
|
16
|
+
await queryRunner.query(`ALTER TABLE "${schema}"."User" ADD CONSTRAINT "FK_da2f97fadc32136438de8d6a7a7" FOREIGN KEY ("orgId") REFERENCES "${schema}"."Org"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`);
|
|
17
|
+
await queryRunner.query(`ALTER TABLE "${schema}"."Product" ADD CONSTRAINT "FK_0426b5b66a3ad86d93237917bbf" FOREIGN KEY ("orgId") REFERENCES "${schema}"."Org"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`);
|
|
18
|
+
await queryRunner.query(`ALTER TABLE "${schema}"."Product" ADD CONSTRAINT "FK_de75905c3b4987f4b5bb1472644" FOREIGN KEY ("userId") REFERENCES "${schema}"."User"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
async down(queryRunner: QueryRunner): Promise<void> {
|
|
22
|
+
await queryRunner.query(`ALTER TABLE "${schema}"."Product" DROP CONSTRAINT "FK_de75905c3b4987f4b5bb1472644"`);
|
|
23
|
+
await queryRunner.query(`ALTER TABLE "${schema}"."Product" DROP CONSTRAINT "FK_0426b5b66a3ad86d93237917bbf"`);
|
|
24
|
+
await queryRunner.query(`ALTER TABLE "${schema}"."User" DROP CONSTRAINT "FK_da2f97fadc32136438de8d6a7a7"`);
|
|
25
|
+
await queryRunner.query(`DROP TABLE "${schema}"."Org"`);
|
|
26
|
+
await queryRunner.query(`DROP TABLE "${schema}"."Product"`);
|
|
27
|
+
await queryRunner.query(`DROP TABLE "${schema}"."User"`);
|
|
28
|
+
}
|
|
29
|
+
}
|
package/jest.config.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "typeorm-hasura",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"hasura",
|
|
7
|
+
"typeorm"
|
|
8
|
+
],
|
|
9
|
+
"main": "./dist/cjs/index.js",
|
|
10
|
+
"module": "./dist/esm/index.js",
|
|
11
|
+
"types": "./dist/esm/index.d.ts",
|
|
12
|
+
"type": "commonjs",
|
|
13
|
+
"repository": {
|
|
14
|
+
"type": "git",
|
|
15
|
+
"url": "https://github.com/utyfua/typeorm-hasura.git"
|
|
16
|
+
},
|
|
17
|
+
"bugs": {
|
|
18
|
+
"url": "https://github.com/utyfua/typeorm-hasura/issues"
|
|
19
|
+
},
|
|
20
|
+
"scripts": {
|
|
21
|
+
"clean": "rimraf dist/*",
|
|
22
|
+
"prebuild": "run-s clean",
|
|
23
|
+
"build": "run-s build:tsc build:rollup",
|
|
24
|
+
"build:tsc": "tsc --module commonjs",
|
|
25
|
+
"build:rollup": "rollup -c ",
|
|
26
|
+
"typeorm": "typeorm-ts-node-esm",
|
|
27
|
+
"test": "jest",
|
|
28
|
+
"test:watch": "jest --watch",
|
|
29
|
+
"play:gen": "npx env-cmd npx typeorm-ts-node-esm migration:generate ./dev-playground/migration/next -d ./dev-playground/data-source",
|
|
30
|
+
"play:up": "npx env-cmd npx typeorm-ts-node-esm migration:run -d ./dev-playground/data-source",
|
|
31
|
+
"play:down": "npx env-cmd npx typeorm-ts-node-esm migration:revert -d ./dev-playground/data-source",
|
|
32
|
+
"play:start": "npx env-cmd ts-node dev-playground/index.ts",
|
|
33
|
+
"play:run": "npx env-cmd ts-node dev-playground/hasura.ts"
|
|
34
|
+
},
|
|
35
|
+
"author": {
|
|
36
|
+
"name": "Utyfua",
|
|
37
|
+
"email": "utyfua@gmail.com"
|
|
38
|
+
},
|
|
39
|
+
"license": "MIT",
|
|
40
|
+
"dependencies": {
|
|
41
|
+
"graphql": "^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0",
|
|
42
|
+
"graphql-tag": "^2.0.0",
|
|
43
|
+
"lodash.snakecase": "^4.1.1"
|
|
44
|
+
},
|
|
45
|
+
"peerDependencies": {
|
|
46
|
+
"graphql": "^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0",
|
|
47
|
+
"graphql-tag": "^2.0.0",
|
|
48
|
+
"typeorm": "^0.3.0"
|
|
49
|
+
},
|
|
50
|
+
"devDependencies": {
|
|
51
|
+
"@rollup/plugin-babel": "^6.0.3",
|
|
52
|
+
"@rollup/plugin-commonjs": "^24.0.1",
|
|
53
|
+
"@rollup/plugin-node-resolve": "^15.0.2",
|
|
54
|
+
"@rollup/plugin-typescript": "^11.1.0",
|
|
55
|
+
"@types/jest": "^29.5.0",
|
|
56
|
+
"@types/lodash.snakecase": "^4.1.7",
|
|
57
|
+
"@types/node": "^18.14.0",
|
|
58
|
+
"env-cmd": "^10.1.0",
|
|
59
|
+
"hasura-metadata-types": "^2.22.1",
|
|
60
|
+
"jest": "^29.5.0",
|
|
61
|
+
"npm-run-all": "^4.1.5",
|
|
62
|
+
"pg": "^8.10.0",
|
|
63
|
+
"reflect-metadata": "^0.1.13",
|
|
64
|
+
"rimraf": "^3.0.2",
|
|
65
|
+
"rollup": "^2.79.1",
|
|
66
|
+
"ts-jest": "^29.0.5",
|
|
67
|
+
"ts-node": "^10.9.1",
|
|
68
|
+
"typeorm": "^0.3.12"
|
|
69
|
+
}
|
|
70
|
+
}
|
package/random-notes.md
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
|
|
2
|
+
import nodeResolve from '@rollup/plugin-node-resolve';
|
|
3
|
+
import commonjs from '@rollup/plugin-commonjs';
|
|
4
|
+
import typescript from '@rollup/plugin-typescript';
|
|
5
|
+
import { babel } from '@rollup/plugin-babel';
|
|
6
|
+
|
|
7
|
+
import pkg from './package.json' assert { type: 'json' };
|
|
8
|
+
|
|
9
|
+
const banner = `
|
|
10
|
+
/*!
|
|
11
|
+
* ${pkg.name} v${pkg.version} by ${pkg.author}
|
|
12
|
+
* ${"homepage" in pkg ? pkg.homepage : `https://github.com/${pkg.repository}`}
|
|
13
|
+
* @license ${pkg.license}
|
|
14
|
+
*/
|
|
15
|
+
`.trim()
|
|
16
|
+
|
|
17
|
+
const defaultExportOutro = `
|
|
18
|
+
module.exports = exports.default || {}
|
|
19
|
+
Object.entries(exports).forEach(([key, value]) => { module.exports[key] = value })
|
|
20
|
+
`
|
|
21
|
+
|
|
22
|
+
export default {
|
|
23
|
+
input: 'src/index.ts',
|
|
24
|
+
output: [
|
|
25
|
+
{
|
|
26
|
+
file: pkg.main,
|
|
27
|
+
format: 'cjs',
|
|
28
|
+
sourcemap: true,
|
|
29
|
+
exports: 'named',
|
|
30
|
+
outro: defaultExportOutro,
|
|
31
|
+
banner
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
file: pkg.module,
|
|
35
|
+
format: 'es',
|
|
36
|
+
sourcemap: true,
|
|
37
|
+
exports: 'named',
|
|
38
|
+
banner
|
|
39
|
+
}
|
|
40
|
+
],
|
|
41
|
+
external: [
|
|
42
|
+
...Object.keys(pkg.dependencies || {}),
|
|
43
|
+
...Object.keys(pkg.peerDependencies || {}),
|
|
44
|
+
],
|
|
45
|
+
plugins: [
|
|
46
|
+
nodeResolve(),
|
|
47
|
+
babel({
|
|
48
|
+
exclude: 'node_modules/**',
|
|
49
|
+
}),
|
|
50
|
+
commonjs(),
|
|
51
|
+
// Compile TypeScript files
|
|
52
|
+
typescript({
|
|
53
|
+
declaration: true,
|
|
54
|
+
}),
|
|
55
|
+
],
|
|
56
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type * as Hasura from "hasura-metadata-types";
|
|
2
|
+
import { getGraphQLDefinitions } from "../mappers/graphql";
|
|
3
|
+
import { ActionBuildResult, ActionCustomMetadataV1 } from "../types";
|
|
4
|
+
|
|
5
|
+
export class ActionBuilder {
|
|
6
|
+
static buildV1(customMetadata: ActionCustomMetadataV1): ActionBuildResult {
|
|
7
|
+
const defs = getGraphQLDefinitions(customMetadata.definitionType);
|
|
8
|
+
if (defs.baseActions.length !== 1)
|
|
9
|
+
throw new Error(`Expected exactly one base action, got ${defs.baseActions.length}`);
|
|
10
|
+
const [baseAction] = defs.baseActions;
|
|
11
|
+
const action: Hasura.Action = {
|
|
12
|
+
name: baseAction.name,
|
|
13
|
+
comment: customMetadata.comment,
|
|
14
|
+
permissions: customMetadata.permissions,
|
|
15
|
+
definition: {
|
|
16
|
+
...baseAction.definition,
|
|
17
|
+
forward_client_headers: customMetadata.forwardClientHeaders || false,
|
|
18
|
+
handler: customMetadata.handler,
|
|
19
|
+
...customMetadata.nativeDefinition,
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
return {
|
|
23
|
+
actions: [action],
|
|
24
|
+
custom_types: defs.custom_types,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
}
|