@eide/foir-cli 0.1.35 → 0.1.37
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/dist/schema.graphql +6062 -0
- 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
package/dist/commands/records.js
DELETED
|
@@ -1,314 +0,0 @@
|
|
|
1
|
-
import { withErrorHandler } from '../lib/errors.js';
|
|
2
|
-
import { createClient } from '../lib/client.js';
|
|
3
|
-
import { formatOutput, formatList, timeAgo, success } from '../lib/output.js';
|
|
4
|
-
import { parseInputData, parseFilters, parseSort, isUUID, confirmAction, } from '../lib/input.js';
|
|
5
|
-
import { ListRecordsDocument, GetRecordDocument, GetRecordResolvedDocument, GetRecordByKeyDocument, GetRecordByKeyResolvedDocument, CreateRecordDocument, UpdateRecordDocument, DeleteRecordDocument, PublishVersionDocument, UnpublishRecordDocument, DuplicateRecordDocument, CreateVersionDocument, CreateVariantDocument, RecordVersionsDocument, RecordVariantsDocument, } from '../graphql/generated.js';
|
|
6
|
-
export function registerRecordsCommands(program, globalOpts) {
|
|
7
|
-
const records = program.command('records').description('Manage records');
|
|
8
|
-
// list
|
|
9
|
-
records
|
|
10
|
-
.command('list <modelKey>')
|
|
11
|
-
.description('List records for a model')
|
|
12
|
-
.option('--filter <expr>', 'Filter expression (e.g. status=active)')
|
|
13
|
-
.option('--sort <expr>', 'Sort expression (e.g. createdAt:desc)')
|
|
14
|
-
.option('--limit <n>', 'Max results', '20')
|
|
15
|
-
.option('--offset <n>', 'Skip results', '0')
|
|
16
|
-
.action(withErrorHandler(globalOpts, async (modelKey, cmdOpts) => {
|
|
17
|
-
const opts = globalOpts();
|
|
18
|
-
const client = await createClient(opts);
|
|
19
|
-
const variables = {
|
|
20
|
-
modelKey,
|
|
21
|
-
limit: parseInt(cmdOpts.limit ?? '20', 10),
|
|
22
|
-
offset: parseInt(cmdOpts.offset ?? '0', 10),
|
|
23
|
-
};
|
|
24
|
-
if (cmdOpts.filter)
|
|
25
|
-
variables.filters = parseFilters(cmdOpts.filter);
|
|
26
|
-
if (cmdOpts.sort)
|
|
27
|
-
variables.sort = parseSort(cmdOpts.sort);
|
|
28
|
-
const data = await client.request(ListRecordsDocument, variables);
|
|
29
|
-
formatList(data.records.items, opts, {
|
|
30
|
-
columns: [
|
|
31
|
-
{ key: 'id', header: 'ID', width: 28 },
|
|
32
|
-
{ key: 'naturalKey', header: 'Key', width: 24 },
|
|
33
|
-
{ key: 'versionNumber', header: 'Version', width: 8 },
|
|
34
|
-
{
|
|
35
|
-
key: 'updatedAt',
|
|
36
|
-
header: 'Updated',
|
|
37
|
-
width: 12,
|
|
38
|
-
format: (v) => timeAgo(v),
|
|
39
|
-
},
|
|
40
|
-
],
|
|
41
|
-
total: data.records.total,
|
|
42
|
-
});
|
|
43
|
-
}));
|
|
44
|
-
// get
|
|
45
|
-
records
|
|
46
|
-
.command('get <modelKey> <idOrKey>')
|
|
47
|
-
.description('Get a record by ID or natural key')
|
|
48
|
-
.option('--resolved', 'Include resolved content (published version)')
|
|
49
|
-
.option('--preview', 'Resolve latest draft instead of published version')
|
|
50
|
-
.option('--locale <locale>', 'Locale for field translations')
|
|
51
|
-
.action(withErrorHandler(globalOpts, async (modelKey, idOrKey, cmdOpts) => {
|
|
52
|
-
const opts = globalOpts();
|
|
53
|
-
const client = await createClient(opts);
|
|
54
|
-
let result;
|
|
55
|
-
const useResolved = !!cmdOpts.resolved || !!cmdOpts.preview;
|
|
56
|
-
if (isUUID(idOrKey)) {
|
|
57
|
-
if (useResolved) {
|
|
58
|
-
const variables = { id: idOrKey };
|
|
59
|
-
if (cmdOpts.locale)
|
|
60
|
-
variables.locale = cmdOpts.locale;
|
|
61
|
-
if (cmdOpts.preview)
|
|
62
|
-
variables.preview = true;
|
|
63
|
-
const data = await client.request(GetRecordResolvedDocument, variables);
|
|
64
|
-
result = data.record;
|
|
65
|
-
}
|
|
66
|
-
else {
|
|
67
|
-
const data = await client.request(GetRecordDocument, {
|
|
68
|
-
id: idOrKey,
|
|
69
|
-
});
|
|
70
|
-
result = data.record;
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
else {
|
|
74
|
-
if (useResolved) {
|
|
75
|
-
const variables = {
|
|
76
|
-
modelKey,
|
|
77
|
-
naturalKey: idOrKey,
|
|
78
|
-
};
|
|
79
|
-
if (cmdOpts.locale)
|
|
80
|
-
variables.locale = cmdOpts.locale;
|
|
81
|
-
if (cmdOpts.preview)
|
|
82
|
-
variables.preview = true;
|
|
83
|
-
const data = await client.request(GetRecordByKeyResolvedDocument, variables);
|
|
84
|
-
result = data.recordByKey;
|
|
85
|
-
}
|
|
86
|
-
else {
|
|
87
|
-
const data = await client.request(GetRecordByKeyDocument, {
|
|
88
|
-
modelKey,
|
|
89
|
-
naturalKey: idOrKey,
|
|
90
|
-
});
|
|
91
|
-
result = data.recordByKey;
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
if (!result) {
|
|
95
|
-
throw new Error(`Record "${idOrKey}" not found in model "${modelKey}".`);
|
|
96
|
-
}
|
|
97
|
-
formatOutput(result, opts);
|
|
98
|
-
}));
|
|
99
|
-
// create
|
|
100
|
-
records
|
|
101
|
-
.command('create <modelKey>')
|
|
102
|
-
.description('Create a new record')
|
|
103
|
-
.option('-d, --data <json>', 'Record data as JSON')
|
|
104
|
-
.option('-f, --file <path>', 'Read data from file')
|
|
105
|
-
.action(withErrorHandler(globalOpts, async (modelKey, cmdOpts) => {
|
|
106
|
-
const opts = globalOpts();
|
|
107
|
-
const client = await createClient(opts);
|
|
108
|
-
const inputData = await parseInputData(cmdOpts);
|
|
109
|
-
const input = { modelKey, ...inputData };
|
|
110
|
-
const data = await client.request(CreateRecordDocument, {
|
|
111
|
-
input,
|
|
112
|
-
});
|
|
113
|
-
formatOutput(data.createRecord, opts);
|
|
114
|
-
if (!(opts.json || opts.jsonl || opts.quiet)) {
|
|
115
|
-
success(`Created record ${data.createRecord.record.id}`);
|
|
116
|
-
}
|
|
117
|
-
}));
|
|
118
|
-
// update
|
|
119
|
-
records
|
|
120
|
-
.command('update <modelKey> <id>')
|
|
121
|
-
.description('Update a record')
|
|
122
|
-
.option('-d, --data <json>', 'Record data as JSON')
|
|
123
|
-
.option('-f, --file <path>', 'Read data from file')
|
|
124
|
-
.action(withErrorHandler(globalOpts, async (_modelKey, id, cmdOpts) => {
|
|
125
|
-
const opts = globalOpts();
|
|
126
|
-
const client = await createClient(opts);
|
|
127
|
-
const inputData = await parseInputData(cmdOpts);
|
|
128
|
-
const input = { id, ...inputData };
|
|
129
|
-
const data = await client.request(UpdateRecordDocument, { input });
|
|
130
|
-
formatOutput(data.updateRecord, opts);
|
|
131
|
-
if (!(opts.json || opts.jsonl || opts.quiet)) {
|
|
132
|
-
success(`Updated record ${id}`);
|
|
133
|
-
}
|
|
134
|
-
}));
|
|
135
|
-
// delete
|
|
136
|
-
records
|
|
137
|
-
.command('delete <modelKey> <id>')
|
|
138
|
-
.description('Delete a record')
|
|
139
|
-
.option('--confirm', 'Skip confirmation prompt')
|
|
140
|
-
.action(withErrorHandler(globalOpts, async (_modelKey, id, cmdOpts) => {
|
|
141
|
-
const opts = globalOpts();
|
|
142
|
-
const confirmed = await confirmAction(`Delete record ${id}?`, {
|
|
143
|
-
confirm: !!cmdOpts.confirm,
|
|
144
|
-
});
|
|
145
|
-
if (!confirmed) {
|
|
146
|
-
console.log('Aborted.');
|
|
147
|
-
return;
|
|
148
|
-
}
|
|
149
|
-
const client = await createClient(opts);
|
|
150
|
-
const data = await client.request(DeleteRecordDocument, { id });
|
|
151
|
-
formatOutput(data.deleteRecord, opts);
|
|
152
|
-
if (!(opts.json || opts.jsonl || opts.quiet)) {
|
|
153
|
-
success(`Deleted record ${id}`);
|
|
154
|
-
}
|
|
155
|
-
}));
|
|
156
|
-
// publish
|
|
157
|
-
records
|
|
158
|
-
.command('publish <versionId>')
|
|
159
|
-
.description('Publish a record version')
|
|
160
|
-
.action(withErrorHandler(globalOpts, async (versionId) => {
|
|
161
|
-
const opts = globalOpts();
|
|
162
|
-
const client = await createClient(opts);
|
|
163
|
-
await client.request(PublishVersionDocument, { versionId });
|
|
164
|
-
if (opts.json || opts.jsonl) {
|
|
165
|
-
formatOutput({ published: true, versionId }, opts);
|
|
166
|
-
}
|
|
167
|
-
else {
|
|
168
|
-
success(`Published version ${versionId}`);
|
|
169
|
-
}
|
|
170
|
-
}));
|
|
171
|
-
// unpublish
|
|
172
|
-
records
|
|
173
|
-
.command('unpublish <id>')
|
|
174
|
-
.description('Unpublish a record')
|
|
175
|
-
.action(withErrorHandler(globalOpts, async (id) => {
|
|
176
|
-
const opts = globalOpts();
|
|
177
|
-
const client = await createClient(opts);
|
|
178
|
-
await client.request(UnpublishRecordDocument, { id });
|
|
179
|
-
if (opts.json || opts.jsonl) {
|
|
180
|
-
formatOutput({ unpublished: true, id }, opts);
|
|
181
|
-
}
|
|
182
|
-
else {
|
|
183
|
-
success(`Unpublished record ${id}`);
|
|
184
|
-
}
|
|
185
|
-
}));
|
|
186
|
-
// duplicate
|
|
187
|
-
records
|
|
188
|
-
.command('duplicate <modelKey> <id>')
|
|
189
|
-
.description('Duplicate a record')
|
|
190
|
-
.option('--natural-key <key>', 'Natural key for the duplicate')
|
|
191
|
-
.action(withErrorHandler(globalOpts, async (_modelKey, id, cmdOpts) => {
|
|
192
|
-
const opts = globalOpts();
|
|
193
|
-
const client = await createClient(opts);
|
|
194
|
-
const naturalKey = cmdOpts.naturalKey ?? `${id}-copy`;
|
|
195
|
-
const data = await client.request(DuplicateRecordDocument, {
|
|
196
|
-
input: { recordId: id, naturalKey },
|
|
197
|
-
});
|
|
198
|
-
formatOutput(data.duplicateRecord, opts);
|
|
199
|
-
if (!(opts.json || opts.jsonl || opts.quiet)) {
|
|
200
|
-
success(`Duplicated → ${data.duplicateRecord.record.id}`);
|
|
201
|
-
}
|
|
202
|
-
}));
|
|
203
|
-
// versions
|
|
204
|
-
records
|
|
205
|
-
.command('versions <id>')
|
|
206
|
-
.description('List versions for a record')
|
|
207
|
-
.option('--limit <n>', 'Max results', '20')
|
|
208
|
-
.action(withErrorHandler(globalOpts, async (parentId, cmdOpts) => {
|
|
209
|
-
const opts = globalOpts();
|
|
210
|
-
const client = await createClient(opts);
|
|
211
|
-
const data = await client.request(RecordVersionsDocument, {
|
|
212
|
-
parentId,
|
|
213
|
-
limit: parseInt(cmdOpts.limit ?? '20', 10),
|
|
214
|
-
});
|
|
215
|
-
formatList(data.recordVersions.items, opts, {
|
|
216
|
-
columns: [
|
|
217
|
-
{ key: 'id', header: 'Version ID', width: 28 },
|
|
218
|
-
{ key: 'versionNumber', header: '#', width: 5 },
|
|
219
|
-
{ key: 'changeDescription', header: 'Description', width: 30 },
|
|
220
|
-
{
|
|
221
|
-
key: 'createdAt',
|
|
222
|
-
header: 'Created',
|
|
223
|
-
width: 12,
|
|
224
|
-
format: (v) => timeAgo(v),
|
|
225
|
-
},
|
|
226
|
-
],
|
|
227
|
-
});
|
|
228
|
-
}));
|
|
229
|
-
// variants
|
|
230
|
-
records
|
|
231
|
-
.command('variants <recordId>')
|
|
232
|
-
.description('List variants for a record')
|
|
233
|
-
.action(withErrorHandler(globalOpts, async (recordId) => {
|
|
234
|
-
const opts = globalOpts();
|
|
235
|
-
const client = await createClient(opts);
|
|
236
|
-
const data = await client.request(RecordVariantsDocument, { recordId });
|
|
237
|
-
formatList(data.recordVariants.items, opts, {
|
|
238
|
-
columns: [
|
|
239
|
-
{ key: 'id', header: 'Variant ID', width: 28 },
|
|
240
|
-
{ key: 'variantKey', header: 'Key', width: 20 },
|
|
241
|
-
{ key: 'isDefault', header: 'Default', width: 8 },
|
|
242
|
-
{
|
|
243
|
-
key: 'createdAt',
|
|
244
|
-
header: 'Created',
|
|
245
|
-
width: 12,
|
|
246
|
-
format: (v) => timeAgo(v),
|
|
247
|
-
},
|
|
248
|
-
],
|
|
249
|
-
});
|
|
250
|
-
}));
|
|
251
|
-
// create-version
|
|
252
|
-
records
|
|
253
|
-
.command('create-version <parentId>')
|
|
254
|
-
.description('Create a new version on a versioned record (or variant). parentId is the record or variant ID.')
|
|
255
|
-
.option('-d, --data <json>', 'Version content as JSON')
|
|
256
|
-
.option('-f, --file <path>', 'Read content from file')
|
|
257
|
-
.option('-m, --message <msg>', 'Change description')
|
|
258
|
-
.option('--source-version <id>', 'Source version ID to base off')
|
|
259
|
-
.action(withErrorHandler(globalOpts, async (parentId, cmdOpts) => {
|
|
260
|
-
const opts = globalOpts();
|
|
261
|
-
const client = await createClient(opts);
|
|
262
|
-
const inputData = await parseInputData(cmdOpts);
|
|
263
|
-
const input = {
|
|
264
|
-
parentId,
|
|
265
|
-
content: inputData,
|
|
266
|
-
};
|
|
267
|
-
if (cmdOpts.message)
|
|
268
|
-
input.changeDescription = cmdOpts.message;
|
|
269
|
-
if (cmdOpts.sourceVersion)
|
|
270
|
-
input.sourceVersionId = cmdOpts.sourceVersion;
|
|
271
|
-
const data = await client.request(CreateVersionDocument, {
|
|
272
|
-
input,
|
|
273
|
-
});
|
|
274
|
-
formatOutput(data.createVersion, opts);
|
|
275
|
-
if (!(opts.json || opts.jsonl || opts.quiet)) {
|
|
276
|
-
success(`Created version ${data.createVersion.id}`);
|
|
277
|
-
}
|
|
278
|
-
}));
|
|
279
|
-
// create-variant
|
|
280
|
-
records
|
|
281
|
-
.command('create-variant <recordId>')
|
|
282
|
-
.description('Create a new variant on a record')
|
|
283
|
-
.requiredOption('--key <variantKey>', 'Variant key (e.g. "uk-market")')
|
|
284
|
-
.option('--name <name>', 'Variant display name')
|
|
285
|
-
.option('--description <desc>', 'Variant description')
|
|
286
|
-
.option('--catalog-id <id>', 'Variant catalog entry ID')
|
|
287
|
-
.option('--priority <n>', 'Priority (lower = higher priority)')
|
|
288
|
-
.option('--default', 'Set as default variant')
|
|
289
|
-
.action(withErrorHandler(globalOpts, async (recordId, cmdOpts) => {
|
|
290
|
-
const opts = globalOpts();
|
|
291
|
-
const client = await createClient(opts);
|
|
292
|
-
const input = {
|
|
293
|
-
recordId,
|
|
294
|
-
variantKey: cmdOpts.key,
|
|
295
|
-
};
|
|
296
|
-
if (cmdOpts.name)
|
|
297
|
-
input.name = cmdOpts.name;
|
|
298
|
-
if (cmdOpts.description)
|
|
299
|
-
input.description = cmdOpts.description;
|
|
300
|
-
if (cmdOpts.catalogId)
|
|
301
|
-
input.catalogId = cmdOpts.catalogId;
|
|
302
|
-
if (cmdOpts.priority !== undefined)
|
|
303
|
-
input.priority = parseInt(cmdOpts.priority, 10);
|
|
304
|
-
if (cmdOpts.default)
|
|
305
|
-
input.isDefault = true;
|
|
306
|
-
const data = await client.request(CreateVariantDocument, {
|
|
307
|
-
input,
|
|
308
|
-
});
|
|
309
|
-
formatOutput(data.createVariant, opts);
|
|
310
|
-
if (!(opts.json || opts.jsonl || opts.quiet)) {
|
|
311
|
-
success(`Created variant ${data.createVariant.id}`);
|
|
312
|
-
}
|
|
313
|
-
}));
|
|
314
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import type { Command } from 'commander';
|
|
2
|
-
import type { GlobalOptions } from '../lib/config.js';
|
|
3
|
-
/**
|
|
4
|
-
* Register all declarative commands from the command registry.
|
|
5
|
-
*/
|
|
6
|
-
export declare function registerDynamicCommands(program: Command, globalOpts: () => GlobalOptions): void;
|
|
7
|
-
//# sourceMappingURL=register-commands.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"register-commands.d.ts","sourceRoot":"","sources":["../../src/commands/register-commands.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOzC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AA0GtD;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE,MAAM,aAAa,GAC9B,IAAI,CA8LN"}
|
|
@@ -1,259 +0,0 @@
|
|
|
1
|
-
import { readFileSync } from 'fs';
|
|
2
|
-
import { resolve, dirname } from 'path';
|
|
3
|
-
import { fileURLToPath } from 'url';
|
|
4
|
-
import { COMMANDS, createSchemaEngine, } from '@eide/command-registry';
|
|
5
|
-
import { withErrorHandler } from '../lib/errors.js';
|
|
6
|
-
import { createClient } from '../lib/client.js';
|
|
7
|
-
import { formatOutput, formatList, timeAgo, success, } from '../lib/output.js';
|
|
8
|
-
import { parseInputData, confirmAction, isUUID } from '../lib/input.js';
|
|
9
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
10
|
-
const __dirname = dirname(__filename);
|
|
11
|
-
function loadSchemaSDL() {
|
|
12
|
-
// Try monorepo path first (development)
|
|
13
|
-
const monorepoPath = resolve(__dirname, '../../../../graphql-core/schema.graphql');
|
|
14
|
-
try {
|
|
15
|
-
return readFileSync(monorepoPath, 'utf-8');
|
|
16
|
-
}
|
|
17
|
-
catch {
|
|
18
|
-
// Fall back to relative path from dist (might differ)
|
|
19
|
-
const altPath = resolve(__dirname, '../../../graphql-core/schema.graphql');
|
|
20
|
-
try {
|
|
21
|
-
return readFileSync(altPath, 'utf-8');
|
|
22
|
-
}
|
|
23
|
-
catch {
|
|
24
|
-
throw new Error('Could not find schema.graphql. Ensure you are running from within the EIDE monorepo.');
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* Extract the useful data from a GraphQL result, unwrapping list wrappers.
|
|
30
|
-
*/
|
|
31
|
-
function extractResult(result, operationName) {
|
|
32
|
-
const raw = result[operationName];
|
|
33
|
-
if (!raw || typeof raw !== 'object')
|
|
34
|
-
return { data: raw };
|
|
35
|
-
const obj = raw;
|
|
36
|
-
// Check for list wrappers: { items: [...], total } or { entityName: [...], total }
|
|
37
|
-
if ('total' in obj) {
|
|
38
|
-
for (const [key, val] of Object.entries(obj)) {
|
|
39
|
-
if (key !== 'total' && key !== '__typename' && Array.isArray(val)) {
|
|
40
|
-
return { data: val, total: obj.total };
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
return { data: raw };
|
|
45
|
-
}
|
|
46
|
-
/**
|
|
47
|
-
* Convert registry ColumnDef (with string format) to CLI ColumnDef (with format function).
|
|
48
|
-
*/
|
|
49
|
-
function toCliColumns(columns) {
|
|
50
|
-
if (!columns)
|
|
51
|
-
return undefined;
|
|
52
|
-
return columns.map((col) => {
|
|
53
|
-
const cliCol = {
|
|
54
|
-
key: col.key,
|
|
55
|
-
header: col.header,
|
|
56
|
-
width: col.width,
|
|
57
|
-
};
|
|
58
|
-
switch (col.format) {
|
|
59
|
-
case 'timeAgo':
|
|
60
|
-
cliCol.format = (v) => timeAgo(v);
|
|
61
|
-
break;
|
|
62
|
-
case 'boolean':
|
|
63
|
-
cliCol.format = (v) => (v ? 'yes' : '');
|
|
64
|
-
break;
|
|
65
|
-
case 'truncate':
|
|
66
|
-
cliCol.format = (v) => {
|
|
67
|
-
const str = String(v ?? '');
|
|
68
|
-
return str.length > 40 ? str.slice(0, 39) + '\u2026' : str;
|
|
69
|
-
};
|
|
70
|
-
break;
|
|
71
|
-
case 'join':
|
|
72
|
-
cliCol.format = (v) => Array.isArray(v) ? v.join(', ') : String(v ?? '');
|
|
73
|
-
break;
|
|
74
|
-
case 'bytes':
|
|
75
|
-
cliCol.format = (v) => {
|
|
76
|
-
const num = Number(v);
|
|
77
|
-
if (num < 1024)
|
|
78
|
-
return `${num} B`;
|
|
79
|
-
if (num < 1024 * 1024)
|
|
80
|
-
return `${(num / 1024).toFixed(1)} KB`;
|
|
81
|
-
return `${(num / (1024 * 1024)).toFixed(1)} MB`;
|
|
82
|
-
};
|
|
83
|
-
break;
|
|
84
|
-
}
|
|
85
|
-
return cliCol;
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
|
-
/**
|
|
89
|
-
* Register all declarative commands from the command registry.
|
|
90
|
-
*/
|
|
91
|
-
export function registerDynamicCommands(program, globalOpts) {
|
|
92
|
-
let engine;
|
|
93
|
-
try {
|
|
94
|
-
const sdl = loadSchemaSDL();
|
|
95
|
-
engine = createSchemaEngine(sdl);
|
|
96
|
-
}
|
|
97
|
-
catch (err) {
|
|
98
|
-
// If schema can't be loaded, skip dynamic command registration
|
|
99
|
-
// (special commands still work)
|
|
100
|
-
console.error(`Warning: Could not load schema for dynamic commands: ${err instanceof Error ? err.message : String(err)}`);
|
|
101
|
-
return;
|
|
102
|
-
}
|
|
103
|
-
// Group commands by group name
|
|
104
|
-
const groups = new Map();
|
|
105
|
-
for (const cmd of COMMANDS) {
|
|
106
|
-
if (!groups.has(cmd.group))
|
|
107
|
-
groups.set(cmd.group, []);
|
|
108
|
-
groups.get(cmd.group).push(cmd);
|
|
109
|
-
}
|
|
110
|
-
for (const [groupName, entries] of groups) {
|
|
111
|
-
const group = program.command(groupName).description(`Manage ${groupName}`);
|
|
112
|
-
for (const entry of entries) {
|
|
113
|
-
let cmd = group.command(entry.name).description(entry.description);
|
|
114
|
-
// Add positional args
|
|
115
|
-
for (const pos of entry.positionalArgs ?? []) {
|
|
116
|
-
cmd = cmd.argument(`<${pos.name}>`, pos.description ?? pos.name);
|
|
117
|
-
}
|
|
118
|
-
// Add flags from schema args (excluding positional args and input args)
|
|
119
|
-
const schemaArgs = engine.getOperationArgs(entry.operation, entry.operationType);
|
|
120
|
-
for (const arg of schemaArgs) {
|
|
121
|
-
// Skip if already a positional arg
|
|
122
|
-
if (entry.positionalArgs?.some((p) => p.graphqlArg === arg.name))
|
|
123
|
-
continue;
|
|
124
|
-
// Skip if it's the input arg
|
|
125
|
-
if (entry.acceptsInput && arg.name === (entry.inputArgName ?? 'input'))
|
|
126
|
-
continue;
|
|
127
|
-
const reqStr = arg.required ? ' (required)' : '';
|
|
128
|
-
cmd = cmd.option(`--${arg.name} <value>`, `${arg.name}${reqStr}`);
|
|
129
|
-
}
|
|
130
|
-
// Add --data/--file for input commands
|
|
131
|
-
if (entry.acceptsInput) {
|
|
132
|
-
cmd = cmd.option('-d, --data <json>', 'Data as JSON');
|
|
133
|
-
cmd = cmd.option('-f, --file <path>', 'Read data from file');
|
|
134
|
-
}
|
|
135
|
-
// Add --confirm for destructive commands
|
|
136
|
-
if (entry.requiresConfirmation) {
|
|
137
|
-
cmd = cmd.option('--confirm', 'Skip confirmation prompt');
|
|
138
|
-
}
|
|
139
|
-
// Action handler
|
|
140
|
-
cmd.action(withErrorHandler(globalOpts, async (...actionArgs) => {
|
|
141
|
-
const opts = globalOpts();
|
|
142
|
-
const client = await createClient(opts);
|
|
143
|
-
// Build variables from positional args + flags
|
|
144
|
-
const variables = {};
|
|
145
|
-
// Map positional args
|
|
146
|
-
const positionals = entry.positionalArgs ?? [];
|
|
147
|
-
for (let i = 0; i < positionals.length; i++) {
|
|
148
|
-
const posDef = positionals[i];
|
|
149
|
-
const value = actionArgs[i];
|
|
150
|
-
if (value) {
|
|
151
|
-
variables[posDef.graphqlArg] = value;
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
// The flags/options object is the last argument from Commander
|
|
155
|
-
const flags = (actionArgs[positionals.length] ?? {});
|
|
156
|
-
// Map named flags to variables (coerce types)
|
|
157
|
-
const rawFlags = {};
|
|
158
|
-
for (const [key, val] of Object.entries(flags)) {
|
|
159
|
-
if (key === 'data' || key === 'file' || key === 'confirm')
|
|
160
|
-
continue;
|
|
161
|
-
rawFlags[key] = String(val);
|
|
162
|
-
}
|
|
163
|
-
const coerced = engine.coerceArgs(entry.operation, entry.operationType, rawFlags);
|
|
164
|
-
Object.assign(variables, coerced);
|
|
165
|
-
// Handle input data (--data, --file, stdin)
|
|
166
|
-
if (entry.acceptsInput && (flags.data || flags.file)) {
|
|
167
|
-
const inputData = await parseInputData({
|
|
168
|
-
data: flags.data,
|
|
169
|
-
file: flags.file,
|
|
170
|
-
});
|
|
171
|
-
const argName = entry.inputArgName ?? 'input';
|
|
172
|
-
variables[argName] = inputData;
|
|
173
|
-
}
|
|
174
|
-
// Handle alternate get (by key/code instead of UUID)
|
|
175
|
-
if (entry.alternateGet &&
|
|
176
|
-
positionals.length > 0 &&
|
|
177
|
-
variables[positionals[0].graphqlArg]) {
|
|
178
|
-
const firstArgValue = String(variables[positionals[0].graphqlArg]);
|
|
179
|
-
if (!isUUID(firstArgValue)) {
|
|
180
|
-
// Use alternate operation
|
|
181
|
-
const altEntry = {
|
|
182
|
-
...entry,
|
|
183
|
-
operation: entry.alternateGet.operation,
|
|
184
|
-
positionalArgs: [
|
|
185
|
-
{
|
|
186
|
-
name: positionals[0].name,
|
|
187
|
-
graphqlArg: entry.alternateGet.argName,
|
|
188
|
-
},
|
|
189
|
-
],
|
|
190
|
-
};
|
|
191
|
-
// Remap the variable
|
|
192
|
-
delete variables[positionals[0].graphqlArg];
|
|
193
|
-
variables[entry.alternateGet.argName] = firstArgValue;
|
|
194
|
-
const queryStr = engine.buildQuery(altEntry, variables);
|
|
195
|
-
const result = (await client.request(queryStr, variables));
|
|
196
|
-
const { data } = extractResult(result, altEntry.operation);
|
|
197
|
-
formatOutput(data, opts);
|
|
198
|
-
return;
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
// Confirmation prompt for destructive actions
|
|
202
|
-
if (entry.requiresConfirmation) {
|
|
203
|
-
const confirmed = await confirmAction(`${entry.description}?`, {
|
|
204
|
-
confirm: !!flags.confirm,
|
|
205
|
-
});
|
|
206
|
-
if (!confirmed) {
|
|
207
|
-
console.log('Aborted.');
|
|
208
|
-
return;
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
// Build and execute query
|
|
212
|
-
const queryStr = engine.buildQuery(entry, variables);
|
|
213
|
-
const result = (await client.request(queryStr, variables));
|
|
214
|
-
const { data, total } = extractResult(result, entry.operation);
|
|
215
|
-
// Format output
|
|
216
|
-
if (entry.scalarResult) {
|
|
217
|
-
if (!(opts.json || opts.jsonl || opts.quiet)) {
|
|
218
|
-
if (entry.successMessage) {
|
|
219
|
-
success(entry.successMessage);
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
else {
|
|
223
|
-
formatOutput(data, opts);
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
else if (Array.isArray(data)) {
|
|
227
|
-
const cliColumns = toCliColumns(entry.columns);
|
|
228
|
-
formatList(data, opts, {
|
|
229
|
-
columns: cliColumns ?? autoColumns(data),
|
|
230
|
-
total,
|
|
231
|
-
});
|
|
232
|
-
}
|
|
233
|
-
else {
|
|
234
|
-
formatOutput(data, opts);
|
|
235
|
-
if (entry.successMessage &&
|
|
236
|
-
!(opts.json || opts.jsonl || opts.quiet)) {
|
|
237
|
-
success(entry.successMessage);
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
}));
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
/**
|
|
245
|
-
* Auto-generate column definitions from the first item in an array.
|
|
246
|
-
*/
|
|
247
|
-
function autoColumns(items) {
|
|
248
|
-
if (items.length === 0)
|
|
249
|
-
return [];
|
|
250
|
-
const first = items[0];
|
|
251
|
-
return Object.keys(first)
|
|
252
|
-
.filter((k) => k !== '__typename')
|
|
253
|
-
.slice(0, 6)
|
|
254
|
-
.map((key) => ({
|
|
255
|
-
key,
|
|
256
|
-
header: key,
|
|
257
|
-
width: 20,
|
|
258
|
-
}));
|
|
259
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"schedules.d.ts","sourceRoot":"","sources":["../../src/commands/schedules.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAgBtD,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE,MAAM,aAAa,GAC9B,IAAI,CAmLN"}
|