@eide/foir-cli 0.1.16 → 0.1.18
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 +3 -0
- package/dist/codegen/field-mapping.d.ts +1 -0
- package/dist/codegen/field-mapping.d.ts.map +1 -1
- package/dist/codegen/field-mapping.js +8 -0
- package/dist/codegen/generators/customer-profile-hooks.d.ts +5 -0
- package/dist/codegen/generators/customer-profile-hooks.d.ts.map +1 -0
- package/dist/codegen/generators/customer-profile-hooks.js +78 -0
- package/dist/codegen/generators/customer-profile-loaders.d.ts +5 -0
- package/dist/codegen/generators/customer-profile-loaders.d.ts.map +1 -0
- package/dist/codegen/generators/customer-profile-loaders.js +67 -0
- package/dist/codegen/generators/customer-profile-operations.d.ts +5 -0
- package/dist/codegen/generators/customer-profile-operations.d.ts.map +1 -0
- package/dist/codegen/generators/customer-profile-operations.js +126 -0
- package/dist/codegen/generators/documents.d.ts.map +1 -1
- package/dist/codegen/generators/documents.js +4 -0
- package/dist/codegen/generators/public-schema-content.d.ts +14 -0
- package/dist/codegen/generators/public-schema-content.d.ts.map +1 -0
- package/dist/codegen/generators/public-schema-content.js +22 -0
- package/dist/codegen/generators/react-hooks-index.d.ts +6 -0
- package/dist/codegen/generators/react-hooks-index.d.ts.map +1 -0
- package/dist/codegen/generators/react-hooks-index.js +20 -0
- package/dist/codegen/generators/react-hooks.d.ts +7 -0
- package/dist/codegen/generators/react-hooks.d.ts.map +1 -0
- package/dist/codegen/generators/react-hooks.js +139 -0
- package/dist/codegen/generators/remix-loaders-index.d.ts +6 -0
- package/dist/codegen/generators/remix-loaders-index.d.ts.map +1 -0
- package/dist/codegen/generators/remix-loaders-index.js +20 -0
- package/dist/codegen/generators/remix-loaders.d.ts +7 -0
- package/dist/codegen/generators/remix-loaders.d.ts.map +1 -0
- package/dist/codegen/generators/remix-loaders.js +107 -0
- package/dist/codegen/generators/static-documents.d.ts +14 -0
- package/dist/codegen/generators/static-documents.d.ts.map +1 -0
- package/dist/codegen/generators/static-documents.js +766 -0
- package/dist/codegen/generators/typed-operations-common.d.ts +6 -0
- package/dist/codegen/generators/typed-operations-common.d.ts.map +1 -0
- package/dist/codegen/generators/typed-operations-common.js +74 -0
- package/dist/codegen/generators/typed-operations-index.d.ts +6 -0
- package/dist/codegen/generators/typed-operations-index.d.ts.map +1 -0
- package/dist/codegen/generators/typed-operations-index.js +22 -0
- package/dist/codegen/generators/typed-operations.d.ts +11 -0
- package/dist/codegen/generators/typed-operations.d.ts.map +1 -0
- package/dist/codegen/generators/typed-operations.js +251 -0
- package/dist/commands/create-extension.d.ts +4 -0
- package/dist/commands/create-extension.d.ts.map +1 -0
- package/dist/commands/create-extension.js +60 -0
- package/dist/commands/pull.d.ts.map +1 -1
- package/dist/commands/pull.js +135 -25
- package/dist/config/pull-config.d.ts +6 -0
- package/dist/config/pull-config.d.ts.map +1 -1
- package/dist/config/pull-config.js +50 -1
- package/dist/config/types.d.ts +23 -0
- package/dist/config/types.d.ts.map +1 -1
- package/dist/scaffold/package-manager.d.ts +12 -0
- package/dist/scaffold/package-manager.d.ts.map +1 -0
- package/dist/scaffold/package-manager.js +51 -0
- package/dist/scaffold/scaffold.d.ts +4 -0
- package/dist/scaffold/scaffold.d.ts.map +1 -0
- package/dist/scaffold/scaffold.js +462 -0
- package/package.json +1 -1
package/dist/commands/pull.js
CHANGED
|
@@ -17,6 +17,18 @@ import { generateSwiftModelKeys } from '../codegen/generators/swift-model-keys.j
|
|
|
17
17
|
import { generateCustomerProfileTypes } from '../codegen/generators/customer-profile-types.js';
|
|
18
18
|
import { generateSwiftCustomerProfileFile } from '../codegen/generators/swift-customer-profile.js';
|
|
19
19
|
import { generateCustomerProfileDocuments } from '../codegen/generators/customer-profile-documents.js';
|
|
20
|
+
import { generateStaticDocuments } from '../codegen/generators/static-documents.js';
|
|
21
|
+
import { generateTypedOperationsCommon } from '../codegen/generators/typed-operations-common.js';
|
|
22
|
+
import { generateTypedOperations, computeTypesRelPath } from '../codegen/generators/typed-operations.js';
|
|
23
|
+
import { generateTypedOperationsIndex } from '../codegen/generators/typed-operations-index.js';
|
|
24
|
+
import { generateCustomerProfileOperations } from '../codegen/generators/customer-profile-operations.js';
|
|
25
|
+
import { generateReactHooks } from '../codegen/generators/react-hooks.js';
|
|
26
|
+
import { generateReactHooksIndex } from '../codegen/generators/react-hooks-index.js';
|
|
27
|
+
import { generateCustomerProfileHooks } from '../codegen/generators/customer-profile-hooks.js';
|
|
28
|
+
import { generateRemixLoaders } from '../codegen/generators/remix-loaders.js';
|
|
29
|
+
import { generateRemixLoadersIndex } from '../codegen/generators/remix-loaders-index.js';
|
|
30
|
+
import { generateCustomerProfileLoaders } from '../codegen/generators/customer-profile-loaders.js';
|
|
31
|
+
import { fetchPublicSchema } from '../codegen/generators/public-schema-content.js';
|
|
20
32
|
import { writeFiles } from '../codegen/write-files.js';
|
|
21
33
|
export function registerPullCommand(program, globalOpts) {
|
|
22
34
|
program
|
|
@@ -39,12 +51,13 @@ export function registerPullCommand(program, globalOpts) {
|
|
|
39
51
|
swift: cmdOpts.swift,
|
|
40
52
|
};
|
|
41
53
|
const config = await loadPullConfig(flags);
|
|
42
|
-
// Fetch models + customer profile schema
|
|
54
|
+
// Fetch models + customer profile schema + public schema
|
|
43
55
|
const client = await createClient(opts);
|
|
44
56
|
console.log(chalk.dim('Fetching models…'));
|
|
45
|
-
const [allModels, cpSchema] = await Promise.all([
|
|
57
|
+
const [allModels, cpSchema, publicSchema] = await Promise.all([
|
|
46
58
|
fetchModelsForCodegen(client),
|
|
47
59
|
fetchCustomerProfileSchema(client),
|
|
60
|
+
fetchPublicSchema(client),
|
|
48
61
|
]);
|
|
49
62
|
if (allModels.length === 0 && !cpSchema) {
|
|
50
63
|
console.log(chalk.yellow('No models found. Nothing to generate.'));
|
|
@@ -59,7 +72,17 @@ export function registerPullCommand(program, globalOpts) {
|
|
|
59
72
|
const cwd = process.cwd();
|
|
60
73
|
const typesDir = resolve(cwd, config.output.types);
|
|
61
74
|
const docsDir = resolve(cwd, config.output.documents);
|
|
75
|
+
const opsDir = resolve(cwd, config.output.operations);
|
|
76
|
+
const hooksDir = config.output.hooks
|
|
77
|
+
? resolve(cwd, config.output.hooks)
|
|
78
|
+
: null;
|
|
79
|
+
const loadersDir = config.output.loaders
|
|
80
|
+
? resolve(cwd, config.output.loaders)
|
|
81
|
+
: null;
|
|
62
82
|
const files = [];
|
|
83
|
+
const hasCustomerProfile = !!(cpSchema && cpSchema.fields.length > 0);
|
|
84
|
+
const publicModels = models.filter((m) => m.config.publicApi && m.config.records);
|
|
85
|
+
// ─── Types ───────────────────────────────────────────────
|
|
63
86
|
// 1. Static files
|
|
64
87
|
files.push({
|
|
65
88
|
path: resolve(typesDir, 'field-types.ts'),
|
|
@@ -81,22 +104,27 @@ export function registerPullCommand(program, globalOpts) {
|
|
|
81
104
|
path: resolve(typesDir, 'models', 'index.ts'),
|
|
82
105
|
content: generateModelIndex(models),
|
|
83
106
|
});
|
|
84
|
-
// 4. Customer profile types
|
|
85
|
-
if (
|
|
107
|
+
// 4. Customer profile types
|
|
108
|
+
if (hasCustomerProfile) {
|
|
86
109
|
files.push({
|
|
87
110
|
path: resolve(typesDir, 'customer-profile.ts'),
|
|
88
111
|
content: generateCustomerProfileTypes(cpSchema),
|
|
89
112
|
});
|
|
90
113
|
}
|
|
91
|
-
// 5.
|
|
92
|
-
|
|
114
|
+
// 5. Main index
|
|
115
|
+
files.push({
|
|
116
|
+
path: resolve(typesDir, 'index.ts'),
|
|
117
|
+
content: generateMainIndex(hasCustomerProfile),
|
|
118
|
+
});
|
|
119
|
+
// ─── Documents (.graphql) ────────────────────────────────
|
|
120
|
+
// 6. Per-model GraphQL documents
|
|
93
121
|
for (const model of publicModels) {
|
|
94
122
|
files.push({
|
|
95
123
|
path: resolve(docsDir, `${model.key}.graphql`),
|
|
96
124
|
content: generateModelDocuments(model),
|
|
97
125
|
});
|
|
98
126
|
}
|
|
99
|
-
//
|
|
127
|
+
// 6a. Shared fragments
|
|
100
128
|
const hasSharingModels = publicModels.some((m) => m.config.sharing?.enabled);
|
|
101
129
|
if (hasSharingModels) {
|
|
102
130
|
files.push({
|
|
@@ -104,31 +132,101 @@ export function registerPullCommand(program, globalOpts) {
|
|
|
104
132
|
content: generateSharedFragments(),
|
|
105
133
|
});
|
|
106
134
|
}
|
|
107
|
-
//
|
|
135
|
+
// 6b. Customer profile GraphQL documents
|
|
108
136
|
files.push({
|
|
109
137
|
path: resolve(docsDir, 'customer-profile.graphql'),
|
|
110
138
|
content: generateCustomerProfileDocuments(),
|
|
111
139
|
});
|
|
112
|
-
//
|
|
113
|
-
const
|
|
140
|
+
// 6c. Static domain documents
|
|
141
|
+
const staticDocs = generateStaticDocuments(config.domains);
|
|
142
|
+
for (const doc of staticDocs) {
|
|
143
|
+
files.push({
|
|
144
|
+
path: resolve(docsDir, doc.filename),
|
|
145
|
+
content: doc.content,
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
// 6d. Public schema (for consumer codegen)
|
|
149
|
+
if (publicSchema) {
|
|
150
|
+
files.push({
|
|
151
|
+
path: resolve(docsDir, 'public-schema.graphql'),
|
|
152
|
+
content: publicSchema,
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
// ─── Typed Operations ────────────────────────────────────
|
|
156
|
+
// 7. Operations common types
|
|
157
|
+
const typesRelPath = computeTypesRelPath(opsDir, typesDir);
|
|
114
158
|
files.push({
|
|
115
|
-
path: resolve(
|
|
116
|
-
content:
|
|
159
|
+
path: resolve(opsDir, '_common.ts'),
|
|
160
|
+
content: generateTypedOperationsCommon(),
|
|
161
|
+
});
|
|
162
|
+
// 7a. Per-model typed operations
|
|
163
|
+
for (const model of publicModels) {
|
|
164
|
+
files.push({
|
|
165
|
+
path: resolve(opsDir, `${model.key}.ts`),
|
|
166
|
+
content: generateTypedOperations(model, typesRelPath),
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
// 7b. Customer profile operations
|
|
170
|
+
if (hasCustomerProfile) {
|
|
171
|
+
files.push({
|
|
172
|
+
path: resolve(opsDir, 'customer-profile.ts'),
|
|
173
|
+
content: generateCustomerProfileOperations(typesRelPath),
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
// 7c. Operations index
|
|
177
|
+
files.push({
|
|
178
|
+
path: resolve(opsDir, 'index.ts'),
|
|
179
|
+
content: generateTypedOperationsIndex(publicModels, hasCustomerProfile),
|
|
117
180
|
});
|
|
118
|
-
//
|
|
181
|
+
// ─── React Hooks (when target includes 'react') ─────────
|
|
182
|
+
if (hooksDir) {
|
|
183
|
+
for (const model of publicModels) {
|
|
184
|
+
files.push({
|
|
185
|
+
path: resolve(hooksDir, `${model.key}.ts`),
|
|
186
|
+
content: generateReactHooks(model),
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
if (hasCustomerProfile) {
|
|
190
|
+
files.push({
|
|
191
|
+
path: resolve(hooksDir, 'customer-profile.ts'),
|
|
192
|
+
content: generateCustomerProfileHooks(),
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
files.push({
|
|
196
|
+
path: resolve(hooksDir, 'index.ts'),
|
|
197
|
+
content: generateReactHooksIndex(publicModels, hasCustomerProfile),
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
// ─── Remix Loaders (when target includes 'remix') ───────
|
|
201
|
+
if (loadersDir) {
|
|
202
|
+
for (const model of publicModels) {
|
|
203
|
+
files.push({
|
|
204
|
+
path: resolve(loadersDir, `${model.key}.ts`),
|
|
205
|
+
content: generateRemixLoaders(model),
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
if (hasCustomerProfile) {
|
|
209
|
+
files.push({
|
|
210
|
+
path: resolve(loadersDir, 'customer-profile.ts'),
|
|
211
|
+
content: generateCustomerProfileLoaders(),
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
files.push({
|
|
215
|
+
path: resolve(loadersDir, 'index.ts'),
|
|
216
|
+
content: generateRemixLoadersIndex(publicModels, hasCustomerProfile),
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
// ─── Swift (when configured) ────────────────────────────
|
|
119
220
|
if (config.output.swift) {
|
|
120
221
|
const swiftDir = resolve(cwd, config.output.swift);
|
|
121
|
-
// Shared types
|
|
122
222
|
files.push({
|
|
123
223
|
path: resolve(swiftDir, 'FieldTypes.swift'),
|
|
124
224
|
content: generateSwiftFieldTypesFile(),
|
|
125
225
|
});
|
|
126
|
-
// Model keys
|
|
127
226
|
files.push({
|
|
128
227
|
path: resolve(swiftDir, 'ModelKeys.swift'),
|
|
129
228
|
content: generateSwiftModelKeys(models),
|
|
130
229
|
});
|
|
131
|
-
// Per-model Swift files
|
|
132
230
|
for (const model of models) {
|
|
133
231
|
const swiftTypeName = toPascalCase(model.key);
|
|
134
232
|
files.push({
|
|
@@ -136,7 +234,6 @@ export function registerPullCommand(program, globalOpts) {
|
|
|
136
234
|
content: generateSwiftModelFile(model),
|
|
137
235
|
});
|
|
138
236
|
}
|
|
139
|
-
// Customer profile Swift file
|
|
140
237
|
if (hasCustomerProfile) {
|
|
141
238
|
files.push({
|
|
142
239
|
path: resolve(swiftDir, 'CustomerProfile.swift'),
|
|
@@ -144,7 +241,8 @@ export function registerPullCommand(program, globalOpts) {
|
|
|
144
241
|
});
|
|
145
242
|
}
|
|
146
243
|
}
|
|
147
|
-
//
|
|
244
|
+
// ─── Output ─────────────────────────────────────────────
|
|
245
|
+
// Dry run
|
|
148
246
|
if (config.dryRun) {
|
|
149
247
|
console.log(chalk.bold('\nDry run — files that would be generated:\n'));
|
|
150
248
|
for (const file of files) {
|
|
@@ -158,17 +256,29 @@ export function registerPullCommand(program, globalOpts) {
|
|
|
158
256
|
await writeFiles(files, config.prettier);
|
|
159
257
|
// Summary
|
|
160
258
|
const modelCount = models.length;
|
|
161
|
-
const docCount = publicModels.length;
|
|
162
|
-
const
|
|
259
|
+
const docCount = publicModels.length + staticDocs.length;
|
|
260
|
+
const opsCount = publicModels.length + (hasCustomerProfile ? 1 : 0) + 2; // +2 for _common + index
|
|
261
|
+
const hookCount = hooksDir
|
|
262
|
+
? publicModels.length + (hasCustomerProfile ? 1 : 0) + 1
|
|
263
|
+
: 0;
|
|
264
|
+
const loaderCount = loadersDir
|
|
265
|
+
? publicModels.length + (hasCustomerProfile ? 1 : 0) + 1
|
|
266
|
+
: 0;
|
|
267
|
+
const swiftCount = config.output.swift ? models.length + 2 : 0;
|
|
163
268
|
const cpSuffix = hasCustomerProfile ? ', customer profile' : '';
|
|
164
269
|
console.log(chalk.green(`\nGenerated ${files.length} file(s)`) +
|
|
165
|
-
chalk.dim(` (${modelCount}
|
|
166
|
-
console.log(chalk.dim(` Types:
|
|
167
|
-
|
|
168
|
-
|
|
270
|
+
chalk.dim(` (${modelCount} type(s), ${docCount} document(s), ${opsCount} operation(s)${cpSuffix}${hookCount > 0 ? `, ${hookCount} hook(s)` : ''}${loaderCount > 0 ? `, ${loaderCount} loader(s)` : ''}${swiftCount > 0 ? `, ${swiftCount} Swift file(s)` : ''})`));
|
|
271
|
+
console.log(chalk.dim(` Types: ${typesDir}`));
|
|
272
|
+
console.log(chalk.dim(` Documents: ${docsDir}`));
|
|
273
|
+
console.log(chalk.dim(` Operations: ${opsDir}`));
|
|
274
|
+
if (hooksDir) {
|
|
275
|
+
console.log(chalk.dim(` Hooks: ${hooksDir}`));
|
|
276
|
+
}
|
|
277
|
+
if (loadersDir) {
|
|
278
|
+
console.log(chalk.dim(` Loaders: ${loadersDir}`));
|
|
169
279
|
}
|
|
170
280
|
if (config.output.swift) {
|
|
171
|
-
console.log(chalk.dim(` Swift:
|
|
281
|
+
console.log(chalk.dim(` Swift: ${resolve(cwd, config.output.swift)}`));
|
|
172
282
|
}
|
|
173
283
|
}));
|
|
174
284
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Pull config loader — searches for foir.config.ts / .foirrc.ts and merges with CLI flags.
|
|
3
3
|
*/
|
|
4
|
+
import type { CodegenTarget, DomainConfig } from './types.js';
|
|
4
5
|
export interface PullCliFlags {
|
|
5
6
|
config?: string;
|
|
6
7
|
only?: string;
|
|
@@ -13,8 +14,13 @@ export interface ResolvedPullConfig {
|
|
|
13
14
|
output: {
|
|
14
15
|
types: string;
|
|
15
16
|
documents: string;
|
|
17
|
+
operations: string;
|
|
18
|
+
hooks?: string;
|
|
19
|
+
loaders?: string;
|
|
16
20
|
swift?: string;
|
|
17
21
|
};
|
|
22
|
+
targets: CodegenTarget[];
|
|
23
|
+
domains: Required<DomainConfig>;
|
|
18
24
|
only: string[];
|
|
19
25
|
includeInline: boolean;
|
|
20
26
|
prettier: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pull-config.d.ts","sourceRoot":"","sources":["../../src/config/pull-config.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"pull-config.d.ts","sourceRoot":"","sources":["../../src/config/pull-config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,KAAK,EAGV,aAAa,EACb,YAAY,EACb,MAAM,YAAY,CAAC;AAuDpB,MAAM,WAAW,YAAY;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE;QACN,KAAK,EAAE,MAAM,CAAC;QACd,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,EAAE,MAAM,CAAC;QACnB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,OAAO,EAAE,QAAQ,CAAC,YAAY,CAAC,CAAC;IAChC,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,aAAa,EAAE,OAAO,CAAC;IACvB,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC;CACjB;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,KAAK,EAAE,YAAY,GAClB,OAAO,CAAC,kBAAkB,CAAC,CAqE7B"}
|
|
@@ -14,6 +14,18 @@ const CONFIG_FILE_NAMES = [
|
|
|
14
14
|
];
|
|
15
15
|
const DEFAULT_TYPES_DIR = './src/generated/types';
|
|
16
16
|
const DEFAULT_DOCS_DIR = './src/generated/documents';
|
|
17
|
+
const ALL_DOMAINS = {
|
|
18
|
+
auth: true,
|
|
19
|
+
authProviders: true,
|
|
20
|
+
files: true,
|
|
21
|
+
sync: true,
|
|
22
|
+
notifications: true,
|
|
23
|
+
operations: true,
|
|
24
|
+
schedules: true,
|
|
25
|
+
sharing: true,
|
|
26
|
+
search: true,
|
|
27
|
+
analytics: true,
|
|
28
|
+
};
|
|
17
29
|
/**
|
|
18
30
|
* Resolve a config file from the given directory (or cwd).
|
|
19
31
|
*/
|
|
@@ -55,16 +67,53 @@ export async function loadPullConfig(flags) {
|
|
|
55
67
|
const types = flags.out ?? fileConfig.output?.types ?? DEFAULT_TYPES_DIR;
|
|
56
68
|
const documents = fileConfig.output?.documents ?? DEFAULT_DOCS_DIR;
|
|
57
69
|
const swift = flags.swift ?? fileConfig.output?.swift;
|
|
70
|
+
// Targets
|
|
71
|
+
const targets = fileConfig.targets ?? [];
|
|
72
|
+
// Operations dir defaults to sibling of types dir
|
|
73
|
+
const typesParent = types.replace(/\/[^/]+$/, '');
|
|
74
|
+
const operations = fileConfig.output?.operations ?? `${typesParent}/operations`;
|
|
75
|
+
// Hooks and loaders only resolve when matching target is present
|
|
76
|
+
const hooks = targets.includes('react')
|
|
77
|
+
? (fileConfig.output?.hooks ?? `${typesParent}/hooks`)
|
|
78
|
+
: undefined;
|
|
79
|
+
const loaders = targets.includes('remix')
|
|
80
|
+
? (fileConfig.output?.loaders ?? `${typesParent}/loaders`)
|
|
81
|
+
: undefined;
|
|
58
82
|
const output = {
|
|
59
83
|
types,
|
|
60
84
|
documents,
|
|
85
|
+
operations,
|
|
86
|
+
...(hooks ? { hooks } : {}),
|
|
87
|
+
...(loaders ? { loaders } : {}),
|
|
61
88
|
...(swift ? { swift } : {}),
|
|
62
89
|
};
|
|
90
|
+
// Domains: true = all, false = none, object = selective
|
|
91
|
+
let domains;
|
|
92
|
+
if (fileConfig.domains === false) {
|
|
93
|
+
domains = {
|
|
94
|
+
auth: false,
|
|
95
|
+
authProviders: false,
|
|
96
|
+
files: false,
|
|
97
|
+
sync: false,
|
|
98
|
+
notifications: false,
|
|
99
|
+
operations: false,
|
|
100
|
+
schedules: false,
|
|
101
|
+
sharing: false,
|
|
102
|
+
search: false,
|
|
103
|
+
analytics: false,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
else if (typeof fileConfig.domains === 'object') {
|
|
107
|
+
domains = { ...ALL_DOMAINS, ...fileConfig.domains };
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
domains = { ...ALL_DOMAINS };
|
|
111
|
+
}
|
|
63
112
|
const only = flags.only
|
|
64
113
|
? flags.only.split(',').map((s) => s.trim())
|
|
65
114
|
: (fileConfig.only ?? []);
|
|
66
115
|
const includeInline = fileConfig.includeInline ?? true;
|
|
67
116
|
const prettier = flags.noPrettier ? false : (fileConfig.prettier ?? true);
|
|
68
117
|
const dryRun = flags.dryRun ?? false;
|
|
69
|
-
return { output, only, includeInline, prettier, dryRun };
|
|
118
|
+
return { output, targets, domains, only, includeInline, prettier, dryRun };
|
|
70
119
|
}
|
package/dist/config/types.d.ts
CHANGED
|
@@ -1,15 +1,38 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Configuration types for foir-cli
|
|
3
3
|
*/
|
|
4
|
+
export type CodegenTarget = 'react' | 'remix';
|
|
5
|
+
export interface DomainConfig {
|
|
6
|
+
auth?: boolean;
|
|
7
|
+
authProviders?: boolean;
|
|
8
|
+
files?: boolean;
|
|
9
|
+
sync?: boolean;
|
|
10
|
+
notifications?: boolean;
|
|
11
|
+
operations?: boolean;
|
|
12
|
+
schedules?: boolean;
|
|
13
|
+
sharing?: boolean;
|
|
14
|
+
search?: boolean;
|
|
15
|
+
analytics?: boolean;
|
|
16
|
+
}
|
|
4
17
|
export interface FoirPullConfig {
|
|
5
18
|
output?: {
|
|
6
19
|
/** Directory for generated TypeScript types (default: './src/generated/types') */
|
|
7
20
|
types?: string;
|
|
8
21
|
/** Directory for generated GraphQL documents (default: './src/generated/documents') */
|
|
9
22
|
documents?: string;
|
|
23
|
+
/** Directory for generated typed operation modules (default: sibling of types) */
|
|
24
|
+
operations?: string;
|
|
25
|
+
/** Directory for generated React hooks (requires 'react' target) */
|
|
26
|
+
hooks?: string;
|
|
27
|
+
/** Directory for generated Remix loaders (requires 'remix' target) */
|
|
28
|
+
loaders?: string;
|
|
10
29
|
/** Directory for generated Swift files (e.g., './generated/swift') */
|
|
11
30
|
swift?: string;
|
|
12
31
|
};
|
|
32
|
+
/** Code generation targets — 'react' for Apollo hooks, 'remix' for typed loaders */
|
|
33
|
+
targets?: CodegenTarget[];
|
|
34
|
+
/** Enable static domain document generation (default: all enabled) */
|
|
35
|
+
domains?: boolean | DomainConfig;
|
|
13
36
|
/** Filter to specific model keys */
|
|
14
37
|
only?: string[];
|
|
15
38
|
/** Include inline-only models for type resolution (default: true) */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/config/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE;QACP,kFAAkF;QAClF,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,uFAAuF;QACvF,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,sEAAsE;QACtE,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,oCAAoC;IACpC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,qEAAqE;IACrE,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,kDAAkD;IAClD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,EAAE,cAAc,CAAC;CACvB;AAED;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,UAAU,GAAG,UAAU,CAE3D"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/config/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,OAAO,CAAC;AAE9C,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE;QACP,kFAAkF;QAClF,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,uFAAuF;QACvF,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,kFAAkF;QAClF,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,oEAAoE;QACpE,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,sEAAsE;QACtE,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,sEAAsE;QACtE,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,oFAAoF;IACpF,OAAO,CAAC,EAAE,aAAa,EAAE,CAAC;IAC1B,sEAAsE;IACtE,OAAO,CAAC,EAAE,OAAO,GAAG,YAAY,CAAC;IACjC,oCAAoC;IACpC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,qEAAqE;IACrE,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,kDAAkD;IAClD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,EAAE,cAAc,CAAC;CACvB;AAED;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,UAAU,GAAG,UAAU,CAE3D"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export type PackageManager = 'pnpm' | 'yarn' | 'npm';
|
|
2
|
+
export interface PackageManagerInfo {
|
|
3
|
+
name: PackageManager;
|
|
4
|
+
installCommand: string;
|
|
5
|
+
execCommand: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Detects the package manager by checking for lock files in the
|
|
9
|
+
* current working directory and parent directories.
|
|
10
|
+
*/
|
|
11
|
+
export declare function detectPackageManager(): PackageManagerInfo;
|
|
12
|
+
//# sourceMappingURL=package-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"package-manager.d.ts","sourceRoot":"","sources":["../../src/scaffold/package-manager.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC;AAErD,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,cAAc,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,IAAI,kBAAkB,CA0BzD"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import * as fs from 'node:fs';
|
|
2
|
+
import * as path from 'node:path';
|
|
3
|
+
/**
|
|
4
|
+
* Detects the package manager by checking for lock files in the
|
|
5
|
+
* current working directory and parent directories.
|
|
6
|
+
*/
|
|
7
|
+
export function detectPackageManager() {
|
|
8
|
+
const lockFiles = [
|
|
9
|
+
{ file: 'pnpm-lock.yaml', manager: 'pnpm' },
|
|
10
|
+
{ file: 'yarn.lock', manager: 'yarn' },
|
|
11
|
+
{ file: 'package-lock.json', manager: 'npm' },
|
|
12
|
+
];
|
|
13
|
+
let dir = process.cwd();
|
|
14
|
+
// Walk up the directory tree looking for lock files
|
|
15
|
+
while (true) {
|
|
16
|
+
for (const { file, manager } of lockFiles) {
|
|
17
|
+
if (fs.existsSync(path.join(dir, file))) {
|
|
18
|
+
return getManagerInfo(manager);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
const parentDir = path.dirname(dir);
|
|
22
|
+
if (parentDir === dir) {
|
|
23
|
+
break;
|
|
24
|
+
}
|
|
25
|
+
dir = parentDir;
|
|
26
|
+
}
|
|
27
|
+
// Default to npm if no lock file found
|
|
28
|
+
return getManagerInfo('npm');
|
|
29
|
+
}
|
|
30
|
+
function getManagerInfo(manager) {
|
|
31
|
+
switch (manager) {
|
|
32
|
+
case 'pnpm':
|
|
33
|
+
return {
|
|
34
|
+
name: 'pnpm',
|
|
35
|
+
installCommand: 'pnpm install',
|
|
36
|
+
execCommand: 'pnpm dlx',
|
|
37
|
+
};
|
|
38
|
+
case 'yarn':
|
|
39
|
+
return {
|
|
40
|
+
name: 'yarn',
|
|
41
|
+
installCommand: 'yarn install',
|
|
42
|
+
execCommand: 'yarn dlx',
|
|
43
|
+
};
|
|
44
|
+
case 'npm':
|
|
45
|
+
return {
|
|
46
|
+
name: 'npm',
|
|
47
|
+
installCommand: 'npm install',
|
|
48
|
+
execCommand: 'npx',
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scaffold.d.ts","sourceRoot":"","sources":["../../src/scaffold/scaffold.ts"],"names":[],"mappings":"AAIA,KAAK,aAAa,GAAG,eAAe,GAAG,UAAU,GAAG,QAAQ,CAAC;AAE7D,wBAAsB,QAAQ,CAC5B,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,aAAa,EAC5B,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC,CA0Cf"}
|