@eide/foir-cli 0.1.35 → 0.1.36
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 +7467 -42
- package/dist/config/types.d.ts +7 -6
- package/dist/config/types.js +6 -14
- package/dist/generated-CPsQ9jfu.d.ts +195 -0
- package/dist/lib/extension-helpers.d.ts +10 -7
- package/dist/lib/extension-helpers.js +15 -85
- package/dist/lib/hook-helpers.d.ts +9 -6
- package/dist/lib/hook-helpers.js +12 -105
- package/dist/lib/seed-helpers.d.ts +10 -8
- package/dist/lib/seed-helpers.js +18 -124
- package/package.json +9 -8
- package/dist/auth/credentials.d.ts +0 -31
- package/dist/auth/credentials.d.ts.map +0 -1
- package/dist/auth/credentials.js +0 -139
- package/dist/cli.d.ts +0 -3
- package/dist/cli.d.ts.map +0 -1
- package/dist/codegen/fetch-customer-profile-schema.d.ts +0 -12
- package/dist/codegen/fetch-customer-profile-schema.d.ts.map +0 -1
- package/dist/codegen/fetch-customer-profile-schema.js +0 -21
- package/dist/codegen/fetch-models.d.ts +0 -58
- package/dist/codegen/fetch-models.d.ts.map +0 -1
- package/dist/codegen/fetch-models.js +0 -96
- package/dist/codegen/field-mapping.d.ts +0 -34
- package/dist/codegen/field-mapping.d.ts.map +0 -1
- package/dist/codegen/field-mapping.js +0 -250
- package/dist/codegen/generators/config.d.ts +0 -5
- package/dist/codegen/generators/config.d.ts.map +0 -1
- package/dist/codegen/generators/config.js +0 -82
- package/dist/codegen/generators/customer-profile-documents.d.ts +0 -5
- package/dist/codegen/generators/customer-profile-documents.d.ts.map +0 -1
- package/dist/codegen/generators/customer-profile-documents.js +0 -42
- package/dist/codegen/generators/customer-profile-hooks.d.ts +0 -5
- package/dist/codegen/generators/customer-profile-hooks.d.ts.map +0 -1
- package/dist/codegen/generators/customer-profile-hooks.js +0 -78
- package/dist/codegen/generators/customer-profile-loaders.d.ts +0 -5
- package/dist/codegen/generators/customer-profile-loaders.d.ts.map +0 -1
- package/dist/codegen/generators/customer-profile-loaders.js +0 -67
- package/dist/codegen/generators/customer-profile-operations.d.ts +0 -5
- package/dist/codegen/generators/customer-profile-operations.d.ts.map +0 -1
- package/dist/codegen/generators/customer-profile-operations.js +0 -126
- package/dist/codegen/generators/customer-profile-types.d.ts +0 -6
- package/dist/codegen/generators/customer-profile-types.d.ts.map +0 -1
- package/dist/codegen/generators/customer-profile-types.js +0 -45
- package/dist/codegen/generators/documents.d.ts +0 -12
- package/dist/codegen/generators/documents.d.ts.map +0 -1
- package/dist/codegen/generators/documents.js +0 -178
- package/dist/codegen/generators/field-types.d.ts +0 -5
- package/dist/codegen/generators/field-types.d.ts.map +0 -1
- package/dist/codegen/generators/field-types.js +0 -346
- package/dist/codegen/generators/model-index.d.ts +0 -6
- package/dist/codegen/generators/model-index.d.ts.map +0 -1
- package/dist/codegen/generators/model-index.js +0 -26
- package/dist/codegen/generators/model-types.d.ts +0 -12
- package/dist/codegen/generators/model-types.d.ts.map +0 -1
- package/dist/codegen/generators/model-types.js +0 -177
- package/dist/codegen/generators/public-schema-content.d.ts +0 -14
- package/dist/codegen/generators/public-schema-content.d.ts.map +0 -1
- package/dist/codegen/generators/public-schema-content.js +0 -22
- package/dist/codegen/generators/react-hooks-index.d.ts +0 -6
- package/dist/codegen/generators/react-hooks-index.d.ts.map +0 -1
- package/dist/codegen/generators/react-hooks-index.js +0 -20
- package/dist/codegen/generators/react-hooks.d.ts +0 -7
- package/dist/codegen/generators/react-hooks.d.ts.map +0 -1
- package/dist/codegen/generators/react-hooks.js +0 -139
- package/dist/codegen/generators/remix-loaders-index.d.ts +0 -6
- package/dist/codegen/generators/remix-loaders-index.d.ts.map +0 -1
- package/dist/codegen/generators/remix-loaders-index.js +0 -20
- package/dist/codegen/generators/remix-loaders.d.ts +0 -7
- package/dist/codegen/generators/remix-loaders.d.ts.map +0 -1
- package/dist/codegen/generators/remix-loaders.js +0 -107
- package/dist/codegen/generators/static-documents.d.ts +0 -14
- package/dist/codegen/generators/static-documents.d.ts.map +0 -1
- package/dist/codegen/generators/static-documents.js +0 -771
- package/dist/codegen/generators/swift-customer-profile.d.ts +0 -9
- package/dist/codegen/generators/swift-customer-profile.d.ts.map +0 -1
- package/dist/codegen/generators/swift-customer-profile.js +0 -152
- package/dist/codegen/generators/swift-field-types.d.ts +0 -5
- package/dist/codegen/generators/swift-field-types.d.ts.map +0 -1
- package/dist/codegen/generators/swift-field-types.js +0 -151
- package/dist/codegen/generators/swift-model-keys.d.ts +0 -6
- package/dist/codegen/generators/swift-model-keys.d.ts.map +0 -1
- package/dist/codegen/generators/swift-model-keys.js +0 -25
- package/dist/codegen/generators/swift-types.d.ts +0 -13
- package/dist/codegen/generators/swift-types.d.ts.map +0 -1
- package/dist/codegen/generators/swift-types.js +0 -188
- package/dist/codegen/generators/typed-operations-common.d.ts +0 -6
- package/dist/codegen/generators/typed-operations-common.d.ts.map +0 -1
- package/dist/codegen/generators/typed-operations-common.js +0 -84
- package/dist/codegen/generators/typed-operations-index.d.ts +0 -6
- package/dist/codegen/generators/typed-operations-index.d.ts.map +0 -1
- package/dist/codegen/generators/typed-operations-index.js +0 -22
- package/dist/codegen/generators/typed-operations.d.ts +0 -11
- package/dist/codegen/generators/typed-operations.d.ts.map +0 -1
- package/dist/codegen/generators/typed-operations.js +0 -263
- package/dist/codegen/swift-field-mapping.d.ts +0 -30
- package/dist/codegen/swift-field-mapping.d.ts.map +0 -1
- package/dist/codegen/swift-field-mapping.js +0 -150
- package/dist/codegen/write-files.d.ts +0 -15
- package/dist/codegen/write-files.d.ts.map +0 -1
- package/dist/codegen/write-files.js +0 -36
- package/dist/commands/api-keys.d.ts +0 -4
- package/dist/commands/api-keys.d.ts.map +0 -1
- package/dist/commands/api-keys.js +0 -129
- package/dist/commands/auth-config.d.ts +0 -4
- package/dist/commands/auth-config.d.ts.map +0 -1
- package/dist/commands/auth-config.js +0 -38
- package/dist/commands/auth-providers.d.ts +0 -4
- package/dist/commands/auth-providers.d.ts.map +0 -1
- package/dist/commands/auth-providers.js +0 -207
- package/dist/commands/context.d.ts +0 -4
- package/dist/commands/context.d.ts.map +0 -1
- package/dist/commands/context.js +0 -91
- package/dist/commands/create-extension.d.ts +0 -4
- package/dist/commands/create-extension.d.ts.map +0 -1
- package/dist/commands/create-extension.js +0 -60
- package/dist/commands/customer-profiles.d.ts +0 -4
- package/dist/commands/customer-profiles.d.ts.map +0 -1
- package/dist/commands/customer-profiles.js +0 -99
- package/dist/commands/customers.d.ts +0 -4
- package/dist/commands/customers.d.ts.map +0 -1
- package/dist/commands/customers.js +0 -126
- package/dist/commands/embeddings.d.ts +0 -4
- package/dist/commands/embeddings.d.ts.map +0 -1
- package/dist/commands/embeddings.js +0 -145
- package/dist/commands/experiments.d.ts +0 -4
- package/dist/commands/experiments.d.ts.map +0 -1
- package/dist/commands/experiments.js +0 -196
- package/dist/commands/extensions.d.ts +0 -4
- package/dist/commands/extensions.d.ts.map +0 -1
- package/dist/commands/extensions.js +0 -210
- package/dist/commands/files.d.ts +0 -4
- package/dist/commands/files.d.ts.map +0 -1
- package/dist/commands/files.js +0 -143
- package/dist/commands/hooks.d.ts +0 -4
- package/dist/commands/hooks.d.ts.map +0 -1
- package/dist/commands/hooks.js +0 -228
- package/dist/commands/locales.d.ts +0 -4
- package/dist/commands/locales.d.ts.map +0 -1
- package/dist/commands/locales.js +0 -140
- package/dist/commands/login.d.ts +0 -4
- package/dist/commands/login.d.ts.map +0 -1
- package/dist/commands/login.js +0 -124
- package/dist/commands/logout.d.ts +0 -4
- package/dist/commands/logout.d.ts.map +0 -1
- package/dist/commands/logout.js +0 -16
- package/dist/commands/media.d.ts +0 -4
- package/dist/commands/media.d.ts.map +0 -1
- package/dist/commands/media.js +0 -44
- package/dist/commands/models.d.ts +0 -4
- package/dist/commands/models.d.ts.map +0 -1
- package/dist/commands/models.js +0 -153
- package/dist/commands/notes.d.ts +0 -4
- package/dist/commands/notes.d.ts.map +0 -1
- package/dist/commands/notes.js +0 -132
- package/dist/commands/notifications.d.ts +0 -4
- package/dist/commands/notifications.d.ts.map +0 -1
- package/dist/commands/notifications.js +0 -73
- package/dist/commands/operations.d.ts +0 -4
- package/dist/commands/operations.d.ts.map +0 -1
- package/dist/commands/operations.js +0 -341
- package/dist/commands/playground.d.ts +0 -4
- package/dist/commands/playground.d.ts.map +0 -1
- package/dist/commands/playground.js +0 -270
- package/dist/commands/pull.d.ts +0 -4
- package/dist/commands/pull.d.ts.map +0 -1
- package/dist/commands/pull.js +0 -300
- package/dist/commands/records.d.ts +0 -4
- package/dist/commands/records.d.ts.map +0 -1
- package/dist/commands/records.js +0 -314
- package/dist/commands/register-commands.d.ts +0 -7
- package/dist/commands/register-commands.d.ts.map +0 -1
- package/dist/commands/register-commands.js +0 -259
- package/dist/commands/schedules.d.ts +0 -4
- package/dist/commands/schedules.d.ts.map +0 -1
- package/dist/commands/schedules.js +0 -155
- package/dist/commands/search.d.ts +0 -4
- package/dist/commands/search.d.ts.map +0 -1
- package/dist/commands/search.js +0 -60
- package/dist/commands/segments.d.ts +0 -4
- package/dist/commands/segments.d.ts.map +0 -1
- package/dist/commands/segments.js +0 -155
- package/dist/commands/select-project.d.ts +0 -4
- package/dist/commands/select-project.d.ts.map +0 -1
- package/dist/commands/select-project.js +0 -144
- package/dist/commands/settings.d.ts +0 -4
- package/dist/commands/settings.d.ts.map +0 -1
- package/dist/commands/settings.js +0 -115
- package/dist/commands/variant-catalog.d.ts +0 -4
- package/dist/commands/variant-catalog.d.ts.map +0 -1
- package/dist/commands/variant-catalog.js +0 -118
- package/dist/commands/whoami.d.ts +0 -4
- package/dist/commands/whoami.d.ts.map +0 -1
- package/dist/commands/whoami.js +0 -51
- package/dist/config/pull-config.d.ts +0 -33
- package/dist/config/pull-config.d.ts.map +0 -1
- package/dist/config/pull-config.js +0 -119
- package/dist/config/types.d.ts.map +0 -1
- package/dist/graphql/generated.d.ts +0 -6074
- package/dist/graphql/generated.d.ts.map +0 -1
- package/dist/graphql/generated.js +0 -355
- package/dist/lib/client.d.ts +0 -18
- package/dist/lib/client.d.ts.map +0 -1
- package/dist/lib/client.js +0 -64
- package/dist/lib/config-loader.d.ts +0 -28
- package/dist/lib/config-loader.d.ts.map +0 -1
- package/dist/lib/config-loader.js +0 -49
- package/dist/lib/config.d.ts +0 -12
- package/dist/lib/config.d.ts.map +0 -1
- package/dist/lib/config.js +0 -8
- package/dist/lib/errors.d.ts +0 -6
- package/dist/lib/errors.d.ts.map +0 -1
- package/dist/lib/errors.js +0 -76
- package/dist/lib/extension-helpers.d.ts.map +0 -1
- package/dist/lib/hook-helpers.d.ts.map +0 -1
- package/dist/lib/input.d.ts +0 -38
- package/dist/lib/input.d.ts.map +0 -1
- package/dist/lib/input.js +0 -108
- package/dist/lib/output.d.ts +0 -31
- package/dist/lib/output.d.ts.map +0 -1
- package/dist/lib/output.js +0 -107
- package/dist/lib/seed-helpers.d.ts.map +0 -1
- package/dist/scaffold/package-manager.d.ts +0 -12
- package/dist/scaffold/package-manager.d.ts.map +0 -1
- package/dist/scaffold/package-manager.js +0 -51
- package/dist/scaffold/scaffold.d.ts +0 -4
- package/dist/scaffold/scaffold.d.ts.map +0 -1
- package/dist/scaffold/scaffold.js +0 -462
|
@@ -1,270 +0,0 @@
|
|
|
1
|
-
import chalk from 'chalk';
|
|
2
|
-
import * as readline from 'readline';
|
|
3
|
-
import { homedir } from 'os';
|
|
4
|
-
import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs';
|
|
5
|
-
import { join } from 'path';
|
|
6
|
-
import { createClient } from '../lib/client.js';
|
|
7
|
-
import { getProjectContext } from '../auth/credentials.js';
|
|
8
|
-
import { ListModelsDocument } from '../graphql/generated.js';
|
|
9
|
-
const HISTORY_FILE = join(homedir(), '.foir', 'repl-history');
|
|
10
|
-
const MAX_HISTORY = 500;
|
|
11
|
-
function loadHistory() {
|
|
12
|
-
try {
|
|
13
|
-
if (existsSync(HISTORY_FILE)) {
|
|
14
|
-
return readFileSync(HISTORY_FILE, 'utf-8')
|
|
15
|
-
.split('\n')
|
|
16
|
-
.filter(Boolean)
|
|
17
|
-
.slice(-MAX_HISTORY);
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
catch {
|
|
21
|
-
// ignore
|
|
22
|
-
}
|
|
23
|
-
return [];
|
|
24
|
-
}
|
|
25
|
-
function saveHistory(lines) {
|
|
26
|
-
try {
|
|
27
|
-
const dir = join(homedir(), '.foir');
|
|
28
|
-
if (!existsSync(dir))
|
|
29
|
-
mkdirSync(dir, { recursive: true });
|
|
30
|
-
writeFileSync(HISTORY_FILE, lines.slice(-MAX_HISTORY).join('\n') + '\n');
|
|
31
|
-
}
|
|
32
|
-
catch {
|
|
33
|
-
// ignore
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
export function registerPlaygroundCommand(program, getGlobalOpts) {
|
|
37
|
-
program
|
|
38
|
-
.command('playground')
|
|
39
|
-
.alias('repl')
|
|
40
|
-
.description('Interactive REPL with tab completion')
|
|
41
|
-
.action(async () => {
|
|
42
|
-
const opts = getGlobalOpts();
|
|
43
|
-
// Validate auth and create client
|
|
44
|
-
let client;
|
|
45
|
-
try {
|
|
46
|
-
client = await createClient(opts);
|
|
47
|
-
}
|
|
48
|
-
catch (err) {
|
|
49
|
-
throw new Error('Authentication required. Run `foir login` first.');
|
|
50
|
-
}
|
|
51
|
-
// Pre-fetch model keys for tab completion (don't block startup)
|
|
52
|
-
let modelKeys = [];
|
|
53
|
-
client
|
|
54
|
-
.request(ListModelsDocument, { limit: 200 })
|
|
55
|
-
.then((data) => {
|
|
56
|
-
modelKeys = data.models.items.map((m) => m.key);
|
|
57
|
-
})
|
|
58
|
-
.catch(() => {
|
|
59
|
-
/* ignore — completion just won't have model keys */
|
|
60
|
-
});
|
|
61
|
-
// Get project context for prompt
|
|
62
|
-
let projectName = 'no project';
|
|
63
|
-
try {
|
|
64
|
-
const ctx = await getProjectContext();
|
|
65
|
-
if (ctx?.name)
|
|
66
|
-
projectName = ctx.name;
|
|
67
|
-
}
|
|
68
|
-
catch {
|
|
69
|
-
// no project context
|
|
70
|
-
}
|
|
71
|
-
// Collect command names for completion
|
|
72
|
-
const commandNames = program.commands.map((c) => c.name());
|
|
73
|
-
const commandMap = new Map();
|
|
74
|
-
for (const cmd of program.commands) {
|
|
75
|
-
commandMap.set(cmd.name(), cmd);
|
|
76
|
-
for (const alias of cmd.aliases()) {
|
|
77
|
-
commandMap.set(alias, cmd);
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
// Build completer
|
|
81
|
-
const metaCommands = [
|
|
82
|
-
'.help',
|
|
83
|
-
'.clear',
|
|
84
|
-
'.exit',
|
|
85
|
-
'.commands',
|
|
86
|
-
'.context',
|
|
87
|
-
'.models',
|
|
88
|
-
];
|
|
89
|
-
function completer(line) {
|
|
90
|
-
const trimmed = line.trim();
|
|
91
|
-
const parts = trimmed.split(/\s+/);
|
|
92
|
-
// Meta commands
|
|
93
|
-
if (parts.length === 1 && trimmed.startsWith('.')) {
|
|
94
|
-
const hits = metaCommands.filter((c) => c.startsWith(trimmed));
|
|
95
|
-
return [hits.length ? hits : metaCommands, trimmed];
|
|
96
|
-
}
|
|
97
|
-
// First word: command names
|
|
98
|
-
if (parts.length <= 1) {
|
|
99
|
-
const hits = commandNames.filter((c) => c.startsWith(trimmed));
|
|
100
|
-
return [hits.length ? hits : commandNames, trimmed];
|
|
101
|
-
}
|
|
102
|
-
// Second word: subcommands
|
|
103
|
-
const firstPart = parts[0] ?? '';
|
|
104
|
-
const cmd = commandMap.get(firstPart);
|
|
105
|
-
if (cmd && parts.length === 2) {
|
|
106
|
-
const subNames = cmd.commands.map((c) => c.name());
|
|
107
|
-
const partial = parts[1] ?? '';
|
|
108
|
-
const hits = subNames.filter((s) => s.startsWith(partial));
|
|
109
|
-
return [hits.length ? hits : subNames, partial];
|
|
110
|
-
}
|
|
111
|
-
// Level 3: model keys for records/search commands
|
|
112
|
-
const cmdName = cmd?.name();
|
|
113
|
-
if ((cmdName === 'records' || cmdName === 'search') &&
|
|
114
|
-
parts.length === 3 &&
|
|
115
|
-
modelKeys.length > 0) {
|
|
116
|
-
const partial = parts[2] ?? '';
|
|
117
|
-
const hits = modelKeys.filter((k) => k.startsWith(partial));
|
|
118
|
-
return [hits.length ? hits : modelKeys, partial];
|
|
119
|
-
}
|
|
120
|
-
// Flags
|
|
121
|
-
if (cmd) {
|
|
122
|
-
const lastPart = parts[parts.length - 1] ?? '';
|
|
123
|
-
if (lastPart.startsWith('-')) {
|
|
124
|
-
const flags = cmd.options.map((o) => o.long).filter((f) => Boolean(f));
|
|
125
|
-
const hits = flags.filter((f) => f.startsWith(lastPart));
|
|
126
|
-
return [hits.length ? hits : [], lastPart];
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
return [[], trimmed];
|
|
130
|
-
}
|
|
131
|
-
// Load history
|
|
132
|
-
const history = loadHistory();
|
|
133
|
-
const rl = readline.createInterface({
|
|
134
|
-
input: process.stdin,
|
|
135
|
-
output: process.stdout,
|
|
136
|
-
prompt: chalk.cyan(`foir (${projectName})> `),
|
|
137
|
-
completer,
|
|
138
|
-
history,
|
|
139
|
-
historySize: MAX_HISTORY,
|
|
140
|
-
});
|
|
141
|
-
console.log(chalk.bold('\nFoir Interactive Playground'));
|
|
142
|
-
console.log(chalk.dim('Type commands without the "foir" prefix. Use Tab for completion.'));
|
|
143
|
-
console.log(chalk.dim('Type .help for available meta-commands.\n'));
|
|
144
|
-
rl.prompt();
|
|
145
|
-
// Prevent Commander from calling process.exit()
|
|
146
|
-
program.exitOverride();
|
|
147
|
-
rl.on('line', async (line) => {
|
|
148
|
-
const input = line.trim();
|
|
149
|
-
if (!input) {
|
|
150
|
-
rl.prompt();
|
|
151
|
-
return;
|
|
152
|
-
}
|
|
153
|
-
// Meta commands
|
|
154
|
-
if (input === '.help') {
|
|
155
|
-
console.log(chalk.bold('\nMeta-commands:'));
|
|
156
|
-
console.log(' .help Show this help');
|
|
157
|
-
console.log(' .clear Clear terminal');
|
|
158
|
-
console.log(' .exit Exit playground');
|
|
159
|
-
console.log(' .commands List available commands');
|
|
160
|
-
console.log(' .context Show current auth/project context');
|
|
161
|
-
console.log(' .models Refresh and list model keys');
|
|
162
|
-
console.log(chalk.dim('\nRun any foir command without the "foir" prefix.'));
|
|
163
|
-
console.log(chalk.dim('Example: records list page\n'));
|
|
164
|
-
rl.prompt();
|
|
165
|
-
return;
|
|
166
|
-
}
|
|
167
|
-
if (input === '.clear') {
|
|
168
|
-
console.clear();
|
|
169
|
-
rl.prompt();
|
|
170
|
-
return;
|
|
171
|
-
}
|
|
172
|
-
if (input === '.exit' || input === 'exit' || input === 'quit') {
|
|
173
|
-
saveHistory(rl.history || []);
|
|
174
|
-
console.log(chalk.dim('Goodbye!'));
|
|
175
|
-
rl.close();
|
|
176
|
-
return;
|
|
177
|
-
}
|
|
178
|
-
if (input === '.commands') {
|
|
179
|
-
console.log(chalk.bold('\nAvailable commands:'));
|
|
180
|
-
for (const cmd of program.commands) {
|
|
181
|
-
if (cmd.name() === 'playground')
|
|
182
|
-
continue;
|
|
183
|
-
const desc = cmd.description() || '';
|
|
184
|
-
console.log(` ${chalk.green(cmd.name().padEnd(24))} ${chalk.dim(desc)}`);
|
|
185
|
-
}
|
|
186
|
-
console.log('');
|
|
187
|
-
rl.prompt();
|
|
188
|
-
return;
|
|
189
|
-
}
|
|
190
|
-
if (input === '.context') {
|
|
191
|
-
try {
|
|
192
|
-
const ctx = await getProjectContext();
|
|
193
|
-
console.log(chalk.bold('\nCurrent context:'));
|
|
194
|
-
if (ctx) {
|
|
195
|
-
console.log(` Project: ${chalk.green(ctx.name || 'unnamed')}`);
|
|
196
|
-
console.log(` ID: ${chalk.dim(ctx.id || 'n/a')}`);
|
|
197
|
-
console.log(` Tenant: ${chalk.dim(ctx.tenantId || 'n/a')}`);
|
|
198
|
-
}
|
|
199
|
-
else {
|
|
200
|
-
console.log(chalk.yellow(' No project selected. Run: select-project'));
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
catch {
|
|
204
|
-
console.log(chalk.yellow(' No project context available.'));
|
|
205
|
-
}
|
|
206
|
-
console.log('');
|
|
207
|
-
rl.prompt();
|
|
208
|
-
return;
|
|
209
|
-
}
|
|
210
|
-
if (input === '.models') {
|
|
211
|
-
try {
|
|
212
|
-
const data = await client.request(ListModelsDocument, {
|
|
213
|
-
limit: 200,
|
|
214
|
-
});
|
|
215
|
-
modelKeys = data.models.items.map((m) => m.key);
|
|
216
|
-
console.log(chalk.bold('\nModel keys:'));
|
|
217
|
-
for (const key of modelKeys) {
|
|
218
|
-
console.log(` ${chalk.green(key)}`);
|
|
219
|
-
}
|
|
220
|
-
if (modelKeys.length === 0) {
|
|
221
|
-
console.log(chalk.yellow(' No models found.'));
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
catch {
|
|
225
|
-
console.log(chalk.yellow(' Failed to fetch models.'));
|
|
226
|
-
}
|
|
227
|
-
console.log('');
|
|
228
|
-
rl.prompt();
|
|
229
|
-
return;
|
|
230
|
-
}
|
|
231
|
-
// Regular command - parse and execute via Commander
|
|
232
|
-
const args = input.match(/(?:[^\s"']+|"[^"]*"|'[^']*')/g) || [];
|
|
233
|
-
// Strip quotes from arguments
|
|
234
|
-
const cleanArgs = args.map((a) => a.replace(/^["']|["']$/g, ''));
|
|
235
|
-
try {
|
|
236
|
-
await program.parseAsync(['node', 'foir', ...cleanArgs], {
|
|
237
|
-
from: 'user',
|
|
238
|
-
});
|
|
239
|
-
}
|
|
240
|
-
catch (err) {
|
|
241
|
-
// CommanderError is thrown by exitOverride instead of process.exit
|
|
242
|
-
if (err.code === 'commander.helpDisplayed' ||
|
|
243
|
-
err.code === 'commander.version') {
|
|
244
|
-
// Help/version output already printed
|
|
245
|
-
}
|
|
246
|
-
else if (err.code === 'commander.unknownCommand') {
|
|
247
|
-
console.error(chalk.red(`Unknown command: ${cleanArgs[0]}`));
|
|
248
|
-
console.log(chalk.dim('Type .commands to see available commands.'));
|
|
249
|
-
}
|
|
250
|
-
else if (err.exitCode !== undefined) {
|
|
251
|
-
// Commander error with exit code - already printed message
|
|
252
|
-
}
|
|
253
|
-
else {
|
|
254
|
-
// Application error
|
|
255
|
-
console.error(chalk.red(err.message || String(err)));
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
console.log(''); // spacing
|
|
259
|
-
rl.prompt();
|
|
260
|
-
});
|
|
261
|
-
rl.on('close', () => {
|
|
262
|
-
saveHistory(rl.history || []);
|
|
263
|
-
});
|
|
264
|
-
// Handle SIGINT gracefully
|
|
265
|
-
rl.on('SIGINT', () => {
|
|
266
|
-
console.log(chalk.dim('\n(Use .exit or Ctrl+D to quit)'));
|
|
267
|
-
rl.prompt();
|
|
268
|
-
});
|
|
269
|
-
});
|
|
270
|
-
}
|
package/dist/commands/pull.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"pull.d.ts","sourceRoot":"","sources":["../../src/commands/pull.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAyCtD,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE,MAAM,aAAa,GAC9B,IAAI,CAyUN"}
|
package/dist/commands/pull.js
DELETED
|
@@ -1,300 +0,0 @@
|
|
|
1
|
-
import { resolve } from 'path';
|
|
2
|
-
import chalk from 'chalk';
|
|
3
|
-
import { withErrorHandler } from '../lib/errors.js';
|
|
4
|
-
import { createClient } from '../lib/client.js';
|
|
5
|
-
import { loadPullConfig } from '../config/pull-config.js';
|
|
6
|
-
import { fetchModelsForCodegen, filterModels, } from '../codegen/fetch-models.js';
|
|
7
|
-
import { fetchCustomerProfileSchema } from '../codegen/fetch-customer-profile-schema.js';
|
|
8
|
-
import { toPascalCase } from '../codegen/field-mapping.js';
|
|
9
|
-
import { generateFieldTypesFile } from '../codegen/generators/field-types.js';
|
|
10
|
-
import { generateConfigFile } from '../codegen/generators/config.js';
|
|
11
|
-
import { generateModelTypes } from '../codegen/generators/model-types.js';
|
|
12
|
-
import { generateModelIndex } from '../codegen/generators/model-index.js';
|
|
13
|
-
import { generateModelDocuments, generateSharedFragments, } from '../codegen/generators/documents.js';
|
|
14
|
-
import { generateSwiftModelFile } from '../codegen/generators/swift-types.js';
|
|
15
|
-
import { generateSwiftFieldTypesFile } from '../codegen/generators/swift-field-types.js';
|
|
16
|
-
import { generateSwiftModelKeys } from '../codegen/generators/swift-model-keys.js';
|
|
17
|
-
import { generateCustomerProfileTypes } from '../codegen/generators/customer-profile-types.js';
|
|
18
|
-
import { generateSwiftCustomerProfileFile } from '../codegen/generators/swift-customer-profile.js';
|
|
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';
|
|
32
|
-
import { writeFiles } from '../codegen/write-files.js';
|
|
33
|
-
export function registerPullCommand(program, globalOpts) {
|
|
34
|
-
program
|
|
35
|
-
.command('pull')
|
|
36
|
-
.description('Generate TypeScript types, GraphQL documents, and Swift types from platform models')
|
|
37
|
-
.option('--config <path>', 'Path to config file')
|
|
38
|
-
.option('--only <models>', 'Comma-separated model keys to generate')
|
|
39
|
-
.option('--no-prettier', 'Skip Prettier formatting')
|
|
40
|
-
.option('--dry-run', 'Show what would be generated without writing')
|
|
41
|
-
.option('--out <dir>', 'Override output directory for types')
|
|
42
|
-
.option('--swift <dir>', 'Generate Swift files to directory')
|
|
43
|
-
.action(withErrorHandler(globalOpts, async (cmdOpts) => {
|
|
44
|
-
const opts = globalOpts();
|
|
45
|
-
const flags = {
|
|
46
|
-
config: cmdOpts.config,
|
|
47
|
-
only: cmdOpts.only,
|
|
48
|
-
noPrettier: cmdOpts.prettier === false,
|
|
49
|
-
dryRun: !!cmdOpts.dryRun,
|
|
50
|
-
out: cmdOpts.out,
|
|
51
|
-
swift: cmdOpts.swift,
|
|
52
|
-
};
|
|
53
|
-
const config = await loadPullConfig(flags);
|
|
54
|
-
// Fetch models + customer profile schema + public schema
|
|
55
|
-
const client = await createClient(opts);
|
|
56
|
-
console.log(chalk.dim('Fetching models…'));
|
|
57
|
-
const [allModels, cpSchema, publicSchema] = await Promise.all([
|
|
58
|
-
fetchModelsForCodegen(client),
|
|
59
|
-
fetchCustomerProfileSchema(client),
|
|
60
|
-
fetchPublicSchema(client),
|
|
61
|
-
]);
|
|
62
|
-
if (allModels.length === 0 && !cpSchema) {
|
|
63
|
-
console.log(chalk.yellow('No models found. Nothing to generate.'));
|
|
64
|
-
return;
|
|
65
|
-
}
|
|
66
|
-
const models = filterModels(allModels, {
|
|
67
|
-
only: config.only.length > 0 ? config.only : undefined,
|
|
68
|
-
includeInline: config.includeInline,
|
|
69
|
-
});
|
|
70
|
-
console.log(chalk.dim(`Found ${allModels.length} model(s), generating for ${models.length}.`));
|
|
71
|
-
// Collect files to write
|
|
72
|
-
const cwd = process.cwd();
|
|
73
|
-
const typesDir = resolve(cwd, config.output.types);
|
|
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;
|
|
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 ───────────────────────────────────────────────
|
|
86
|
-
// 1. Static files
|
|
87
|
-
files.push({
|
|
88
|
-
path: resolve(typesDir, 'field-types.ts'),
|
|
89
|
-
content: generateFieldTypesFile(),
|
|
90
|
-
});
|
|
91
|
-
files.push({
|
|
92
|
-
path: resolve(typesDir, 'config.ts'),
|
|
93
|
-
content: generateConfigFile(),
|
|
94
|
-
});
|
|
95
|
-
// 2. Per-model type files
|
|
96
|
-
for (const model of models) {
|
|
97
|
-
files.push({
|
|
98
|
-
path: resolve(typesDir, 'models', `${model.key}.ts`),
|
|
99
|
-
content: generateModelTypes(model, models),
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
// 3. Model index
|
|
103
|
-
files.push({
|
|
104
|
-
path: resolve(typesDir, 'models', 'index.ts'),
|
|
105
|
-
content: generateModelIndex(models),
|
|
106
|
-
});
|
|
107
|
-
// 4. Customer profile types
|
|
108
|
-
if (hasCustomerProfile) {
|
|
109
|
-
files.push({
|
|
110
|
-
path: resolve(typesDir, 'customer-profile.ts'),
|
|
111
|
-
content: generateCustomerProfileTypes(cpSchema),
|
|
112
|
-
});
|
|
113
|
-
}
|
|
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
|
|
121
|
-
for (const model of publicModels) {
|
|
122
|
-
files.push({
|
|
123
|
-
path: resolve(docsDir, `${model.key}.graphql`),
|
|
124
|
-
content: generateModelDocuments(model),
|
|
125
|
-
});
|
|
126
|
-
}
|
|
127
|
-
// 6a. Shared fragments
|
|
128
|
-
const hasSharingModels = publicModels.some((m) => m.config.sharing?.enabled);
|
|
129
|
-
if (hasSharingModels) {
|
|
130
|
-
files.push({
|
|
131
|
-
path: resolve(docsDir, '_shared.graphql'),
|
|
132
|
-
content: generateSharedFragments(),
|
|
133
|
-
});
|
|
134
|
-
}
|
|
135
|
-
// 6b. Customer profile GraphQL documents
|
|
136
|
-
files.push({
|
|
137
|
-
path: resolve(docsDir, 'customer-profile.graphql'),
|
|
138
|
-
content: generateCustomerProfileDocuments(),
|
|
139
|
-
});
|
|
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);
|
|
158
|
-
files.push({
|
|
159
|
-
path: resolve(opsDir, '_common.ts'),
|
|
160
|
-
content: generateTypedOperationsCommon(typesRelPath),
|
|
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),
|
|
180
|
-
});
|
|
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) ────────────────────────────
|
|
220
|
-
if (config.output.swift) {
|
|
221
|
-
const swiftDir = resolve(cwd, config.output.swift);
|
|
222
|
-
files.push({
|
|
223
|
-
path: resolve(swiftDir, 'FieldTypes.swift'),
|
|
224
|
-
content: generateSwiftFieldTypesFile(),
|
|
225
|
-
});
|
|
226
|
-
files.push({
|
|
227
|
-
path: resolve(swiftDir, 'ModelKeys.swift'),
|
|
228
|
-
content: generateSwiftModelKeys(models),
|
|
229
|
-
});
|
|
230
|
-
for (const model of models) {
|
|
231
|
-
const swiftTypeName = toPascalCase(model.key);
|
|
232
|
-
files.push({
|
|
233
|
-
path: resolve(swiftDir, `${swiftTypeName}.swift`),
|
|
234
|
-
content: generateSwiftModelFile(model),
|
|
235
|
-
});
|
|
236
|
-
}
|
|
237
|
-
if (hasCustomerProfile) {
|
|
238
|
-
files.push({
|
|
239
|
-
path: resolve(swiftDir, 'CustomerProfile.swift'),
|
|
240
|
-
content: generateSwiftCustomerProfileFile(cpSchema),
|
|
241
|
-
});
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
// ─── Output ─────────────────────────────────────────────
|
|
245
|
-
// Dry run
|
|
246
|
-
if (config.dryRun) {
|
|
247
|
-
console.log(chalk.bold('\nDry run — files that would be generated:\n'));
|
|
248
|
-
for (const file of files) {
|
|
249
|
-
const rel = file.path.replace(cwd + '/', '');
|
|
250
|
-
console.log(` ${chalk.green('+')} ${rel}`);
|
|
251
|
-
}
|
|
252
|
-
console.log(`\n${chalk.dim(`${files.length} file(s) total`)}`);
|
|
253
|
-
return;
|
|
254
|
-
}
|
|
255
|
-
// Write files
|
|
256
|
-
await writeFiles(files, config.prettier);
|
|
257
|
-
// Summary
|
|
258
|
-
const modelCount = models.length;
|
|
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;
|
|
268
|
-
const cpSuffix = hasCustomerProfile ? ', customer profile' : '';
|
|
269
|
-
console.log(chalk.green(`\nGenerated ${files.length} file(s)`) +
|
|
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}`));
|
|
279
|
-
}
|
|
280
|
-
if (config.output.swift) {
|
|
281
|
-
console.log(chalk.dim(` Swift: ${resolve(cwd, config.output.swift)}`));
|
|
282
|
-
}
|
|
283
|
-
}));
|
|
284
|
-
}
|
|
285
|
-
function generateMainIndex(includeCustomerProfile) {
|
|
286
|
-
let code = `/**
|
|
287
|
-
* Generated types and configs
|
|
288
|
-
*
|
|
289
|
-
* @generated by foir — DO NOT EDIT MANUALLY
|
|
290
|
-
*/
|
|
291
|
-
|
|
292
|
-
export * from './field-types.js';
|
|
293
|
-
export * from './config.js';
|
|
294
|
-
export * from './models/index.js';
|
|
295
|
-
`;
|
|
296
|
-
if (includeCustomerProfile) {
|
|
297
|
-
code += `export * from './customer-profile.js';\n`;
|
|
298
|
-
}
|
|
299
|
-
return code;
|
|
300
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"records.d.ts","sourceRoot":"","sources":["../../src/commands/records.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AA6BtD,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE,MAAM,aAAa,GAC9B,IAAI,CAuZN"}
|