postgresdk 0.18.1 → 0.18.2
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/dist/cli.js +0 -0
- package/package.json +1 -1
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/core/operations.d.ts +0 -68
- package/dist/emit-api-contract.d.ts +0 -60
- package/dist/emit-client.d.ts.map +0 -1
- package/dist/emit-client.js +0 -114
- package/dist/emit-client.js.map +0 -1
- package/dist/emit-include-builder.d.ts.map +0 -1
- package/dist/emit-include-builder.js +0 -30
- package/dist/emit-include-builder.js.map +0 -1
- package/dist/emit-include-loader.d.ts.map +0 -1
- package/dist/emit-include-loader.js +0 -299
- package/dist/emit-include-loader.js.map +0 -1
- package/dist/emit-include-spec.d.ts.map +0 -1
- package/dist/emit-include-spec.js +0 -26
- package/dist/emit-include-spec.js.map +0 -1
- package/dist/emit-logger.d.ts.map +0 -1
- package/dist/emit-logger.js +0 -35
- package/dist/emit-logger.js.map +0 -1
- package/dist/emit-router.d.ts +0 -5
- package/dist/emit-routes.d.ts.map +0 -1
- package/dist/emit-routes.js +0 -208
- package/dist/emit-routes.js.map +0 -1
- package/dist/emit-server-index.d.ts +0 -5
- package/dist/emit-types.d.ts.map +0 -1
- package/dist/emit-types.js +0 -51
- package/dist/emit-types.js.map +0 -1
- package/dist/emit-zod.d.ts.map +0 -1
- package/dist/emit-zod.js +0 -43
- package/dist/emit-zod.js.map +0 -1
- package/dist/gen.config.d.ts +0 -10
- package/dist/gen.config.js +0 -10
- package/dist/gen.config.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/introspect.d.ts.map +0 -1
- package/dist/introspect.js +0 -132
- package/dist/introspect.js.map +0 -1
- package/dist/rel-classify.d.ts.map +0 -1
- package/dist/rel-classify.js +0 -52
- package/dist/rel-classify.js.map +0 -1
- package/dist/src/cli.d.ts +0 -2
- package/dist/src/cli.js +0 -39
- package/dist/src/cli.js.map +0 -1
- package/dist/src/emit-client.d.ts +0 -3
- package/dist/src/emit-client.js +0 -114
- package/dist/src/emit-client.js.map +0 -1
- package/dist/src/emit-include-builder.d.ts +0 -2
- package/dist/src/emit-include-builder.js +0 -30
- package/dist/src/emit-include-builder.js.map +0 -1
- package/dist/src/emit-include-loader.d.ts +0 -9
- package/dist/src/emit-include-loader.js +0 -299
- package/dist/src/emit-include-loader.js.map +0 -1
- package/dist/src/emit-include-spec.d.ts +0 -2
- package/dist/src/emit-include-spec.js +0 -26
- package/dist/src/emit-include-spec.js.map +0 -1
- package/dist/src/emit-logger.d.ts +0 -1
- package/dist/src/emit-logger.js +0 -35
- package/dist/src/emit-logger.js.map +0 -1
- package/dist/src/emit-routes.d.ts +0 -20
- package/dist/src/emit-routes.js +0 -208
- package/dist/src/emit-routes.js.map +0 -1
- package/dist/src/emit-types.d.ts +0 -5
- package/dist/src/emit-types.js +0 -51
- package/dist/src/emit-types.js.map +0 -1
- package/dist/src/emit-zod.d.ts +0 -5
- package/dist/src/emit-zod.js +0 -43
- package/dist/src/emit-zod.js.map +0 -1
- package/dist/src/index.d.ts +0 -1
- package/dist/src/index.js +0 -83
- package/dist/src/index.js.map +0 -1
- package/dist/src/introspect.d.ts +0 -26
- package/dist/src/introspect.js +0 -132
- package/dist/src/introspect.js.map +0 -1
- package/dist/src/rel-classify.d.ts +0 -10
- package/dist/src/rel-classify.js +0 -52
- package/dist/src/rel-classify.js.map +0 -1
- package/dist/src/utils.d.ts +0 -6
- package/dist/src/utils.js +0 -17
- package/dist/src/utils.js.map +0 -1
- package/dist/utils.d.ts.map +0 -1
- package/dist/utils.js +0 -17
- package/dist/utils.js.map +0 -1
package/dist/cli.js
CHANGED
|
File without changes
|
package/package.json
CHANGED
package/dist/cli.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
|
package/dist/cli.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAEnC,2BAA2B;AAC3B,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AACtC,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,iBAAiB,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;AAC1F,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC;AAEpC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAEnC,mBAAmB;AACnB,IAAI,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;IACtD,OAAO,CAAC,GAAG,CAAC,eAAe,OAAO,EAAE,CAAC,CAAC;IACtC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,gBAAgB;AAChB,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;IACnD,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;CAUb,CAAC,CAAC;IACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,kBAAkB;AAClB,IAAI,UAAU,GAAG,sBAAsB,CAAC;AACxC,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,UAAU,CAAC,CAAC;AACxE,IAAI,WAAW,KAAK,CAAC,CAAC,IAAI,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC,EAAE,CAAC;IAChD,UAAU,GAAG,IAAI,CAAC,WAAW,GAAG,CAAC,CAAE,CAAC;AACtC,CAAC;AAED,gBAAgB;AAChB,IAAI,CAAC;IACH,MAAM,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,UAAU,CAAC,CAAC,CAAC;AACrD,CAAC;AAAC,OAAO,GAAG,EAAE,CAAC;IACb,OAAO,CAAC,KAAK,CAAC,sBAAsB,EAAE,GAAG,CAAC,CAAC;IAC3C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC"}
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Core database operations that are framework-agnostic.
|
|
3
|
-
* These functions handle the actual database logic and can be used by any framework adapter.
|
|
4
|
-
*/
|
|
5
|
-
export interface DatabaseClient {
|
|
6
|
-
query: (text: string, params?: any[]) => Promise<{
|
|
7
|
-
rows: any[];
|
|
8
|
-
}>;
|
|
9
|
-
}
|
|
10
|
-
export interface OperationContext {
|
|
11
|
-
pg: DatabaseClient;
|
|
12
|
-
table: string;
|
|
13
|
-
pkColumns: string[];
|
|
14
|
-
softDeleteColumn?: string | null;
|
|
15
|
-
includeMethodsDepth: number;
|
|
16
|
-
}
|
|
17
|
-
/**
|
|
18
|
-
* CREATE operation - Insert a new record
|
|
19
|
-
*/
|
|
20
|
-
export declare function createRecord(ctx: OperationContext, data: Record<string, any>): Promise<{
|
|
21
|
-
data?: any;
|
|
22
|
-
error?: string;
|
|
23
|
-
issues?: any;
|
|
24
|
-
status: number;
|
|
25
|
-
}>;
|
|
26
|
-
/**
|
|
27
|
-
* READ operation - Get a record by primary key
|
|
28
|
-
*/
|
|
29
|
-
export declare function getByPk(ctx: OperationContext, pkValues: any[]): Promise<{
|
|
30
|
-
data?: any;
|
|
31
|
-
error?: string;
|
|
32
|
-
status: number;
|
|
33
|
-
}>;
|
|
34
|
-
/**
|
|
35
|
-
* LIST operation - Get multiple records with optional filters
|
|
36
|
-
*/
|
|
37
|
-
export declare function listRecords(ctx: OperationContext, params: {
|
|
38
|
-
where?: any;
|
|
39
|
-
limit?: number;
|
|
40
|
-
offset?: number;
|
|
41
|
-
include?: any;
|
|
42
|
-
orderBy?: string | string[];
|
|
43
|
-
order?: "asc" | "desc" | ("asc" | "desc")[];
|
|
44
|
-
}): Promise<{
|
|
45
|
-
data?: any;
|
|
46
|
-
error?: string;
|
|
47
|
-
issues?: any;
|
|
48
|
-
needsIncludes?: boolean;
|
|
49
|
-
includeSpec?: any;
|
|
50
|
-
status: number;
|
|
51
|
-
}>;
|
|
52
|
-
/**
|
|
53
|
-
* UPDATE operation - Update a record by primary key
|
|
54
|
-
*/
|
|
55
|
-
export declare function updateRecord(ctx: OperationContext, pkValues: any[], updateData: Record<string, any>): Promise<{
|
|
56
|
-
data?: any;
|
|
57
|
-
error?: string;
|
|
58
|
-
issues?: any;
|
|
59
|
-
status: number;
|
|
60
|
-
}>;
|
|
61
|
-
/**
|
|
62
|
-
* DELETE operation - Delete or soft-delete a record by primary key
|
|
63
|
-
*/
|
|
64
|
-
export declare function deleteRecord(ctx: OperationContext, pkValues: any[]): Promise<{
|
|
65
|
-
data?: any;
|
|
66
|
-
error?: string;
|
|
67
|
-
status: number;
|
|
68
|
-
}>;
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import type { Model } from "./introspect";
|
|
2
|
-
import type { Config, AuthConfig } from "./types";
|
|
3
|
-
export interface ApiContract {
|
|
4
|
-
version: string;
|
|
5
|
-
generatedAt: string;
|
|
6
|
-
description: string;
|
|
7
|
-
authentication?: {
|
|
8
|
-
type: string;
|
|
9
|
-
description: string;
|
|
10
|
-
};
|
|
11
|
-
resources: ResourceContract[];
|
|
12
|
-
relationships: RelationshipContract[];
|
|
13
|
-
}
|
|
14
|
-
export interface ResourceContract {
|
|
15
|
-
name: string;
|
|
16
|
-
tableName: string;
|
|
17
|
-
description: string;
|
|
18
|
-
endpoints: EndpointContract[];
|
|
19
|
-
fields: FieldContract[];
|
|
20
|
-
}
|
|
21
|
-
export interface EndpointContract {
|
|
22
|
-
method: string;
|
|
23
|
-
path: string;
|
|
24
|
-
description: string;
|
|
25
|
-
requestBody?: any;
|
|
26
|
-
responseBody?: any;
|
|
27
|
-
queryParameters?: any;
|
|
28
|
-
}
|
|
29
|
-
export interface FieldContract {
|
|
30
|
-
name: string;
|
|
31
|
-
type: string;
|
|
32
|
-
required: boolean;
|
|
33
|
-
description: string;
|
|
34
|
-
foreignKey?: {
|
|
35
|
-
table: string;
|
|
36
|
-
field: string;
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
|
-
export interface RelationshipContract {
|
|
40
|
-
from: string;
|
|
41
|
-
to: string;
|
|
42
|
-
type: "one-to-many" | "many-to-one" | "many-to-many";
|
|
43
|
-
description: string;
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* Generate a comprehensive API contract in JSON format
|
|
47
|
-
*/
|
|
48
|
-
export declare function generateApiContract(model: Model, config: Config & {
|
|
49
|
-
auth?: AuthConfig;
|
|
50
|
-
}): ApiContract;
|
|
51
|
-
/**
|
|
52
|
-
* Generate a human-readable markdown version of the contract
|
|
53
|
-
*/
|
|
54
|
-
export declare function generateApiContractMarkdown(contract: ApiContract): string;
|
|
55
|
-
/**
|
|
56
|
-
* Emit the API contract as TypeScript code that can be served as an endpoint
|
|
57
|
-
*/
|
|
58
|
-
export declare function emitApiContract(model: Model, config: Config & {
|
|
59
|
-
auth?: AuthConfig;
|
|
60
|
-
}): string;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"emit-client.d.ts","sourceRoot":"","sources":["../src/emit-client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAG1C,wBAAgB,UAAU,CAAC,KAAK,EAAE,KAAK,UA8FtC;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,KAAK,EAAE,UAmB9C"}
|
package/dist/emit-client.js
DELETED
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
import { pascal } from "./utils";
|
|
2
|
-
export function emitClient(table) {
|
|
3
|
-
const Type = pascal(table.name);
|
|
4
|
-
// Normalize PKs
|
|
5
|
-
const pkCols = Array.isArray(table.pk)
|
|
6
|
-
? table.pk
|
|
7
|
-
: table.pk
|
|
8
|
-
? [table.pk]
|
|
9
|
-
: [];
|
|
10
|
-
const safePk = pkCols.length ? pkCols : ["id"];
|
|
11
|
-
const hasCompositePk = safePk.length > 1;
|
|
12
|
-
const pkType = hasCompositePk ? `{ ${safePk.map((c) => `${c}: string`).join("; ")} }` : `string`;
|
|
13
|
-
const pkPathExpr = hasCompositePk ? safePk.map((c) => `pk.${c}`).join(` + "/" + `) : `pk`;
|
|
14
|
-
return `/* Generated. Do not edit. */
|
|
15
|
-
import type { ${Type}IncludeSpec } from "./include-spec";
|
|
16
|
-
import type { Insert${Type}, Update${Type}, Select${Type} } from "./types/${table.name}";
|
|
17
|
-
|
|
18
|
-
export class ${Type}Client {
|
|
19
|
-
constructor(
|
|
20
|
-
private baseUrl: string,
|
|
21
|
-
private fetchFn: typeof fetch = fetch,
|
|
22
|
-
private auth?: () => Promise<Record<string,string>>
|
|
23
|
-
) {}
|
|
24
|
-
|
|
25
|
-
private async headers(json = false) {
|
|
26
|
-
const extra = (await this.auth?.()) ?? {};
|
|
27
|
-
return json ? { "Content-Type": "application/json", ...extra } : extra;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
private async okOrThrow(res: Response, action: string) {
|
|
31
|
-
if (!res.ok) {
|
|
32
|
-
let detail = "";
|
|
33
|
-
try { detail = await res.text(); } catch {}
|
|
34
|
-
throw new Error(\`\${action} ${table.name} failed: \${res.status} \${detail}\`);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
async create(data: Insert${Type}): Promise<Select${Type}> {
|
|
39
|
-
const res = await this.fetchFn(\`\${this.baseUrl}/v1/${table.name}\`, {
|
|
40
|
-
method: "POST",
|
|
41
|
-
headers: await this.headers(true),
|
|
42
|
-
body: JSON.stringify(data),
|
|
43
|
-
});
|
|
44
|
-
await this.okOrThrow(res, "create");
|
|
45
|
-
return (await res.json()) as Select${Type};
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
async getByPk(pk: ${pkType}): Promise<Select${Type} | null> {
|
|
49
|
-
const path = ${pkPathExpr};
|
|
50
|
-
const res = await this.fetchFn(\`\${this.baseUrl}/v1/${table.name}/\${path}\`, {
|
|
51
|
-
headers: await this.headers(),
|
|
52
|
-
});
|
|
53
|
-
if (res.status === 404) return null;
|
|
54
|
-
await this.okOrThrow(res, "get");
|
|
55
|
-
return (await res.json()) as Select${Type};
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
async list(params?: { include?: ${Type}IncludeSpec; limit?: number; offset?: number }): Promise<Select${Type}[]> {
|
|
59
|
-
const res = await this.fetchFn(\`\${this.baseUrl}/v1/${table.name}/list\`, {
|
|
60
|
-
method: "POST",
|
|
61
|
-
headers: await this.headers(true),
|
|
62
|
-
body: JSON.stringify(params ?? {}),
|
|
63
|
-
});
|
|
64
|
-
await this.okOrThrow(res, "list");
|
|
65
|
-
return (await res.json()) as Select${Type}[];
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
async update(pk: ${pkType}, patch: Update${Type}): Promise<Select${Type} | null> {
|
|
69
|
-
const path = ${pkPathExpr};
|
|
70
|
-
const res = await this.fetchFn(\`\${this.baseUrl}/v1/${table.name}/\${path}\`, {
|
|
71
|
-
method: "PATCH",
|
|
72
|
-
headers: await this.headers(true),
|
|
73
|
-
body: JSON.stringify(patch),
|
|
74
|
-
});
|
|
75
|
-
if (res.status === 404) return null;
|
|
76
|
-
await this.okOrThrow(res, "update");
|
|
77
|
-
return (await res.json()) as Select${Type};
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
async delete(pk: ${pkType}): Promise<Select${Type} | null> {
|
|
81
|
-
const path = ${pkPathExpr};
|
|
82
|
-
const res = await this.fetchFn(\`\${this.baseUrl}/v1/${table.name}/\${path}\`, {
|
|
83
|
-
method: "DELETE",
|
|
84
|
-
headers: await this.headers(),
|
|
85
|
-
});
|
|
86
|
-
if (res.status === 404) return null;
|
|
87
|
-
await this.okOrThrow(res, "delete");
|
|
88
|
-
return (await res.json()) as Select${Type};
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
`;
|
|
92
|
-
}
|
|
93
|
-
export function emitClientIndex(tables) {
|
|
94
|
-
let out = `/* Generated. Do not edit. */\n`;
|
|
95
|
-
for (const t of tables) {
|
|
96
|
-
out += `import { ${pascal(t.name)}Client } from "./${t.name}";\n`;
|
|
97
|
-
}
|
|
98
|
-
out += `\nexport class SDK {\n`;
|
|
99
|
-
for (const t of tables) {
|
|
100
|
-
out += ` public ${t.name}: ${pascal(t.name)}Client;\n`;
|
|
101
|
-
}
|
|
102
|
-
out += `\n constructor(cfg: { baseUrl: string; fetch?: typeof fetch; auth?: () => Promise<Record<string,string>> }) {\n`;
|
|
103
|
-
out += ` const f = cfg.fetch ?? fetch;\n`;
|
|
104
|
-
for (const t of tables) {
|
|
105
|
-
out += ` this.${t.name} = new ${pascal(t.name)}Client(cfg.baseUrl, f, cfg.auth);\n`;
|
|
106
|
-
}
|
|
107
|
-
out += ` }\n`;
|
|
108
|
-
out += `}\n`;
|
|
109
|
-
for (const t of tables)
|
|
110
|
-
out += `export { ${pascal(t.name)}Client } from "./${t.name}";\n`;
|
|
111
|
-
out += `export * from "./include-spec";\n`;
|
|
112
|
-
return out;
|
|
113
|
-
}
|
|
114
|
-
//# sourceMappingURL=emit-client.js.map
|
package/dist/emit-client.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"emit-client.js","sourceRoot":"","sources":["../src/emit-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"emit-include-builder.d.ts","sourceRoot":"","sources":["../src/emit-include-builder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAE5C,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,UA4BhE"}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
export function emitIncludeBuilder(graph, maxDepth) {
|
|
2
|
-
return `// Generated. Do not edit.
|
|
3
|
-
export const RELATION_GRAPH = ${JSON.stringify(graph, null, 2)} as const;
|
|
4
|
-
type TableName = keyof typeof RELATION_GRAPH;
|
|
5
|
-
|
|
6
|
-
export function buildWith(root: TableName, spec: any, maxDepth = ${maxDepth}) {
|
|
7
|
-
return walk(root as string, spec, 0);
|
|
8
|
-
function walk(table: string, s: any, depth: number): any {
|
|
9
|
-
if (!s || depth >= maxDepth) return undefined;
|
|
10
|
-
const rels: any = (RELATION_GRAPH as any)[table] || {};
|
|
11
|
-
const out: any = {};
|
|
12
|
-
for (const key of Object.keys(s)) {
|
|
13
|
-
const rel = rels[key];
|
|
14
|
-
if (!rel) throw new Error(\`Unknown include key '\${key}' on table '\${table}'\`);
|
|
15
|
-
const v = s[key];
|
|
16
|
-
if (v === true) out[key] = true;
|
|
17
|
-
else if (v && typeof v === "object") {
|
|
18
|
-
const child = "include" in v ? walk(rel.target, v.include, depth + 1) : undefined;
|
|
19
|
-
out[key] = child ? { with: child } : true;
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
return Object.keys(out).length ? out : undefined;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export const buildWithFor = (t: TableName) =>
|
|
27
|
-
(spec?: any, depth = ${maxDepth}) => (spec ? buildWith(t, spec, depth) : undefined);
|
|
28
|
-
`;
|
|
29
|
-
}
|
|
30
|
-
//# sourceMappingURL=emit-include-builder.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"emit-include-builder.js","sourceRoot":"","sources":["../src/emit-include-builder.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,kBAAkB,CAAC,KAAY,EAAE,QAAgB;IAC/D,OAAO;gCACuB,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;;;mEAGK,QAAQ;;;;;;;;;;;;;;;;;;;;;yBAqBlD,QAAQ;CAChC,CAAC;AACF,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"emit-include-loader.d.ts","sourceRoot":"","sources":["../src/emit-include-loader.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAE1C;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,UAgT7E"}
|
|
@@ -1,299 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Emit a generic include loader that:
|
|
3
|
-
* - Walks the include spec
|
|
4
|
-
* - Loads children in batches per edge kind
|
|
5
|
-
* - Stitches onto parent rows (mutates copies)
|
|
6
|
-
*/
|
|
7
|
-
export function emitIncludeLoader(graph, model, maxDepth) {
|
|
8
|
-
// Precompute helpful maps for FK discovery
|
|
9
|
-
const fkIndex = {};
|
|
10
|
-
for (const t of Object.values(model.tables)) {
|
|
11
|
-
fkIndex[t.name] = t.fks.map((f) => ({ from: f.from, toTable: f.toTable, to: f.to }));
|
|
12
|
-
}
|
|
13
|
-
return `/* Generated. Do not edit. */
|
|
14
|
-
import { RELATION_GRAPH } from "./include-builder";
|
|
15
|
-
|
|
16
|
-
// Minimal types to keep the file self-contained
|
|
17
|
-
type Graph = typeof RELATION_GRAPH;
|
|
18
|
-
type TableName = keyof Graph;
|
|
19
|
-
type IncludeSpec = any;
|
|
20
|
-
|
|
21
|
-
// Debug helpers (enabled with SDK_DEBUG=1)
|
|
22
|
-
const DEBUG = process.env.SDK_DEBUG === "1" || process.env.SDK_DEBUG === "true";
|
|
23
|
-
const log = {
|
|
24
|
-
debug: (...args: any[]) => { if (DEBUG) console.debug("[sdk:include]", ...args); },
|
|
25
|
-
warn: (...args: any[]) => console.warn("[sdk:include]", ...args),
|
|
26
|
-
error: (...args: any[]) => console.error("[sdk:include]", ...args),
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
// Helpers for PK/FK discovery from model (inlined)
|
|
30
|
-
const FK_INDEX = ${JSON.stringify(fkIndex, null, 2)} as const;
|
|
31
|
-
const PKS = ${JSON.stringify(Object.fromEntries(Object.values(model.tables).map((t) => [t.name, t.pk])), null, 2)} as const;
|
|
32
|
-
|
|
33
|
-
// Build WHERE predicate for OR-of-AND on composite values
|
|
34
|
-
function buildOrAndPredicate(cols: string[], count: number, startIndex: number) {
|
|
35
|
-
// Generates: (c1=$i AND c2=$i+1) OR (c1=$j AND c2=$j+1) ...
|
|
36
|
-
const groups: string[] = [];
|
|
37
|
-
let idx = startIndex;
|
|
38
|
-
for (let k = 0; k < count; k++) {
|
|
39
|
-
const parts = cols.map((c, j) => \`"\${c}" = $\${idx + j}\`);
|
|
40
|
-
groups.push('(' + parts.join(' AND ') + ')');
|
|
41
|
-
idx += cols.length;
|
|
42
|
-
}
|
|
43
|
-
return groups.join(' OR ');
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// Extract distinct tuples from rows
|
|
47
|
-
function distinctTuples(rows: any[], cols: string[]): any[] {
|
|
48
|
-
const s = new Set<string>();
|
|
49
|
-
const res: any[] = [];
|
|
50
|
-
for (const r of rows) {
|
|
51
|
-
const tup = cols.map(c => r[c]);
|
|
52
|
-
const key = JSON.stringify(tup);
|
|
53
|
-
if (!s.has(key)) {
|
|
54
|
-
s.add(key);
|
|
55
|
-
res.push(tup);
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
return res;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
// Index rows by tuple key
|
|
62
|
-
function indexByTuple(rows: any[], cols: string[]) {
|
|
63
|
-
const map = new Map<string, any>();
|
|
64
|
-
for (const r of rows) {
|
|
65
|
-
const key = JSON.stringify(cols.map(c => r[c]));
|
|
66
|
-
map.set(key, r);
|
|
67
|
-
}
|
|
68
|
-
return map;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// Group rows by tuple key (1:N)
|
|
72
|
-
function groupByTuple(rows: any[], cols: string[]) {
|
|
73
|
-
const map = new Map<string, any[]>();
|
|
74
|
-
for (const r of rows) {
|
|
75
|
-
const key = JSON.stringify(cols.map(c => r[c]));
|
|
76
|
-
const arr = map.get(key) ?? [];
|
|
77
|
-
arr.push(r);
|
|
78
|
-
map.set(key, arr);
|
|
79
|
-
}
|
|
80
|
-
return map;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
// Public entry
|
|
84
|
-
export async function loadIncludes(
|
|
85
|
-
root: TableName,
|
|
86
|
-
parents: any[],
|
|
87
|
-
spec: IncludeSpec | undefined,
|
|
88
|
-
pg: { query: (text: string, params?: any[]) => Promise<{ rows: any[] }> },
|
|
89
|
-
maxDepth: number = ${maxDepth}
|
|
90
|
-
) {
|
|
91
|
-
try {
|
|
92
|
-
if (!spec || !parents.length) return parents;
|
|
93
|
-
log.debug("loadIncludes root/spec/rows", root, Object.keys(spec ?? {}).length, parents.length);
|
|
94
|
-
|
|
95
|
-
// Deep clone parents to avoid mutating caller refs
|
|
96
|
-
const cloned = parents.map(p => ({ ...p }));
|
|
97
|
-
await walk(root, cloned, spec, 0);
|
|
98
|
-
return cloned;
|
|
99
|
-
} catch (e: any) {
|
|
100
|
-
log.error("loadIncludes error:", e?.message ?? e, e?.stack);
|
|
101
|
-
// Never throw to the route; return base rows
|
|
102
|
-
return parents;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
async function walk(table: TableName, rows: any[], s: any, depth: number): Promise<void> {
|
|
106
|
-
if (!s || depth >= maxDepth || rows.length === 0) return;
|
|
107
|
-
const rels: any = (RELATION_GRAPH as any)[table] || {};
|
|
108
|
-
log.debug("walk", { table, depth, keys: Object.keys(s) });
|
|
109
|
-
|
|
110
|
-
// Process each requested relation at this level
|
|
111
|
-
for (const key of Object.keys(s)) {
|
|
112
|
-
const rel = rels[key];
|
|
113
|
-
if (!rel) {
|
|
114
|
-
log.warn(\`Unknown include key '\${key}' on '\${table}' — skipping\`);
|
|
115
|
-
continue;
|
|
116
|
-
}
|
|
117
|
-
const target = rel.target as TableName;
|
|
118
|
-
|
|
119
|
-
// Safely run each loader; never let one bad edge 500 the route
|
|
120
|
-
if (rel.via) {
|
|
121
|
-
// M:N via junction
|
|
122
|
-
try {
|
|
123
|
-
await loadManyToMany(table, target, rel.via as string, rows, key);
|
|
124
|
-
} catch (e: any) {
|
|
125
|
-
log.error("loadManyToMany failed", { table, key, via: rel.via, target }, e?.message ?? e);
|
|
126
|
-
for (const r of rows) r[key] = [];
|
|
127
|
-
}
|
|
128
|
-
// Recurse if nested include specified
|
|
129
|
-
const childSpec = s[key] && typeof s[key] === "object" ? (s[key] as any).include : undefined;
|
|
130
|
-
if (childSpec) {
|
|
131
|
-
const children = rows.flatMap(r => (r[key] ?? []));
|
|
132
|
-
try {
|
|
133
|
-
await walk(target, children, childSpec, depth + 1);
|
|
134
|
-
} catch (e: any) {
|
|
135
|
-
log.error("walk nested (via) failed", { table: String(target), key }, e?.message ?? e);
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
continue;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
if (rel.kind === "many") {
|
|
142
|
-
// 1:N target has FK to current
|
|
143
|
-
try {
|
|
144
|
-
await loadOneToMany(table, target, rows, key);
|
|
145
|
-
} catch (e: any) {
|
|
146
|
-
log.error("loadOneToMany failed", { table, key, target }, e?.message ?? e);
|
|
147
|
-
for (const r of rows) r[key] = [];
|
|
148
|
-
}
|
|
149
|
-
const childSpec = s[key] && typeof s[key] === "object" ? (s[key] as any).include : undefined;
|
|
150
|
-
if (childSpec) {
|
|
151
|
-
const children = rows.flatMap(r => (r[key] ?? []));
|
|
152
|
-
try {
|
|
153
|
-
await walk(target, children, childSpec, depth + 1);
|
|
154
|
-
} catch (e: any) {
|
|
155
|
-
log.error("walk nested (many) failed", { table: String(target), key }, e?.message ?? e);
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
} else {
|
|
159
|
-
// kind === "one"
|
|
160
|
-
// Could be belongs-to (current has FK to target) OR has-one (target unique-FK to current)
|
|
161
|
-
const currFks = (FK_INDEX as any)[table] as Array<{from:string[];toTable:string;to:string[]}>;
|
|
162
|
-
const toTarget = currFks.find(f => f.toTable === target);
|
|
163
|
-
if (toTarget) {
|
|
164
|
-
try {
|
|
165
|
-
await loadBelongsTo(table, target, rows, key);
|
|
166
|
-
} catch (e: any) {
|
|
167
|
-
log.error("loadBelongsTo failed", { table, key, target }, e?.message ?? e);
|
|
168
|
-
for (const r of rows) r[key] = null;
|
|
169
|
-
}
|
|
170
|
-
} else {
|
|
171
|
-
try {
|
|
172
|
-
await loadHasOne(table, target, rows, key);
|
|
173
|
-
} catch (e: any) {
|
|
174
|
-
log.error("loadHasOne failed", { table, key, target }, e?.message ?? e);
|
|
175
|
-
for (const r of rows) r[key] = null;
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
const childSpec = s[key] && typeof s[key] === "object" ? (s[key] as any).include : undefined;
|
|
179
|
-
if (childSpec) {
|
|
180
|
-
const children = rows.map(r => r[key]).filter(Boolean);
|
|
181
|
-
try {
|
|
182
|
-
await walk(target, children, childSpec, depth + 1);
|
|
183
|
-
} catch (e: any) {
|
|
184
|
-
log.error("walk nested (one) failed", { table: String(target), key }, e?.message ?? e);
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
async function loadBelongsTo(curr: TableName, target: TableName, rows: any[], key: string) {
|
|
192
|
-
// current has FK cols referencing target PK
|
|
193
|
-
const fk = (FK_INDEX as any)[curr].find((f: any) => f.toTable === target);
|
|
194
|
-
if (!fk) { for (const r of rows) r[key] = null; return; }
|
|
195
|
-
const tuples = distinctTuples(rows, fk.from).filter(t => t.every((v: any) => v != null));
|
|
196
|
-
if (!tuples.length) { for (const r of rows) r[key] = null; return; }
|
|
197
|
-
|
|
198
|
-
// Query target WHERE target.pk IN tuples
|
|
199
|
-
const pkCols = (PKS as any)[target] as string[];
|
|
200
|
-
const where = buildOrAndPredicate(pkCols, tuples.length, 1);
|
|
201
|
-
const params = tuples.flat();
|
|
202
|
-
const sql = \`SELECT * FROM "\${target}" WHERE \${where}\`;
|
|
203
|
-
log.debug("belongsTo SQL", { curr, target, key, sql, paramsCount: params.length });
|
|
204
|
-
const { rows: targets } = await pg.query(sql, params);
|
|
205
|
-
|
|
206
|
-
const idx = indexByTuple(targets, pkCols);
|
|
207
|
-
for (const r of rows) {
|
|
208
|
-
const tup = fk.from.map((c: string) => r[c]);
|
|
209
|
-
const keyStr = JSON.stringify(tup);
|
|
210
|
-
r[key] = idx.get(keyStr) ?? null;
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
async function loadHasOne(curr: TableName, target: TableName, rows: any[], key: string) {
|
|
215
|
-
// target has FK cols referencing current PK (unique)
|
|
216
|
-
const fk = (FK_INDEX as any)[target].find((f: any) => f.toTable === curr);
|
|
217
|
-
if (!fk) { for (const r of rows) r[key] = null; return; }
|
|
218
|
-
|
|
219
|
-
const pkCols = (PKS as any)[curr] as string[];
|
|
220
|
-
const tuples = distinctTuples(rows, pkCols).filter(t => t.every((v: any) => v != null));
|
|
221
|
-
if (!tuples.length) { for (const r of rows) r[key] = null; return; }
|
|
222
|
-
|
|
223
|
-
// SELECT target WHERE fk IN tuples
|
|
224
|
-
const where = buildOrAndPredicate(fk.from, tuples.length, 1);
|
|
225
|
-
const params = tuples.flat();
|
|
226
|
-
const sql = \`SELECT * FROM "\${target}" WHERE \${where}\`;
|
|
227
|
-
log.debug("hasOne SQL", { curr, target, key, sql, paramsCount: params.length });
|
|
228
|
-
const { rows: targets } = await pg.query(sql, params);
|
|
229
|
-
|
|
230
|
-
const idx = indexByTuple(targets, fk.from);
|
|
231
|
-
for (const r of rows) {
|
|
232
|
-
const keyStr = JSON.stringify(pkCols.map((c: string) => r[c]));
|
|
233
|
-
r[key] = idx.get(keyStr) ?? null;
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
async function loadOneToMany(curr: TableName, target: TableName, rows: any[], key: string) {
|
|
238
|
-
// target has FK cols referencing current PK
|
|
239
|
-
const fk = (FK_INDEX as any)[target].find((f: any) => f.toTable === curr);
|
|
240
|
-
if (!fk) { for (const r of rows) r[key] = []; return; }
|
|
241
|
-
|
|
242
|
-
const pkCols = (PKS as any)[curr] as string[];
|
|
243
|
-
const tuples = distinctTuples(rows, pkCols).filter(t => t.every((v: any) => v != null));
|
|
244
|
-
if (!tuples.length) { for (const r of rows) r[key] = []; return; }
|
|
245
|
-
|
|
246
|
-
const where = buildOrAndPredicate(fk.from, tuples.length, 1);
|
|
247
|
-
const params = tuples.flat();
|
|
248
|
-
const sql = \`SELECT * FROM "\${target}" WHERE \${where}\`;
|
|
249
|
-
log.debug("oneToMany SQL", { curr, target, key, sql, paramsCount: params.length });
|
|
250
|
-
const { rows: children } = await pg.query(sql, params);
|
|
251
|
-
|
|
252
|
-
const groups = groupByTuple(children, fk.from);
|
|
253
|
-
for (const r of rows) {
|
|
254
|
-
const keyStr = JSON.stringify(pkCols.map((c: string) => r[c]));
|
|
255
|
-
r[key] = groups.get(keyStr) ?? [];
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
async function loadManyToMany(curr: TableName, target: TableName, via: string, rows: any[], key: string) {
|
|
260
|
-
// via has two FKs: one to curr, one to target
|
|
261
|
-
const toCurr = (FK_INDEX as any)[via].find((f: any) => f.toTable === curr);
|
|
262
|
-
const toTarget = (FK_INDEX as any)[via].find((f: any) => f.toTable === target);
|
|
263
|
-
if (!toCurr || !toTarget) { for (const r of rows) r[key] = []; return; }
|
|
264
|
-
|
|
265
|
-
const pkCols = (PKS as any)[curr] as string[];
|
|
266
|
-
const tuples = distinctTuples(rows, pkCols).filter(t => t.every((v: any) => v != null));
|
|
267
|
-
if (!tuples.length) { for (const r of rows) r[key] = []; return; }
|
|
268
|
-
|
|
269
|
-
// 1) Load junction rows for current parents
|
|
270
|
-
const whereVia = buildOrAndPredicate(toCurr.from, tuples.length, 1);
|
|
271
|
-
const sqlVia = \`SELECT * FROM "\${via}" WHERE \${whereVia}\`;
|
|
272
|
-
const paramsVia = tuples.flat();
|
|
273
|
-
log.debug("manyToMany junction SQL", { curr, target, via, key, sql: sqlVia, paramsCount: paramsVia.length });
|
|
274
|
-
const { rows: jrows } = await pg.query(sqlVia, paramsVia);
|
|
275
|
-
|
|
276
|
-
if (!jrows.length) { for (const r of rows) r[key] = []; return; }
|
|
277
|
-
|
|
278
|
-
// 2) Load targets by distinct target fk tuples in junction
|
|
279
|
-
const tTuples = distinctTuples(jrows, toTarget.from);
|
|
280
|
-
const whereT = buildOrAndPredicate((PKS as any)[target], tTuples.length, 1);
|
|
281
|
-
const sqlT = \`SELECT * FROM "\${target}" WHERE \${whereT}\`;
|
|
282
|
-
const paramsT = tTuples.flat();
|
|
283
|
-
log.debug("manyToMany target SQL", { curr, target, via, key, sql: sqlT, paramsCount: paramsT.length });
|
|
284
|
-
const { rows: targets } = await pg.query(sqlT, paramsT);
|
|
285
|
-
|
|
286
|
-
const tIdx = indexByTuple(targets, (PKS as any)[target]);
|
|
287
|
-
|
|
288
|
-
// 3) Group junction rows by current pk tuple, map to target rows
|
|
289
|
-
const byCurr = groupByTuple(jrows, toCurr.from);
|
|
290
|
-
for (const r of rows) {
|
|
291
|
-
const currKey = JSON.stringify(pkCols.map((c: string) => r[c]));
|
|
292
|
-
const j = byCurr.get(currKey) ?? [];
|
|
293
|
-
r[key] = j.map(jr => tIdx.get(JSON.stringify(toTarget.from.map((c: string) => jr[c])))).filter(Boolean);
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
`;
|
|
298
|
-
}
|
|
299
|
-
//# sourceMappingURL=emit-include-loader.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"emit-include-loader.js","sourceRoot":"","sources":["../src/emit-include-loader.ts"],"names":[],"mappings":"AAGA;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAY,EAAE,KAAY,EAAE,QAAgB;IAC5E,2CAA2C;IAC3C,MAAM,OAAO,GAQT,EAAE,CAAC;IACP,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;QAC5C,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IACvF,CAAC;IAED,OAAO;;;;;;;;;;;;;;;;;mBAiBU,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;cACrC,IAAI,CAAC,SAAS,CACxB,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAC1E,IAAI,EACJ,CAAC,CACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;uBA0DoB,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgN9B,CAAC;AACF,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"emit-include-spec.d.ts","sourceRoot":"","sources":["../src/emit-include-spec.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAE5C,wBAAgB,eAAe,CAAC,KAAK,EAAE,KAAK,UAsB3C"}
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
export function emitIncludeSpec(graph) {
|
|
2
|
-
let out = `/* Generated. Do not edit. */\n`;
|
|
3
|
-
const tables = Object.keys(graph);
|
|
4
|
-
for (const table of tables) {
|
|
5
|
-
const rels = graph[table] ?? {};
|
|
6
|
-
const entries = Object.entries(rels);
|
|
7
|
-
out += `export type ${toPascal(table)}IncludeSpec = {\n`;
|
|
8
|
-
for (const [relKey, edge] of entries) {
|
|
9
|
-
if (edge.kind === "many") {
|
|
10
|
-
out += ` ${relKey}?: boolean | { include?: ${toPascal(edge.target)}IncludeSpec; limit?: number; offset?: number; };\n`;
|
|
11
|
-
}
|
|
12
|
-
else {
|
|
13
|
-
out += ` ${relKey}?: boolean | ${toPascal(edge.target)}IncludeSpec;\n`;
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
out += `};\n\n`;
|
|
17
|
-
}
|
|
18
|
-
return out;
|
|
19
|
-
}
|
|
20
|
-
function toPascal(s) {
|
|
21
|
-
return s
|
|
22
|
-
.split(/[_\s-]+/)
|
|
23
|
-
.map((w) => (w?.[0] ? w[0].toUpperCase() + w.slice(1) : ""))
|
|
24
|
-
.join("");
|
|
25
|
-
}
|
|
26
|
-
//# sourceMappingURL=emit-include-spec.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"emit-include-spec.js","sourceRoot":"","sources":["../src/emit-include-spec.ts"],"names":[],"mappings":"AAGA,MAAM,UAAU,eAAe,CAAC,KAAY;IAC1C,IAAI,GAAG,GAAG,iCAAiC,CAAC;IAE5C,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QAChC,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAErC,GAAG,IAAI,eAAe,QAAQ,CAAC,KAAK,CAAC,mBAAmB,CAAC;QACzD,KAAK,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,OAAO,EAAE,CAAC;YACrC,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;gBACzB,GAAG,IAAI,KAAK,MAAM,4BAA4B,QAAQ,CACpD,IAAI,CAAC,MAAM,CACZ,oDAAoD,CAAC;YACxD,CAAC;iBAAM,CAAC;gBACN,GAAG,IAAI,KAAK,MAAM,gBAAgB,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC;YAC1E,CAAC;QACH,CAAC;QACD,GAAG,IAAI,QAAQ,CAAC;IAClB,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,QAAQ,CAAC,CAAS;IACzB,OAAO,CAAC;SACL,KAAK,CAAC,SAAS,CAAC;SAChB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;SAC3D,IAAI,CAAC,EAAE,CAAC,CAAC;AACd,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"emit-logger.d.ts","sourceRoot":"","sources":["../src/emit-logger.ts"],"names":[],"mappings":"AACA,wBAAgB,UAAU,WAgCzB"}
|