@eide/foir-cli 0.1.3 → 0.1.5
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 +2 -0
- package/dist/codegen/fetch-customer-profile-schema.d.ts +12 -0
- package/dist/codegen/fetch-customer-profile-schema.d.ts.map +1 -0
- package/dist/codegen/fetch-customer-profile-schema.js +21 -0
- package/dist/codegen/fetch-models.d.ts.map +1 -1
- package/dist/codegen/field-mapping.d.ts.map +1 -1
- package/dist/codegen/field-mapping.js +60 -16
- package/dist/codegen/generators/customer-profile-types.d.ts +6 -0
- package/dist/codegen/generators/customer-profile-types.d.ts.map +1 -0
- package/dist/codegen/generators/customer-profile-types.js +45 -0
- package/dist/codegen/generators/model-types.d.ts.map +1 -1
- package/dist/codegen/generators/model-types.js +4 -2
- package/dist/codegen/generators/swift-field-types.d.ts +5 -0
- package/dist/codegen/generators/swift-field-types.d.ts.map +1 -0
- package/dist/codegen/generators/swift-field-types.js +145 -0
- package/dist/codegen/generators/swift-model-keys.d.ts +6 -0
- package/dist/codegen/generators/swift-model-keys.d.ts.map +1 -0
- package/dist/codegen/generators/swift-model-keys.js +25 -0
- package/dist/codegen/generators/swift-types.d.ts +13 -0
- package/dist/codegen/generators/swift-types.d.ts.map +1 -0
- package/dist/codegen/generators/swift-types.js +186 -0
- package/dist/codegen/swift-field-mapping.d.ts +30 -0
- package/dist/codegen/swift-field-mapping.d.ts.map +1 -0
- package/dist/codegen/swift-field-mapping.js +156 -0
- package/dist/codegen/write-files.d.ts.map +1 -1
- package/dist/codegen/write-files.js +2 -1
- package/dist/commands/customer-profiles.d.ts +4 -0
- package/dist/commands/customer-profiles.d.ts.map +1 -0
- package/dist/commands/customer-profiles.js +97 -0
- package/dist/commands/pull.d.ts.map +1 -1
- package/dist/commands/pull.js +61 -11
- package/dist/config/pull-config.d.ts +2 -0
- package/dist/config/pull-config.d.ts.map +1 -1
- package/dist/config/pull-config.js +7 -2
- package/dist/config/types.d.ts +2 -0
- package/dist/config/types.d.ts.map +1 -1
- package/dist/graphql/queries.d.ts +4 -0
- package/dist/graphql/queries.d.ts.map +1 -1
- package/dist/graphql/queries.js +13 -0
- package/package.json +11 -11
package/dist/cli.js
CHANGED
|
@@ -19,6 +19,7 @@ import { registerRecordsCommands } from './commands/records.js';
|
|
|
19
19
|
import { registerModelsCommands } from './commands/models.js';
|
|
20
20
|
import { registerSearchCommands } from './commands/search.js';
|
|
21
21
|
import { registerCustomersCommands } from './commands/customers.js';
|
|
22
|
+
import { registerCustomerProfilesCommands } from './commands/customer-profiles.js';
|
|
22
23
|
import { registerSegmentsCommands } from './commands/segments.js';
|
|
23
24
|
import { registerExperimentsCommands } from './commands/experiments.js';
|
|
24
25
|
import { registerSettingsCommands } from './commands/settings.js';
|
|
@@ -61,6 +62,7 @@ registerRecordsCommands(program, getGlobalOpts);
|
|
|
61
62
|
registerModelsCommands(program, getGlobalOpts);
|
|
62
63
|
registerSearchCommands(program, getGlobalOpts);
|
|
63
64
|
registerCustomersCommands(program, getGlobalOpts);
|
|
65
|
+
registerCustomerProfilesCommands(program, getGlobalOpts);
|
|
64
66
|
registerSegmentsCommands(program, getGlobalOpts);
|
|
65
67
|
registerExperimentsCommands(program, getGlobalOpts);
|
|
66
68
|
registerSettingsCommands(program, getGlobalOpts);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fetches the customer profile schema from the platform GraphQL API for codegen.
|
|
3
|
+
*/
|
|
4
|
+
import type { GraphQLClient } from 'graphql-request';
|
|
5
|
+
import type { FieldSchemaForGen } from './field-mapping.js';
|
|
6
|
+
export interface CodegenCustomerProfileSchema {
|
|
7
|
+
id: string;
|
|
8
|
+
fields: FieldSchemaForGen[];
|
|
9
|
+
version: number;
|
|
10
|
+
}
|
|
11
|
+
export declare function fetchCustomerProfileSchema(client: GraphQLClient): Promise<CodegenCustomerProfileSchema | null>;
|
|
12
|
+
//# sourceMappingURL=fetch-customer-profile-schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetch-customer-profile-schema.d.ts","sourceRoot":"","sources":["../../src/codegen/fetch-customer-profile-schema.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAErD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAE5D,MAAM,WAAW,4BAA4B;IAC3C,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,iBAAiB,EAAE,CAAC;IAC5B,OAAO,EAAE,MAAM,CAAC;CACjB;AAqBD,wBAAsB,0BAA0B,CAC9C,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,4BAA4B,GAAG,IAAI,CAAC,CAiB9C"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fetches the customer profile schema from the platform GraphQL API for codegen.
|
|
3
|
+
*/
|
|
4
|
+
import { CUSTOMER_PROFILE_SCHEMA } from '../graphql/queries.js';
|
|
5
|
+
export async function fetchCustomerProfileSchema(client) {
|
|
6
|
+
const data = await client.request(CUSTOMER_PROFILE_SCHEMA);
|
|
7
|
+
if (!data.customerProfileSchema)
|
|
8
|
+
return null;
|
|
9
|
+
return {
|
|
10
|
+
id: data.customerProfileSchema.id,
|
|
11
|
+
version: data.customerProfileSchema.version,
|
|
12
|
+
fields: (data.customerProfileSchema.fields ?? []).map((f) => ({
|
|
13
|
+
key: f.key,
|
|
14
|
+
type: f.type,
|
|
15
|
+
label: f.label,
|
|
16
|
+
required: f.required,
|
|
17
|
+
helpText: f.helpText,
|
|
18
|
+
options: f.config,
|
|
19
|
+
})),
|
|
20
|
+
};
|
|
21
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch-models.d.ts","sourceRoot":"","sources":["../../src/codegen/fetch-models.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAErD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAE5D,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;IAClB,cAAc,EAAE,OAAO,CAAC;IACxB,UAAU,CAAC,EAAE;
|
|
1
|
+
{"version":3,"file":"fetch-models.d.ts","sourceRoot":"","sources":["../../src/codegen/fetch-models.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAErD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAE5D,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;IAClB,cAAc,EAAE,OAAO,CAAC;IACxB,UAAU,CAAC,EAAE;QACX,OAAO,EAAE,OAAO,CAAC;QACjB,MAAM,EAAE,KAAK,CAAC;YAAE,SAAS,EAAE,MAAM,CAAC;YAAC,MAAM,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;KACvD,CAAC;CACH;AAED,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,iBAAiB,EAAE,CAAC;IAC5B,MAAM,EAAE,kBAAkB,CAAC;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AAgCD,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,YAAY,EAAE,CAAC,CAezB;AAED;;GAEG;AACH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,YAAY,EAAE,EACtB,OAAO,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,aAAa,CAAC,EAAE,OAAO,CAAA;CAAE,GACpD,YAAY,EAAE,CAahB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"field-mapping.d.ts","sourceRoot":"","sources":["../../src/codegen/field-mapping.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,eAAO,MAAM,qBAAqB,aAsBhC,CAAC;AAEH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE1D;AAED,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,
|
|
1
|
+
{"version":3,"file":"field-mapping.d.ts","sourceRoot":"","sources":["../../src/codegen/field-mapping.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,eAAO,MAAM,qBAAqB,aAsBhC,CAAC;AAEH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE1D;AAED,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CA0D1D,CAAC;AAEF,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED,wBAAgB,YAAY,CAC1B,KAAK,EAAE,iBAAiB,EACxB,IAAI,GAAE,QAAQ,GAAG,OAAkB,GAClC,MAAM,CAwCR;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,iBAAiB,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC,CAc3E;AAED,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,iBAAiB,EAAE,GAC1B,GAAG,CAAC,MAAM,CAAC,CAiBb;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAK/C;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAIhD;AAED,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAKrD;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,iBAAiB,GAAG,MAAM,CAiFjE"}
|
|
@@ -30,26 +30,62 @@ export function isPrimitiveFieldType(type) {
|
|
|
30
30
|
}
|
|
31
31
|
export const FIELD_TYPE_MAPPING = {
|
|
32
32
|
text: { outputType: 'string', inputType: 'string' },
|
|
33
|
-
richtext: {
|
|
33
|
+
richtext: {
|
|
34
|
+
outputType: 'RichtextValue',
|
|
35
|
+
inputType: 'RichtextValue',
|
|
36
|
+
needsImport: 'field-types',
|
|
37
|
+
},
|
|
34
38
|
number: { outputType: 'number', inputType: 'number' },
|
|
35
39
|
boolean: { outputType: 'boolean', inputType: 'boolean' },
|
|
36
40
|
email: { outputType: 'string', inputType: 'string' },
|
|
37
41
|
phone: { outputType: 'string', inputType: 'string' },
|
|
38
42
|
url: { outputType: 'string', inputType: 'string' },
|
|
39
43
|
date: { outputType: 'Date', inputType: 'string' },
|
|
40
|
-
image: {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
+
image: {
|
|
45
|
+
outputType: 'ImageValue',
|
|
46
|
+
inputType: 'string',
|
|
47
|
+
needsImport: 'field-types',
|
|
48
|
+
},
|
|
49
|
+
video: {
|
|
50
|
+
outputType: 'VideoValue',
|
|
51
|
+
inputType: 'string',
|
|
52
|
+
needsImport: 'field-types',
|
|
53
|
+
},
|
|
54
|
+
file: {
|
|
55
|
+
outputType: 'FileValue',
|
|
56
|
+
inputType: 'string',
|
|
57
|
+
needsImport: 'field-types',
|
|
58
|
+
},
|
|
59
|
+
currency: {
|
|
60
|
+
outputType: 'CurrencyValue',
|
|
61
|
+
inputType: 'CurrencyValue',
|
|
62
|
+
needsImport: 'field-types',
|
|
63
|
+
},
|
|
44
64
|
select: { outputType: 'string', inputType: 'string' },
|
|
45
65
|
multiselect: { outputType: 'string[]', inputType: 'string[]' },
|
|
46
66
|
json: { outputType: 'unknown', inputType: 'unknown' },
|
|
47
67
|
list: { outputType: 'unknown[]', inputType: 'unknown[]' },
|
|
48
68
|
tree: { outputType: 'unknown[]', inputType: 'unknown[]' },
|
|
49
|
-
flexible: {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
69
|
+
flexible: {
|
|
70
|
+
outputType: 'FlexibleFieldItem[]',
|
|
71
|
+
inputType: 'FlexibleFieldItem[]',
|
|
72
|
+
needsImport: 'field-types',
|
|
73
|
+
},
|
|
74
|
+
'entity-reference': {
|
|
75
|
+
outputType: 'ReferenceValue',
|
|
76
|
+
inputType: 'ReferenceValue',
|
|
77
|
+
needsImport: 'field-types',
|
|
78
|
+
},
|
|
79
|
+
reference: {
|
|
80
|
+
outputType: 'ReferenceValue',
|
|
81
|
+
inputType: 'ReferenceValue',
|
|
82
|
+
needsImport: 'field-types',
|
|
83
|
+
},
|
|
84
|
+
link: {
|
|
85
|
+
outputType: 'LinkValue',
|
|
86
|
+
inputType: 'LinkValue',
|
|
87
|
+
needsImport: 'field-types',
|
|
88
|
+
},
|
|
53
89
|
};
|
|
54
90
|
export function getFieldType(field, mode = 'output') {
|
|
55
91
|
if (!field?.type)
|
|
@@ -73,7 +109,8 @@ export function getFieldType(field, mode = 'output') {
|
|
|
73
109
|
tsType = `(${options.map((o) => `'${o.value}'`).join(' | ')})[]`;
|
|
74
110
|
}
|
|
75
111
|
}
|
|
76
|
-
if ((field.type === 'list' || field.type === 'tree') &&
|
|
112
|
+
if ((field.type === 'list' || field.type === 'tree') &&
|
|
113
|
+
field.options?.itemType) {
|
|
77
114
|
const itemType = field.options.itemType;
|
|
78
115
|
const itemMapping = FIELD_TYPE_MAPPING[itemType];
|
|
79
116
|
if (itemMapping) {
|
|
@@ -91,7 +128,8 @@ export function getRequiredImports(fields) {
|
|
|
91
128
|
const mapping = FIELD_TYPE_MAPPING[field.type];
|
|
92
129
|
if (mapping?.needsImport)
|
|
93
130
|
imports.add(mapping.needsImport);
|
|
94
|
-
if ((field.type === 'list' || field.type === 'tree') &&
|
|
131
|
+
if ((field.type === 'list' || field.type === 'tree') &&
|
|
132
|
+
field.options?.itemType) {
|
|
95
133
|
const itemMapping = FIELD_TYPE_MAPPING[field.options.itemType];
|
|
96
134
|
if (itemMapping?.needsImport)
|
|
97
135
|
imports.add(itemMapping.needsImport);
|
|
@@ -105,7 +143,8 @@ export function getInlineSchemaReferences(fields) {
|
|
|
105
143
|
if (!isPrimitiveFieldType(field.type) && !FIELD_TYPE_MAPPING[field.type]) {
|
|
106
144
|
refs.add(field.type);
|
|
107
145
|
}
|
|
108
|
-
if ((field.type === 'list' || field.type === 'tree') &&
|
|
146
|
+
if ((field.type === 'list' || field.type === 'tree') &&
|
|
147
|
+
field.options?.itemType) {
|
|
109
148
|
const itemType = field.options.itemType;
|
|
110
149
|
if (!isPrimitiveFieldType(itemType) && !FIELD_TYPE_MAPPING[itemType]) {
|
|
111
150
|
refs.add(itemType);
|
|
@@ -156,7 +195,8 @@ export function generateFieldDef(field) {
|
|
|
156
195
|
if (field.options.step !== undefined)
|
|
157
196
|
parts.push(`step: ${field.options.step}`);
|
|
158
197
|
}
|
|
159
|
-
if ((field.type === 'select' || field.type === 'multiselect') &&
|
|
198
|
+
if ((field.type === 'select' || field.type === 'multiselect') &&
|
|
199
|
+
field.options?.options) {
|
|
160
200
|
const options = field.options.options;
|
|
161
201
|
const optionsStr = options
|
|
162
202
|
.filter((o) => o.value !== undefined)
|
|
@@ -168,20 +208,24 @@ export function generateFieldDef(field) {
|
|
|
168
208
|
.join(', ');
|
|
169
209
|
parts.push(`options: [${optionsStr}]`);
|
|
170
210
|
}
|
|
171
|
-
if ((field.type === 'entity-reference' || field.type === 'reference') &&
|
|
211
|
+
if ((field.type === 'entity-reference' || field.type === 'reference') &&
|
|
212
|
+
field.options?.referenceTypes) {
|
|
172
213
|
const refTypes = field.options.referenceTypes;
|
|
173
214
|
parts.push(`referenceTypes: [${refTypes.map((t) => `'${t}'`).join(', ')}]`);
|
|
174
215
|
if (field.options.multiple)
|
|
175
216
|
parts.push('multiple: true');
|
|
176
217
|
}
|
|
177
|
-
if ((field.type === 'list' || field.type === 'tree') &&
|
|
218
|
+
if ((field.type === 'list' || field.type === 'tree') &&
|
|
219
|
+
field.options?.itemType) {
|
|
178
220
|
parts.push(`itemType: '${field.options.itemType}'`);
|
|
179
221
|
if (field.options.minItems !== undefined)
|
|
180
222
|
parts.push(`minItems: ${field.options.minItems}`);
|
|
181
223
|
if (field.options.maxItems !== undefined)
|
|
182
224
|
parts.push(`maxItems: ${field.options.maxItems}`);
|
|
183
225
|
}
|
|
184
|
-
if ((field.type === 'image' ||
|
|
226
|
+
if ((field.type === 'image' ||
|
|
227
|
+
field.type === 'video' ||
|
|
228
|
+
field.type === 'file') &&
|
|
185
229
|
field.options) {
|
|
186
230
|
if (field.options.allowedTypes) {
|
|
187
231
|
const types = field.options.allowedTypes;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generates TypeScript types for the customer profile schema.
|
|
3
|
+
*/
|
|
4
|
+
import type { CodegenCustomerProfileSchema } from '../fetch-customer-profile-schema.js';
|
|
5
|
+
export declare function generateCustomerProfileTypes(schema: CodegenCustomerProfileSchema): string;
|
|
6
|
+
//# sourceMappingURL=customer-profile-types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"customer-profile-types.d.ts","sourceRoot":"","sources":["../../../src/codegen/generators/customer-profile-types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,qCAAqC,CAAC;AAQxF,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,4BAA4B,GACnC,MAAM,CAqCR"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generates TypeScript types for the customer profile schema.
|
|
3
|
+
*/
|
|
4
|
+
import { getFieldType, sanitizeFieldName, FIELD_TYPE_MAPPING, } from '../field-mapping.js';
|
|
5
|
+
export function generateCustomerProfileTypes(schema) {
|
|
6
|
+
const fields = schema.fields ?? [];
|
|
7
|
+
const fieldTypeImports = getFieldTypeImportsForFields(fields);
|
|
8
|
+
let code = `/**
|
|
9
|
+
* Customer Profile Types
|
|
10
|
+
*
|
|
11
|
+
* @generated by foir from customer profile schema (version ${schema.version}) — DO NOT EDIT MANUALLY
|
|
12
|
+
*/\n\n`;
|
|
13
|
+
if (fieldTypeImports.size > 0) {
|
|
14
|
+
const types = Array.from(fieldTypeImports).sort().join(', ');
|
|
15
|
+
code += `import type { ${types} } from '../field-types.js';\n\n`;
|
|
16
|
+
}
|
|
17
|
+
code += `/**
|
|
18
|
+
* Customer Profile Data
|
|
19
|
+
* Typed field values for customer profiles
|
|
20
|
+
*
|
|
21
|
+
* @generated from customer profile schema (version ${schema.version})
|
|
22
|
+
*/\n`;
|
|
23
|
+
code += `export interface CustomerProfileData {\n`;
|
|
24
|
+
for (const field of fields) {
|
|
25
|
+
const fieldName = sanitizeFieldName(field.key);
|
|
26
|
+
const fieldType = getFieldType(field, 'output');
|
|
27
|
+
const optional = field.required ? '' : '?';
|
|
28
|
+
if (field.helpText) {
|
|
29
|
+
code += ` /** ${field.helpText} */\n`;
|
|
30
|
+
}
|
|
31
|
+
code += ` ${fieldName}${optional}: ${fieldType};\n`;
|
|
32
|
+
}
|
|
33
|
+
code += `}\n`;
|
|
34
|
+
return code;
|
|
35
|
+
}
|
|
36
|
+
function getFieldTypeImportsForFields(fields) {
|
|
37
|
+
const imports = new Set();
|
|
38
|
+
for (const field of fields) {
|
|
39
|
+
const mapping = FIELD_TYPE_MAPPING[field.type];
|
|
40
|
+
if (mapping?.needsImport === 'field-types') {
|
|
41
|
+
imports.add(mapping.outputType);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return imports;
|
|
45
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-types.d.ts","sourceRoot":"","sources":["../../../src/codegen/generators/model-types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAgBvD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,YAAY,EACnB,SAAS,EAAE,YAAY,EAAE,GACxB,MAAM,
|
|
1
|
+
{"version":3,"file":"model-types.d.ts","sourceRoot":"","sources":["../../../src/codegen/generators/model-types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAgBvD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,YAAY,EACnB,SAAS,EAAE,YAAY,EAAE,GACxB,MAAM,CAyBR"}
|
|
@@ -119,7 +119,8 @@ function generateDataInterface(model, fields, interfaceName, allModels) {
|
|
|
119
119
|
fieldType = toPascalCase(field.type) + 'Data';
|
|
120
120
|
}
|
|
121
121
|
// Handle list/tree itemType refs
|
|
122
|
-
if ((field.type === 'list' || field.type === 'tree') &&
|
|
122
|
+
if ((field.type === 'list' || field.type === 'tree') &&
|
|
123
|
+
field.options?.itemType) {
|
|
123
124
|
const itemRefModel = allModels.find((m) => m.key === field.options.itemType);
|
|
124
125
|
if (itemRefModel && !isInlineOnlyModel(itemRefModel)) {
|
|
125
126
|
fieldType = toPascalCase(field.options.itemType) + 'Data[]';
|
|
@@ -139,7 +140,8 @@ function getFieldTypeImportsForFields(fields) {
|
|
|
139
140
|
if (mapping?.needsImport === 'field-types') {
|
|
140
141
|
imports.add(mapping.outputType);
|
|
141
142
|
}
|
|
142
|
-
if ((field.type === 'list' || field.type === 'tree') &&
|
|
143
|
+
if ((field.type === 'list' || field.type === 'tree') &&
|
|
144
|
+
field.options?.itemType) {
|
|
143
145
|
const itemMapping = FIELD_TYPE_MAPPING[field.options.itemType];
|
|
144
146
|
if (itemMapping?.needsImport === 'field-types') {
|
|
145
147
|
imports.add(itemMapping.outputType);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"swift-field-types.d.ts","sourceRoot":"","sources":["../../../src/codegen/generators/swift-field-types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,wBAAgB,2BAA2B,IAAI,MAAM,CA6IpD"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generates the shared FieldTypes.swift file with platform value type structs.
|
|
3
|
+
*/
|
|
4
|
+
export function generateSwiftFieldTypesFile() {
|
|
5
|
+
return `//
|
|
6
|
+
// FieldTypes.swift
|
|
7
|
+
//
|
|
8
|
+
// Shared value types for platform sync data.
|
|
9
|
+
//
|
|
10
|
+
// @generated by foir \u2014 DO NOT EDIT MANUALLY
|
|
11
|
+
//
|
|
12
|
+
|
|
13
|
+
import Foundation
|
|
14
|
+
|
|
15
|
+
// MARK: - Image
|
|
16
|
+
|
|
17
|
+
struct ImageValue {
|
|
18
|
+
let id: String
|
|
19
|
+
let url: String
|
|
20
|
+
var alt: String?
|
|
21
|
+
var width: Int?
|
|
22
|
+
var height: Int?
|
|
23
|
+
|
|
24
|
+
func toSyncData() -> [String: Any] {
|
|
25
|
+
var data: [String: Any] = ["id": id, "url": url]
|
|
26
|
+
if let alt { data["alt"] = alt }
|
|
27
|
+
if let width { data["width"] = width }
|
|
28
|
+
if let height { data["height"] = height }
|
|
29
|
+
return data
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
static func fromSyncData(_ data: [String: Any]) -> ImageValue {
|
|
33
|
+
ImageValue(
|
|
34
|
+
id: data["id"] as? String ?? "",
|
|
35
|
+
url: data["url"] as? String ?? "",
|
|
36
|
+
alt: data["alt"] as? String,
|
|
37
|
+
width: data["width"] as? Int,
|
|
38
|
+
height: data["height"] as? Int
|
|
39
|
+
)
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// MARK: - Video
|
|
44
|
+
|
|
45
|
+
struct VideoValue {
|
|
46
|
+
let id: String
|
|
47
|
+
let url: String
|
|
48
|
+
var thumbnail: String?
|
|
49
|
+
var duration: Double?
|
|
50
|
+
|
|
51
|
+
func toSyncData() -> [String: Any] {
|
|
52
|
+
var data: [String: Any] = ["id": id, "url": url]
|
|
53
|
+
if let thumbnail { data["thumbnail"] = thumbnail }
|
|
54
|
+
if let duration { data["duration"] = duration }
|
|
55
|
+
return data
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
static func fromSyncData(_ data: [String: Any]) -> VideoValue {
|
|
59
|
+
VideoValue(
|
|
60
|
+
id: data["id"] as? String ?? "",
|
|
61
|
+
url: data["url"] as? String ?? "",
|
|
62
|
+
thumbnail: data["thumbnail"] as? String,
|
|
63
|
+
duration: data["duration"] as? Double
|
|
64
|
+
)
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// MARK: - File
|
|
69
|
+
|
|
70
|
+
struct FileValue {
|
|
71
|
+
let id: String
|
|
72
|
+
let url: String
|
|
73
|
+
let name: String
|
|
74
|
+
let size: Int
|
|
75
|
+
let mimeType: String
|
|
76
|
+
|
|
77
|
+
func toSyncData() -> [String: Any] {
|
|
78
|
+
[
|
|
79
|
+
"id": id,
|
|
80
|
+
"url": url,
|
|
81
|
+
"name": name,
|
|
82
|
+
"size": size,
|
|
83
|
+
"mimeType": mimeType,
|
|
84
|
+
]
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
static func fromSyncData(_ data: [String: Any]) -> FileValue {
|
|
88
|
+
FileValue(
|
|
89
|
+
id: data["id"] as? String ?? "",
|
|
90
|
+
url: data["url"] as? String ?? "",
|
|
91
|
+
name: data["name"] as? String ?? "",
|
|
92
|
+
size: data["size"] as? Int ?? 0,
|
|
93
|
+
mimeType: data["mimeType"] as? String ?? ""
|
|
94
|
+
)
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// MARK: - Currency
|
|
99
|
+
|
|
100
|
+
struct CurrencyValue {
|
|
101
|
+
let amount: Double
|
|
102
|
+
let currency: String
|
|
103
|
+
|
|
104
|
+
func toSyncData() -> [String: Any] {
|
|
105
|
+
["amount": amount, "currency": currency]
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
static func fromSyncData(_ data: [String: Any]) -> CurrencyValue {
|
|
109
|
+
CurrencyValue(
|
|
110
|
+
amount: data["amount"] as? Double ?? 0,
|
|
111
|
+
currency: data["currency"] as? String ?? ""
|
|
112
|
+
)
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// MARK: - Link
|
|
117
|
+
|
|
118
|
+
struct LinkValue {
|
|
119
|
+
let type: String
|
|
120
|
+
var entityModelKey: String?
|
|
121
|
+
var entityNaturalKey: String?
|
|
122
|
+
var url: String?
|
|
123
|
+
var target: String?
|
|
124
|
+
|
|
125
|
+
func toSyncData() -> [String: Any] {
|
|
126
|
+
var data: [String: Any] = ["type": type]
|
|
127
|
+
if let entityModelKey { data["entityModelKey"] = entityModelKey }
|
|
128
|
+
if let entityNaturalKey { data["entityNaturalKey"] = entityNaturalKey }
|
|
129
|
+
if let url { data["url"] = url }
|
|
130
|
+
if let target { data["target"] = target }
|
|
131
|
+
return data
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
static func fromSyncData(_ data: [String: Any]) -> LinkValue {
|
|
135
|
+
LinkValue(
|
|
136
|
+
type: data["type"] as? String ?? "",
|
|
137
|
+
entityModelKey: data["entityModelKey"] as? String,
|
|
138
|
+
entityNaturalKey: data["entityNaturalKey"] as? String,
|
|
139
|
+
url: data["url"] as? String,
|
|
140
|
+
target: data["target"] as? String
|
|
141
|
+
)
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
`;
|
|
145
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"swift-model-keys.d.ts","sourceRoot":"","sources":["../../../src/codegen/generators/swift-model-keys.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGvD,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,CAwBrE"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generates ModelKeys.swift with all model key constants in one enum.
|
|
3
|
+
*/
|
|
4
|
+
import { toCamelCase } from '../field-mapping.js';
|
|
5
|
+
export function generateSwiftModelKeys(models) {
|
|
6
|
+
const lines = [];
|
|
7
|
+
lines.push('//');
|
|
8
|
+
lines.push('// ModelKeys.swift');
|
|
9
|
+
lines.push('//');
|
|
10
|
+
lines.push('// All model key constants.');
|
|
11
|
+
lines.push('//');
|
|
12
|
+
lines.push('// @generated by foir \u2014 DO NOT EDIT MANUALLY');
|
|
13
|
+
lines.push('//');
|
|
14
|
+
lines.push('');
|
|
15
|
+
lines.push('import Foundation');
|
|
16
|
+
lines.push('');
|
|
17
|
+
lines.push('enum ModelKeys {');
|
|
18
|
+
for (const model of models) {
|
|
19
|
+
const propName = toCamelCase(model.key);
|
|
20
|
+
lines.push(` static let ${propName} = "${model.key}"`);
|
|
21
|
+
}
|
|
22
|
+
lines.push('}');
|
|
23
|
+
lines.push('');
|
|
24
|
+
return lines.join('\n');
|
|
25
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generates per-model Swift files with:
|
|
3
|
+
* - Field key enum (compile-time safe field keys)
|
|
4
|
+
* - Data struct (typed representation)
|
|
5
|
+
* - Serialization helpers (toSyncData / fromSyncData)
|
|
6
|
+
* - Model config constant
|
|
7
|
+
*/
|
|
8
|
+
import type { CodegenModel } from '../fetch-models.js';
|
|
9
|
+
/**
|
|
10
|
+
* Generate a complete Swift file for a single model.
|
|
11
|
+
*/
|
|
12
|
+
export declare function generateSwiftModelFile(model: CodegenModel): string;
|
|
13
|
+
//# sourceMappingURL=swift-types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"swift-types.d.ts","sourceRoot":"","sources":["../../../src/codegen/generators/swift-types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAQvD;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,YAAY,GAAG,MAAM,CAkClE"}
|