@jd-data-limited/easy-fm 5.0.0-beta.5 → 5.0.0-beta.7
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/bin/cli.js +4 -1
- package/dist/layouts/layout.js +2 -2
- package/dist/models/apiResults.d.ts +27 -14
- package/dist/models/apiResults.js +23 -3
- package/dist/records/recordBase.js +2 -1
- package/dist/schema.js +14 -4
- package/dist/typegen/dataApiSchemaSource.js +18 -11
- package/dist/typegen/generate.d.ts +3 -0
- package/dist/typegen/generate.js +8 -1
- package/dist/typegen/index.d.ts +1 -1
- package/dist/typegen/types.d.ts +10 -0
- package/package.json +1 -1
package/dist/bin/cli.js
CHANGED
|
@@ -40,7 +40,10 @@ program
|
|
|
40
40
|
if (await typegen.ensureZodInstalled(dirname(configPath)))
|
|
41
41
|
console.log(chalk.green('Installed Zod for generated runtime validation.'));
|
|
42
42
|
const loaded = await import(pathToFileURL(configPath).href);
|
|
43
|
-
const result = await typegen.generate(loaded.default)
|
|
43
|
+
const result = await typegen.generate({ ...loaded.default, onDiagnostic: (diagnostic) => {
|
|
44
|
+
const location = [diagnostic.database, diagnostic.layout, diagnostic.portal].filter(Boolean).join('/');
|
|
45
|
+
console.warn(chalk.yellow(`Warning [${location}]: ${diagnostic.message}`));
|
|
46
|
+
} });
|
|
44
47
|
console.log(chalk.green(`Generated ${result.layouts} layouts in ${result.output}`));
|
|
45
48
|
});
|
|
46
49
|
program.parse(process.argv);
|
package/dist/layouts/layout.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { LayoutRecordManager } from './layoutRecordManager.js';
|
|
5
5
|
import { FMError } from '../FMError.js';
|
|
6
|
-
import { ApiLayoutMetadata } from '../models/apiResults.js';
|
|
6
|
+
import { ApiLayoutMetadata, stripInaccessibleMetadata } from '../models/apiResults.js';
|
|
7
7
|
export class Layout {
|
|
8
8
|
database;
|
|
9
9
|
name;
|
|
@@ -37,7 +37,7 @@ export class Layout {
|
|
|
37
37
|
return this.metadata;
|
|
38
38
|
}
|
|
39
39
|
const { value: res } = await this.database.execute({ type: 'layout.metadata', layout: this.name });
|
|
40
|
-
this.metadata = ApiLayoutMetadata.parse(res);
|
|
40
|
+
this.metadata = stripInaccessibleMetadata(ApiLayoutMetadata.parse(res));
|
|
41
41
|
return this.metadata;
|
|
42
42
|
}
|
|
43
43
|
}
|
|
@@ -7,6 +7,7 @@ export declare const ApiFieldTypes: {
|
|
|
7
7
|
export declare const ApiFieldDisplayTypes: {
|
|
8
8
|
readonly EDIT_TEXT: "editText";
|
|
9
9
|
readonly POPUP_LIST: "popupList";
|
|
10
|
+
readonly POPUP_MENU: "popupMenu";
|
|
10
11
|
readonly CHECKBOX: "checkBox";
|
|
11
12
|
readonly RADIO_BUTTONS: "radioButtons";
|
|
12
13
|
readonly SELECTION_LIST: "selectionList";
|
|
@@ -39,28 +40,29 @@ export declare const ApiLayout: z.ZodType<{
|
|
|
39
40
|
}>;
|
|
40
41
|
export declare const ApiFieldMetadata: z.ZodObject<{
|
|
41
42
|
name: z.ZodString;
|
|
42
|
-
type: z.ZodEnum<{
|
|
43
|
+
type: z.ZodUnion<readonly [z.ZodEnum<{
|
|
43
44
|
readonly NORMAL: "normal";
|
|
44
45
|
readonly CALCULATION: "calculation";
|
|
45
46
|
readonly SUMMARY: "summary";
|
|
46
|
-
}>;
|
|
47
|
+
}>, z.ZodLiteral<"invalid">]>;
|
|
47
48
|
displayType: z.ZodEnum<{
|
|
48
49
|
readonly EDIT_TEXT: "editText";
|
|
49
50
|
readonly POPUP_LIST: "popupList";
|
|
51
|
+
readonly POPUP_MENU: "popupMenu";
|
|
50
52
|
readonly CHECKBOX: "checkBox";
|
|
51
53
|
readonly RADIO_BUTTONS: "radioButtons";
|
|
52
54
|
readonly SELECTION_LIST: "selectionList";
|
|
53
55
|
readonly CALENDAR: "calendar";
|
|
54
56
|
readonly SECURE_TEXT: "secureText";
|
|
55
57
|
}>;
|
|
56
|
-
result: z.ZodEnum<{
|
|
58
|
+
result: z.ZodUnion<readonly [z.ZodEnum<{
|
|
57
59
|
readonly TEXT: "text";
|
|
58
60
|
readonly NUMBER: "number";
|
|
59
61
|
readonly DATE: "date";
|
|
60
62
|
readonly TIME: "time";
|
|
61
63
|
readonly TIMESTAMP: "timeStamp";
|
|
62
64
|
readonly CONTAINER: "container";
|
|
63
|
-
}>;
|
|
65
|
+
}>, z.ZodLiteral<"invalid">]>;
|
|
64
66
|
global: z.ZodBoolean;
|
|
65
67
|
autoEnter: z.ZodBoolean;
|
|
66
68
|
fourDigitYear: z.ZodBoolean;
|
|
@@ -78,34 +80,35 @@ export declare const ApiValueList: z.ZodObject<{
|
|
|
78
80
|
type: z.ZodString;
|
|
79
81
|
values: z.ZodArray<z.ZodObject<{
|
|
80
82
|
value: z.ZodString;
|
|
81
|
-
displayName: z.ZodString
|
|
83
|
+
displayName: z.ZodOptional<z.ZodString>;
|
|
82
84
|
}, z.core.$strip>>;
|
|
83
85
|
}, z.core.$strip>;
|
|
84
86
|
export declare const ApiLayoutMetadata: z.ZodObject<{
|
|
85
87
|
fieldMetaData: z.ZodArray<z.ZodObject<{
|
|
86
88
|
name: z.ZodString;
|
|
87
|
-
type: z.ZodEnum<{
|
|
89
|
+
type: z.ZodUnion<readonly [z.ZodEnum<{
|
|
88
90
|
readonly NORMAL: "normal";
|
|
89
91
|
readonly CALCULATION: "calculation";
|
|
90
92
|
readonly SUMMARY: "summary";
|
|
91
|
-
}>;
|
|
93
|
+
}>, z.ZodLiteral<"invalid">]>;
|
|
92
94
|
displayType: z.ZodEnum<{
|
|
93
95
|
readonly EDIT_TEXT: "editText";
|
|
94
96
|
readonly POPUP_LIST: "popupList";
|
|
97
|
+
readonly POPUP_MENU: "popupMenu";
|
|
95
98
|
readonly CHECKBOX: "checkBox";
|
|
96
99
|
readonly RADIO_BUTTONS: "radioButtons";
|
|
97
100
|
readonly SELECTION_LIST: "selectionList";
|
|
98
101
|
readonly CALENDAR: "calendar";
|
|
99
102
|
readonly SECURE_TEXT: "secureText";
|
|
100
103
|
}>;
|
|
101
|
-
result: z.ZodEnum<{
|
|
104
|
+
result: z.ZodUnion<readonly [z.ZodEnum<{
|
|
102
105
|
readonly TEXT: "text";
|
|
103
106
|
readonly NUMBER: "number";
|
|
104
107
|
readonly DATE: "date";
|
|
105
108
|
readonly TIME: "time";
|
|
106
109
|
readonly TIMESTAMP: "timeStamp";
|
|
107
110
|
readonly CONTAINER: "container";
|
|
108
|
-
}>;
|
|
111
|
+
}>, z.ZodLiteral<"invalid">]>;
|
|
109
112
|
global: z.ZodBoolean;
|
|
110
113
|
autoEnter: z.ZodBoolean;
|
|
111
114
|
fourDigitYear: z.ZodBoolean;
|
|
@@ -120,28 +123,29 @@ export declare const ApiLayoutMetadata: z.ZodObject<{
|
|
|
120
123
|
}, z.core.$strip>>;
|
|
121
124
|
portalMetaData: z.ZodRecord<z.ZodString, z.ZodArray<z.ZodObject<{
|
|
122
125
|
name: z.ZodString;
|
|
123
|
-
type: z.ZodEnum<{
|
|
126
|
+
type: z.ZodUnion<readonly [z.ZodEnum<{
|
|
124
127
|
readonly NORMAL: "normal";
|
|
125
128
|
readonly CALCULATION: "calculation";
|
|
126
129
|
readonly SUMMARY: "summary";
|
|
127
|
-
}>;
|
|
130
|
+
}>, z.ZodLiteral<"invalid">]>;
|
|
128
131
|
displayType: z.ZodEnum<{
|
|
129
132
|
readonly EDIT_TEXT: "editText";
|
|
130
133
|
readonly POPUP_LIST: "popupList";
|
|
134
|
+
readonly POPUP_MENU: "popupMenu";
|
|
131
135
|
readonly CHECKBOX: "checkBox";
|
|
132
136
|
readonly RADIO_BUTTONS: "radioButtons";
|
|
133
137
|
readonly SELECTION_LIST: "selectionList";
|
|
134
138
|
readonly CALENDAR: "calendar";
|
|
135
139
|
readonly SECURE_TEXT: "secureText";
|
|
136
140
|
}>;
|
|
137
|
-
result: z.ZodEnum<{
|
|
141
|
+
result: z.ZodUnion<readonly [z.ZodEnum<{
|
|
138
142
|
readonly TEXT: "text";
|
|
139
143
|
readonly NUMBER: "number";
|
|
140
144
|
readonly DATE: "date";
|
|
141
145
|
readonly TIME: "time";
|
|
142
146
|
readonly TIMESTAMP: "timeStamp";
|
|
143
147
|
readonly CONTAINER: "container";
|
|
144
|
-
}>;
|
|
148
|
+
}>, z.ZodLiteral<"invalid">]>;
|
|
145
149
|
global: z.ZodBoolean;
|
|
146
150
|
autoEnter: z.ZodBoolean;
|
|
147
151
|
fourDigitYear: z.ZodBoolean;
|
|
@@ -159,10 +163,19 @@ export declare const ApiLayoutMetadata: z.ZodObject<{
|
|
|
159
163
|
type: z.ZodString;
|
|
160
164
|
values: z.ZodArray<z.ZodObject<{
|
|
161
165
|
value: z.ZodString;
|
|
162
|
-
displayName: z.ZodString
|
|
166
|
+
displayName: z.ZodOptional<z.ZodString>;
|
|
163
167
|
}, z.core.$strip>>;
|
|
164
168
|
}, z.core.$strip>>>;
|
|
165
169
|
}, z.core.$strip>;
|
|
170
|
+
export type ApiLayoutMetadataValue = z.infer<typeof ApiLayoutMetadata>;
|
|
171
|
+
export declare function isAccessibleFieldMetadata(field: z.infer<typeof ApiFieldMetadata>): field is z.infer<typeof ApiFieldMetadata> & {
|
|
172
|
+
type: z.infer<typeof ApiFieldTypes>;
|
|
173
|
+
result: z.infer<typeof ApiFieldResultTypes>;
|
|
174
|
+
};
|
|
175
|
+
/** Removes FileMaker metadata placeholders for fields unavailable to the current account. */
|
|
176
|
+
export declare function stripInaccessibleMetadata(metadata: ApiLayoutMetadataValue): ApiLayoutMetadataValue;
|
|
177
|
+
/** Removes inaccessible placeholder values before strict generated validation. */
|
|
178
|
+
export declare function stripInaccessibleFieldData<T extends Record<string, unknown>>(fields: T): T;
|
|
166
179
|
export declare const ApiScriptResult: z.ZodObject<{
|
|
167
180
|
scriptError: z.ZodString;
|
|
168
181
|
scriptResult: z.ZodOptional<z.ZodString>;
|
|
@@ -10,6 +10,7 @@ export const ApiFieldTypes = {
|
|
|
10
10
|
export const ApiFieldDisplayTypes = {
|
|
11
11
|
EDIT_TEXT: 'editText',
|
|
12
12
|
POPUP_LIST: 'popupList',
|
|
13
|
+
POPUP_MENU: 'popupMenu',
|
|
13
14
|
CHECKBOX: 'checkBox',
|
|
14
15
|
RADIO_BUTTONS: 'radioButtons',
|
|
15
16
|
SELECTION_LIST: 'selectionList',
|
|
@@ -38,9 +39,9 @@ export const ApiLayout = z.lazy(() => z.object({
|
|
|
38
39
|
}));
|
|
39
40
|
export const ApiFieldMetadata = z.object({
|
|
40
41
|
name: z.string(),
|
|
41
|
-
type: z.enum(ApiFieldTypes),
|
|
42
|
+
type: z.union([z.enum(ApiFieldTypes), z.literal('invalid')]),
|
|
42
43
|
displayType: z.enum(ApiFieldDisplayTypes),
|
|
43
|
-
result: z.enum(ApiFieldResultTypes),
|
|
44
|
+
result: z.union([z.enum(ApiFieldResultTypes), z.literal('invalid')]),
|
|
44
45
|
global: z.boolean(),
|
|
45
46
|
autoEnter: z.boolean(),
|
|
46
47
|
fourDigitYear: z.boolean(),
|
|
@@ -58,7 +59,7 @@ export const ApiValueList = z.object({
|
|
|
58
59
|
type: z.string(),
|
|
59
60
|
values: z.array(z.object({
|
|
60
61
|
value: z.string(),
|
|
61
|
-
displayName: z.string()
|
|
62
|
+
displayName: z.string().optional()
|
|
62
63
|
}))
|
|
63
64
|
});
|
|
64
65
|
export const ApiLayoutMetadata = z.object({
|
|
@@ -66,6 +67,25 @@ export const ApiLayoutMetadata = z.object({
|
|
|
66
67
|
portalMetaData: z.record(z.string(), z.array(ApiFieldMetadata)),
|
|
67
68
|
valueLists: z.array(ApiValueList).optional()
|
|
68
69
|
});
|
|
70
|
+
export function isAccessibleFieldMetadata(field) {
|
|
71
|
+
return field.type !== 'invalid' && field.result !== 'invalid' && field.name !== '<No Access>';
|
|
72
|
+
}
|
|
73
|
+
/** Removes FileMaker metadata placeholders for fields unavailable to the current account. */
|
|
74
|
+
export function stripInaccessibleMetadata(metadata) {
|
|
75
|
+
return {
|
|
76
|
+
...metadata,
|
|
77
|
+
fieldMetaData: metadata.fieldMetaData.filter(isAccessibleFieldMetadata),
|
|
78
|
+
portalMetaData: Object.fromEntries(Object.entries(metadata.portalMetaData).map(([name, fields]) => [name, fields.filter(isAccessibleFieldMetadata)]))
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
/** Removes inaccessible placeholder values before strict generated validation. */
|
|
82
|
+
export function stripInaccessibleFieldData(fields) {
|
|
83
|
+
if (!Object.hasOwn(fields, '<No Access>'))
|
|
84
|
+
return fields;
|
|
85
|
+
const result = { ...fields };
|
|
86
|
+
delete result['<No Access>'];
|
|
87
|
+
return result;
|
|
88
|
+
}
|
|
69
89
|
export const ApiScriptResult = z.object({
|
|
70
90
|
scriptError: z.string(),
|
|
71
91
|
scriptResult: z.string().optional()
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { EventEmitter } from 'node:events';
|
|
5
5
|
import { RecordTypes } from '../types.js';
|
|
6
|
+
import { stripInaccessibleFieldData } from '../models/apiResults.js';
|
|
6
7
|
import { DateField, NumberField, TextField, TimeField, TimeStampField, ValueFieldBase } from "./fields/valueField.js";
|
|
7
8
|
import { ContainerField } from "./fields/containerField.js";
|
|
8
9
|
export class RecordBase extends EventEmitter {
|
|
@@ -41,7 +42,7 @@ export class RecordBase extends EventEmitter {
|
|
|
41
42
|
}
|
|
42
43
|
processFieldData(fieldData) {
|
|
43
44
|
const fields = {};
|
|
44
|
-
for (const [key, value] of Object.entries(fieldData)) {
|
|
45
|
+
for (const [key, value] of Object.entries(stripInaccessibleFieldData(fieldData))) {
|
|
45
46
|
const fieldMeta = this.getFieldMetadata(key);
|
|
46
47
|
let field;
|
|
47
48
|
switch (fieldMeta.result) {
|
package/dist/schema.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { stripInaccessibleFieldData, stripInaccessibleMetadata } from './models/apiResults.js';
|
|
1
2
|
/** Built-in runtime adapter used by Zod-generated clients. */
|
|
2
3
|
export const zodValidator = {
|
|
3
4
|
validate(schema, value) {
|
|
@@ -29,19 +30,28 @@ export function withSchemaValidation(provider, schema) {
|
|
|
29
30
|
return { formatting: connection.formatting, maxSessions: connection.maxSessions, close: connection.close?.bind(connection), async openSession(signal) {
|
|
30
31
|
const session = await connection.openSession(signal);
|
|
31
32
|
return { close: session.close.bind(session), fetchContainer: session.fetchContainer.bind(session), async execute(operation) {
|
|
32
|
-
|
|
33
|
-
if (operation.type === 'layout.metadata')
|
|
33
|
+
let result = await session.execute(operation);
|
|
34
|
+
if (operation.type === 'layout.metadata') {
|
|
35
|
+
result = stripInaccessibleMetadata(result);
|
|
34
36
|
validateMetadata(schema, operation.layout, result);
|
|
35
|
-
|
|
37
|
+
}
|
|
38
|
+
if (operation.type === 'record.get') {
|
|
39
|
+
result = stripRecord(result);
|
|
36
40
|
validateRecord(schema, operation.layout, result);
|
|
37
|
-
|
|
41
|
+
}
|
|
42
|
+
if (operation.type === 'record.list') {
|
|
43
|
+
result = result.map(stripRecord);
|
|
38
44
|
for (const record of result)
|
|
39
45
|
validateRecord(schema, operation.layout, record);
|
|
46
|
+
}
|
|
40
47
|
return result;
|
|
41
48
|
} };
|
|
42
49
|
} };
|
|
43
50
|
} };
|
|
44
51
|
}
|
|
52
|
+
function stripRecord(record) {
|
|
53
|
+
return { ...record, fieldData: stripInaccessibleFieldData(record.fieldData), portalData: record.portalData && Object.fromEntries(Object.entries(record.portalData).map(([name, rows]) => [name, rows.map(row => stripInaccessibleFieldData(row))])) };
|
|
54
|
+
}
|
|
45
55
|
function validateRecord(schema, layout, record) {
|
|
46
56
|
const layoutSchema = schema.layouts[layout];
|
|
47
57
|
if (!layoutSchema)
|
|
@@ -1,22 +1,26 @@
|
|
|
1
1
|
import { Database } from '../connection/database.js';
|
|
2
2
|
import { DataApiProvider } from '../connection/DataApiProvider.js';
|
|
3
|
+
import { ApiLayoutMetadata, isAccessibleFieldMetadata } from '../models/apiResults.js';
|
|
3
4
|
export function dataApiSchemaSource(options) {
|
|
4
5
|
return {
|
|
5
6
|
async introspect() {
|
|
6
7
|
const database = Database.create({ provider: new DataApiProvider(options) });
|
|
7
8
|
try {
|
|
8
9
|
const layouts = await database.listLayouts();
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
10
|
+
const inspected = await Promise.all(layouts.map(async (layout) => {
|
|
11
|
+
// Read raw metadata here so inaccessible placeholders can produce diagnostics before stripping.
|
|
12
|
+
const { value } = await database.execute({ type: 'layout.metadata', layout: layout.name });
|
|
13
|
+
const metadata = ApiLayoutMetadata.parse(value);
|
|
14
|
+
const diagnostics = metadata.fieldMetaData.filter(isInaccessible).map(field => ({ level: 'warning', layout: layout.name, message: `Field ${JSON.stringify(field.name)} is inaccessible and was excluded from generated types. Check this account's field privileges.` }));
|
|
15
|
+
for (const [portal, fields] of Object.entries(metadata.portalMetaData))
|
|
16
|
+
for (const field of fields.filter(isInaccessible))
|
|
17
|
+
diagnostics.push({ level: 'warning', layout: layout.name, portal, message: `Portal field ${JSON.stringify(field.name)} is inaccessible and was excluded from generated types. Check this account's field privileges.` });
|
|
18
|
+
return {
|
|
19
|
+
layout: { name: layout.name, fields: unique(metadata.fieldMetaData.filter(isAccessibleFieldMetadata).map(toField)), portals: Object.fromEntries(Object.entries(metadata.portalMetaData).map(([name, fields]) => [name, unique(fields.filter(isAccessibleFieldMetadata).map(toField))])) },
|
|
20
|
+
diagnostics
|
|
21
|
+
};
|
|
22
|
+
}));
|
|
23
|
+
return { version: 1, layouts: inspected.map(item => item.layout), diagnostics: inspected.flatMap(item => item.diagnostics) };
|
|
20
24
|
}
|
|
21
25
|
finally {
|
|
22
26
|
await database.close();
|
|
@@ -24,7 +28,10 @@ export function dataApiSchemaSource(options) {
|
|
|
24
28
|
}
|
|
25
29
|
};
|
|
26
30
|
}
|
|
31
|
+
function isInaccessible(field) { return field.type === 'invalid' || field.result === 'invalid' || field.name === '<No Access>'; }
|
|
27
32
|
function toField(field) {
|
|
33
|
+
if (!isAccessibleFieldMetadata(field))
|
|
34
|
+
throw new Error('Cannot generate an inaccessible field');
|
|
28
35
|
return { name: field.name, result: field.result, type: field.type, writable: field.type === 'normal', required: field.notEmpty };
|
|
29
36
|
}
|
|
30
37
|
function unique(fields) {
|
package/dist/typegen/generate.js
CHANGED
|
@@ -2,8 +2,14 @@ import { mkdir, rename, rm, writeFile } from 'node:fs/promises';
|
|
|
2
2
|
import { dirname, resolve } from 'node:path';
|
|
3
3
|
import { zodTypegenValidator } from './zod.js';
|
|
4
4
|
export async function generate(config) {
|
|
5
|
+
const diagnostics = [];
|
|
5
6
|
const databases = await Promise.all(databaseEntries(config).map(async ([key, databaseConfig]) => {
|
|
6
7
|
const discovered = await databaseConfig.source.introspect();
|
|
8
|
+
for (const diagnostic of discovered.diagnostics ?? []) {
|
|
9
|
+
const item = { ...diagnostic, database: key };
|
|
10
|
+
diagnostics.push(item);
|
|
11
|
+
(config.onDiagnostic ?? defaultDiagnosticReporter)(item);
|
|
12
|
+
}
|
|
7
13
|
const selected = databaseConfig.layouts ? discovered.layouts.filter(layout => databaseConfig.layouts.includes(layout.name)) : discovered.layouts;
|
|
8
14
|
const missing = databaseConfig.layouts?.filter(name => !selected.some(layout => layout.name === name)) ?? [];
|
|
9
15
|
if (missing.length)
|
|
@@ -20,8 +26,9 @@ export async function generate(config) {
|
|
|
20
26
|
await mkdir(dirname(output), { recursive: true });
|
|
21
27
|
await rm(output, { recursive: true, force: true });
|
|
22
28
|
await rename(temporary, output);
|
|
23
|
-
return { output, databases: databases.length, layouts: databases.reduce((sum, db) => sum + db.schema.layouts.length, 0) };
|
|
29
|
+
return { output, databases: databases.length, layouts: databases.reduce((sum, db) => sum + db.schema.layouts.length, 0), diagnostics };
|
|
24
30
|
}
|
|
31
|
+
function defaultDiagnosticReporter(diagnostic) { console.warn(`[easyfm:typegen] warning [${diagnostic.database}${diagnostic.layout ? `/${diagnostic.layout}` : ''}${diagnostic.portal ? `/${diagnostic.portal}` : ''}]: ${diagnostic.message}`); }
|
|
25
32
|
function databaseEntries(config) {
|
|
26
33
|
if (config.databases && Object.keys(config.databases).length)
|
|
27
34
|
return Object.entries(config.databases);
|
package/dist/typegen/index.d.ts
CHANGED
|
@@ -3,4 +3,4 @@ export { dataApiSchemaSource } from './dataApiSchemaSource.js';
|
|
|
3
3
|
export { zodTypegenValidator } from './zod.js';
|
|
4
4
|
export { configExists, readEnvironment, writeDataApiInitialization, writeMultiDatabaseInitialization, type DataApiInitAnswers, type MultiDatabaseInitAnswers } from './init.js';
|
|
5
5
|
export { ensureZodInstalled, getZodInstallPlan, type InstallPlan } from './dependencies.js';
|
|
6
|
-
export { defineTypegenConfig, type SchemaSource, type TypegenConfig, type TypegenDatabaseConfig, type TypegenField, type TypegenLayout, type TypegenSchema, type TypegenTransport, type TypegenValidator } from './types.js';
|
|
6
|
+
export { defineTypegenConfig, type SchemaSource, type TypegenConfig, type TypegenDatabaseConfig, type TypegenDiagnostic, type TypegenField, type TypegenLayout, type TypegenSchema, type TypegenTransport, type TypegenValidator } from './types.js';
|
package/dist/typegen/types.d.ts
CHANGED
|
@@ -12,9 +12,16 @@ export interface TypegenLayout {
|
|
|
12
12
|
fields: TypegenField[];
|
|
13
13
|
portals: Record<string, TypegenField[]>;
|
|
14
14
|
}
|
|
15
|
+
export interface TypegenDiagnostic {
|
|
16
|
+
level: 'warning';
|
|
17
|
+
message: string;
|
|
18
|
+
layout?: string;
|
|
19
|
+
portal?: string;
|
|
20
|
+
}
|
|
15
21
|
export interface TypegenSchema {
|
|
16
22
|
version: 1;
|
|
17
23
|
layouts: TypegenLayout[];
|
|
24
|
+
diagnostics?: TypegenDiagnostic[];
|
|
18
25
|
}
|
|
19
26
|
export type TypegenTransport = 'data-api' | 'odata';
|
|
20
27
|
export interface SchemaSource {
|
|
@@ -38,6 +45,9 @@ export interface TypegenConfig {
|
|
|
38
45
|
/** Defaults to the built-in strict Zod validator. */
|
|
39
46
|
validator?: TypegenValidator;
|
|
40
47
|
databases?: Record<string, TypegenDatabaseConfig>;
|
|
48
|
+
onDiagnostic?: (diagnostic: TypegenDiagnostic & {
|
|
49
|
+
database: string;
|
|
50
|
+
}) => void;
|
|
41
51
|
}
|
|
42
52
|
export interface TypegenDatabaseConfig {
|
|
43
53
|
source: SchemaSource;
|