makefx 0.1.3 → 0.2.0
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/README.md +3 -1
- package/makefx.mjs +2898 -130
- package/package.json +1 -1
package/makefx.mjs
CHANGED
|
@@ -44,7 +44,19 @@ var __toCommonJS = (mod) => __hasOwnProp.call(mod, "module.exports") ? mod["modu
|
|
|
44
44
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
45
45
|
//#endregion
|
|
46
46
|
//#region src/cli/lib/utils.ts
|
|
47
|
-
var BOOLEAN_LONG_OPTIONS = new Set([
|
|
47
|
+
var BOOLEAN_LONG_OPTIONS = new Set([
|
|
48
|
+
"audio",
|
|
49
|
+
"append",
|
|
50
|
+
"default",
|
|
51
|
+
"disable",
|
|
52
|
+
"enable",
|
|
53
|
+
"json",
|
|
54
|
+
"local",
|
|
55
|
+
"no-collection",
|
|
56
|
+
"no-default",
|
|
57
|
+
"no-audio",
|
|
58
|
+
"no-style"
|
|
59
|
+
]);
|
|
48
60
|
function parseArgs(argv) {
|
|
49
61
|
const options = {};
|
|
50
62
|
const positionals = [];
|
|
@@ -689,6 +701,7 @@ async function handleBillingOpsCheck(env) {
|
|
|
689
701
|
if (product?.productId) console.log(` Product: ${product.productId}${product.name ? ` (${product.name})` : ""}`);
|
|
690
702
|
console.log(` Metered prices: ${product?.meteredPriceMeters.length ?? 0}/${productCheck.expectedMeteredPriceMeters.length}`);
|
|
691
703
|
if (productCheck.missingMeteredPriceMeters.length > 0) console.log(` Missing metered prices: ${productCheck.missingMeteredPriceMeters.join(", ")}`);
|
|
704
|
+
if (productCheck.unexpectedMeterCreditBenefitMeters.length > 0) console.log(` Unexpected meter-credit benefits: ${productCheck.unexpectedMeterCreditBenefitMeters.join(", ")}`);
|
|
692
705
|
}
|
|
693
706
|
const syncCheck = billingChecks.checks.syncHealth;
|
|
694
707
|
console.log("\nSync health:");
|
|
@@ -725,8 +738,26 @@ async function handleBillingReconcile(env, parsed) {
|
|
|
725
738
|
const marker = meter.matched ? "OK " : "MISMATCH";
|
|
726
739
|
console.log(` ${marker} ${meter.name.padEnd(22)} local=${meter.local} polar=${meter.polar} delta=${meter.delta}`);
|
|
727
740
|
}
|
|
728
|
-
if (data.
|
|
729
|
-
console.log("\
|
|
741
|
+
if (data.customerCharges) {
|
|
742
|
+
console.log("\nCustomer charge ledger:");
|
|
743
|
+
console.log(` usageEvents=${data.customerCharges.usageEvents} chargeRows=${data.customerCharges.chargeRows} missing=${data.customerCharges.missingChargeRows} orphan=${data.customerCharges.orphanChargeRows}`);
|
|
744
|
+
console.log(` billableUsage=${data.customerCharges.billableUsageQuantity} billableCharges=${data.customerCharges.billableChargeQuantity} delta=${data.customerCharges.billableQuantityDelta}`);
|
|
745
|
+
}
|
|
746
|
+
if (data.providerCost) {
|
|
747
|
+
console.log("\nProvider cost ledger:");
|
|
748
|
+
console.log(` amount=$${data.providerCost.totals.amountUsd.toFixed(6)} entries=${data.providerCost.totals.entries} unpriced=${data.providerCost.totals.unpricedEntries}`);
|
|
749
|
+
console.log(` linkedUsage=${data.providerCost.linkedUsageEvents} linkedCharges=${data.providerCost.linkedCustomerCharges} missingUsage=${data.providerCost.missingUsageEventLinks} missingCharges=${data.providerCost.missingCustomerChargeLinks}`);
|
|
750
|
+
}
|
|
751
|
+
if (data.platformUsage) {
|
|
752
|
+
console.log("\nPlatform usage:");
|
|
753
|
+
console.log(` storageBytes=${data.platformUsage.totals.storageBytes} workflowRuns=${data.platformUsage.totals.workflowRuns} deliveryBytes=${data.platformUsage.totals.deliveryBytes}`);
|
|
754
|
+
}
|
|
755
|
+
if (data.alerts && data.alerts.length > 0) {
|
|
756
|
+
console.log("\nAlerts:");
|
|
757
|
+
for (const alert of data.alerts) console.log(` ${alert.severity.toUpperCase().padEnd(8)} ${alert.code}: ${alert.message}`);
|
|
758
|
+
}
|
|
759
|
+
if (data.status === "mismatch") {
|
|
760
|
+
console.log("\nMismatched billing ledgers need sync/retry or attribution investigation before billing is considered reconciled.");
|
|
730
761
|
process$1.exitCode = 1;
|
|
731
762
|
}
|
|
732
763
|
} catch (error) {
|
|
@@ -808,7 +839,7 @@ function validateProjectConfig(config, configPath) {
|
|
|
808
839
|
* makefx spaces --id <space_id> Show details for a specific space
|
|
809
840
|
* makefx spaces create <name> Create a new space
|
|
810
841
|
*/
|
|
811
|
-
var defaultDeps$
|
|
842
|
+
var defaultDeps$13 = {
|
|
812
843
|
loadConfig: loadStoredConfig,
|
|
813
844
|
resolveBaseUrl,
|
|
814
845
|
saveProjectConfig,
|
|
@@ -823,7 +854,7 @@ async function handleSpaces(parsed) {
|
|
|
823
854
|
process$1.exitCode = 1;
|
|
824
855
|
}
|
|
825
856
|
}
|
|
826
|
-
async function executeSpaces(parsed, deps = defaultDeps$
|
|
857
|
+
async function executeSpaces(parsed, deps = defaultDeps$13) {
|
|
827
858
|
const env = resolveCommandEnvironment(parsed);
|
|
828
859
|
const showDetails = parsed.options.details === "true";
|
|
829
860
|
const spaceId = parsed.options.id;
|
|
@@ -4962,18 +4993,6 @@ function printMessageDetails(message, type) {
|
|
|
4962
4993
|
}
|
|
4963
4994
|
}
|
|
4964
4995
|
}
|
|
4965
|
-
//#endregion
|
|
4966
|
-
//#region src/cli/commands/upload.ts
|
|
4967
|
-
/**
|
|
4968
|
-
* Upload Command - Upload media to create variants
|
|
4969
|
-
*
|
|
4970
|
-
* Usage:
|
|
4971
|
-
* makefx upload <file> --space <id> --asset <id> Upload to existing asset
|
|
4972
|
-
* makefx upload <file> --space <id> --name <name> Create new asset
|
|
4973
|
-
* makefx upload <file> --space <id> --name <name> --type <type>
|
|
4974
|
-
*/
|
|
4975
|
-
var MAX_FILE_SIZE_MB$1 = 10;
|
|
4976
|
-
var MAX_FILE_SIZE_BYTES$1 = MAX_FILE_SIZE_MB$1 * 1024 * 1024;
|
|
4977
4996
|
var EXT_TO_MEDIA_TYPE = {
|
|
4978
4997
|
".aac": {
|
|
4979
4998
|
mediaKind: "audio",
|
|
@@ -5037,7 +5056,7 @@ var EXT_TO_MEDIA_TYPE = {
|
|
|
5037
5056
|
}
|
|
5038
5057
|
};
|
|
5039
5058
|
var ALLOWED_EXTENSIONS$1 = Object.keys(EXT_TO_MEDIA_TYPE).sort();
|
|
5040
|
-
var defaultDeps$
|
|
5059
|
+
var defaultDeps$12 = {
|
|
5041
5060
|
loadConfig: loadStoredConfig,
|
|
5042
5061
|
loadProjectConfig,
|
|
5043
5062
|
resolveBaseUrl,
|
|
@@ -5052,18 +5071,17 @@ async function handleUpload(parsed) {
|
|
|
5052
5071
|
await executeUpload(parsed);
|
|
5053
5072
|
} catch (error) {
|
|
5054
5073
|
console.error(error instanceof Error ? `Error: ${error.message}` : "Error: Upload failed");
|
|
5055
|
-
if (error instanceof UploadUsageError) printUsage$
|
|
5074
|
+
if (error instanceof UploadUsageError) printUsage$12();
|
|
5056
5075
|
process$1.exitCode = 1;
|
|
5057
5076
|
}
|
|
5058
5077
|
}
|
|
5059
|
-
async function executeUpload(parsed, deps = defaultDeps$
|
|
5078
|
+
async function executeUpload(parsed, deps = defaultDeps$12) {
|
|
5060
5079
|
const projectConfig = await deps.loadProjectConfig();
|
|
5061
5080
|
const env = resolveCommandEnvironment(parsed, projectConfig);
|
|
5062
5081
|
const spaceId = resolveCommandSpace(parsed, projectConfig);
|
|
5063
5082
|
const assetId = parsed.options.asset;
|
|
5064
5083
|
const assetName = parsed.options.name;
|
|
5065
5084
|
const assetType = parsed.options.type || "character";
|
|
5066
|
-
const parentAssetId = parsed.options.parent;
|
|
5067
5085
|
const requestedMediaKind = parsed.options["media-kind"] || parsed.options.mediaKind;
|
|
5068
5086
|
const filePath = parsed.positionals[0];
|
|
5069
5087
|
if (!filePath) throw new UploadUsageError("File path is required");
|
|
@@ -5079,7 +5097,7 @@ async function executeUpload(parsed, deps = defaultDeps$8) {
|
|
|
5079
5097
|
try {
|
|
5080
5098
|
const fileStat = await deps.stat(filePath);
|
|
5081
5099
|
if (!fileStat.isFile()) throw new Error(`"${filePath}" is not a file`);
|
|
5082
|
-
if (fileStat.size >
|
|
5100
|
+
if (fileStat.size > 10485760) throw new Error(`File too large (${(fileStat.size / 1024 / 1024).toFixed(2)}MB). Maximum size: 10MB`);
|
|
5083
5101
|
const fileBuffer = await deps.readFile(filePath);
|
|
5084
5102
|
const fileName = path.basename(filePath);
|
|
5085
5103
|
const formData = new FormData();
|
|
@@ -5090,7 +5108,6 @@ async function executeUpload(parsed, deps = defaultDeps$8) {
|
|
|
5090
5108
|
else {
|
|
5091
5109
|
formData.append("assetName", assetName);
|
|
5092
5110
|
formData.append("assetType", assetType);
|
|
5093
|
-
if (parentAssetId) formData.append("parentAssetId", parentAssetId);
|
|
5094
5111
|
}
|
|
5095
5112
|
deps.print(`\nUploading "${fileName}" to space ${spaceId}...`);
|
|
5096
5113
|
deps.print(` Media kind: ${mediaType.mediaKind}`);
|
|
@@ -5150,7 +5167,7 @@ function resolveMediaType(ext, requestedMediaKind) {
|
|
|
5150
5167
|
if (requestedMediaKind && requestedMediaKind !== mediaType.mediaKind) throw new Error(`--media-kind ${requestedMediaKind} does not match ${ext} (${mediaType.mediaKind})`);
|
|
5151
5168
|
return mediaType;
|
|
5152
5169
|
}
|
|
5153
|
-
function printUsage$
|
|
5170
|
+
function printUsage$12() {
|
|
5154
5171
|
console.log(`
|
|
5155
5172
|
Usage:
|
|
5156
5173
|
makefx upload <file> --asset <id> [--space <id>] Upload media to existing asset
|
|
@@ -5162,7 +5179,6 @@ Options:
|
|
|
5162
5179
|
--name <name> New asset name (creates asset + variant)
|
|
5163
5180
|
--type <type> Asset type for new assets (default: character)
|
|
5164
5181
|
--media-kind <k> Optional explicit kind: image, audio, or video
|
|
5165
|
-
--parent <id> Parent asset ID for new assets
|
|
5166
5182
|
--env <env> Environment (production|stage|local)
|
|
5167
5183
|
--local Shortcut for --env local
|
|
5168
5184
|
|
|
@@ -5171,7 +5187,877 @@ Examples:
|
|
|
5171
5187
|
makefx upload theme.mp3 --space abc123 --name "Theme Music" --type audio
|
|
5172
5188
|
makefx upload cutscene.mp4 --space abc123 --name "Opening Cutscene" --type video
|
|
5173
5189
|
makefx upload variant.jpg --space abc123 --asset def456
|
|
5174
|
-
|
|
5190
|
+
`);
|
|
5191
|
+
}
|
|
5192
|
+
//#endregion
|
|
5193
|
+
//#region src/cli/commands/import.ts
|
|
5194
|
+
var defaultDeps$11 = {
|
|
5195
|
+
loadConfig: loadStoredConfig,
|
|
5196
|
+
loadProjectConfig,
|
|
5197
|
+
resolveBaseUrl,
|
|
5198
|
+
fetch,
|
|
5199
|
+
readFile,
|
|
5200
|
+
stat,
|
|
5201
|
+
print: console.log
|
|
5202
|
+
};
|
|
5203
|
+
async function handleImport(parsed) {
|
|
5204
|
+
try {
|
|
5205
|
+
await executeImport(parsed);
|
|
5206
|
+
} catch (error) {
|
|
5207
|
+
console.error(error instanceof Error ? `Error: ${error.message}` : "Error: Import failed");
|
|
5208
|
+
printUsage$11();
|
|
5209
|
+
process$1.exitCode = 1;
|
|
5210
|
+
}
|
|
5211
|
+
}
|
|
5212
|
+
async function executeImport(parsed, deps = defaultDeps$11) {
|
|
5213
|
+
const manifestPath = parsed.positionals[0] || parsed.options.manifest;
|
|
5214
|
+
if (!manifestPath || manifestPath === "true") throw new Error("Manifest path is required: makefx import <manifest.json>");
|
|
5215
|
+
const ctx = await buildContext$8(parsed, deps);
|
|
5216
|
+
const manifest = await readManifest(manifestPath, deps);
|
|
5217
|
+
await validateLocalRecords(manifest.records, deps);
|
|
5218
|
+
const plan = validateManifestPlan(manifest, await fetchSpaceState(ctx, deps));
|
|
5219
|
+
const uploadOrder = buildUploadOrder(manifest.records);
|
|
5220
|
+
if (parsed.options["dry-run"] === "true" || parsed.options.dryRun === "true") {
|
|
5221
|
+
const result = {
|
|
5222
|
+
dryRun: true,
|
|
5223
|
+
records: uploadOrder.map((record) => ({
|
|
5224
|
+
key: record.localKey,
|
|
5225
|
+
file: record.displayPath,
|
|
5226
|
+
target: record.assetId ?? `new:${record.assetName}`,
|
|
5227
|
+
lineageInputs: record.lineage.length
|
|
5228
|
+
})),
|
|
5229
|
+
collections: plan.collections.map((collection) => ({
|
|
5230
|
+
name: collection.name,
|
|
5231
|
+
create: collection.create
|
|
5232
|
+
})),
|
|
5233
|
+
collectionItems: plan.collectionItems.length,
|
|
5234
|
+
relations: plan.relations.length,
|
|
5235
|
+
compositions: plan.compositions.map((composition) => ({
|
|
5236
|
+
name: composition.name,
|
|
5237
|
+
create: composition.create
|
|
5238
|
+
})),
|
|
5239
|
+
compositionItems: plan.compositionItems.length,
|
|
5240
|
+
stylePresets: plan.stylePresets.map((preset) => ({
|
|
5241
|
+
name: preset.name,
|
|
5242
|
+
action: preset.action
|
|
5243
|
+
}))
|
|
5244
|
+
};
|
|
5245
|
+
printResult$1(result, parsed, deps);
|
|
5246
|
+
return result;
|
|
5247
|
+
}
|
|
5248
|
+
const uploadedByKey = /* @__PURE__ */ new Map();
|
|
5249
|
+
const imported = [];
|
|
5250
|
+
const jsonOutput = parsed.options.json === "true";
|
|
5251
|
+
for (const record of uploadOrder) {
|
|
5252
|
+
const lineage = record.lineage.map((input) => ({
|
|
5253
|
+
parentVariantId: input.sourceVariantId ?? uploadedByKey.get(input.sourceFile)?.variantId,
|
|
5254
|
+
relationType: input.relationType
|
|
5255
|
+
}));
|
|
5256
|
+
if (lineage.find((input) => !input.parentVariantId)) throw new Error(`Could not resolve same-batch lineage for ${record.localKey}`);
|
|
5257
|
+
const response = await uploadRecord(ctx, deps, record, lineage, { quiet: jsonOutput });
|
|
5258
|
+
uploadedByKey.set(record.localKey, {
|
|
5259
|
+
assetId: response.variant.asset_id,
|
|
5260
|
+
variantId: response.variant.id
|
|
5261
|
+
});
|
|
5262
|
+
imported.push({
|
|
5263
|
+
key: record.localKey,
|
|
5264
|
+
file: record.displayPath,
|
|
5265
|
+
assetId: response.variant.asset_id,
|
|
5266
|
+
variantId: response.variant.id,
|
|
5267
|
+
lineageIds: (response.lineage ?? []).map((lineageRecord) => lineageRecord.id)
|
|
5268
|
+
});
|
|
5269
|
+
}
|
|
5270
|
+
const result = {
|
|
5271
|
+
dryRun: false,
|
|
5272
|
+
records: imported,
|
|
5273
|
+
...await applyOrganizationPlan(ctx, deps, plan, uploadedByKey)
|
|
5274
|
+
};
|
|
5275
|
+
printResult$1(result, parsed, deps);
|
|
5276
|
+
return result;
|
|
5277
|
+
}
|
|
5278
|
+
async function buildContext$8(parsed, deps) {
|
|
5279
|
+
const projectConfig = await deps.loadProjectConfig();
|
|
5280
|
+
const env = resolveCommandEnvironment(parsed, projectConfig);
|
|
5281
|
+
const spaceId = resolveCommandSpace(parsed, projectConfig);
|
|
5282
|
+
if (!spaceId) throw new Error("--space is required, or run: makefx init --space <id>");
|
|
5283
|
+
const config = await deps.loadConfig(env);
|
|
5284
|
+
if (!config) throw new Error(`Not logged in to ${env} environment. Run: ${loginCommandForEnvironment(env)}`);
|
|
5285
|
+
if (config.token.expiresAt < Date.now()) throw new Error(`Token expired for ${env} environment. Run: ${loginCommandForEnvironment(env)}`);
|
|
5286
|
+
if (env === "local") process$1.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
|
|
5287
|
+
return {
|
|
5288
|
+
env,
|
|
5289
|
+
spaceId,
|
|
5290
|
+
baseUrl: deps.resolveBaseUrl(env),
|
|
5291
|
+
accessToken: config.token.accessToken
|
|
5292
|
+
};
|
|
5293
|
+
}
|
|
5294
|
+
async function readManifest(manifestPath, deps) {
|
|
5295
|
+
const manifestText = await deps.readFile(manifestPath, "utf8");
|
|
5296
|
+
const manifestDir = path.dirname(path.resolve(manifestPath));
|
|
5297
|
+
let parsed;
|
|
5298
|
+
try {
|
|
5299
|
+
parsed = JSON.parse(manifestText);
|
|
5300
|
+
} catch (error) {
|
|
5301
|
+
throw new Error(`Manifest is not valid JSON: ${error instanceof Error ? error.message : String(error)}`);
|
|
5302
|
+
}
|
|
5303
|
+
const root = Array.isArray(parsed) ? {} : parsed;
|
|
5304
|
+
const rawRecords = Array.isArray(parsed) ? parsed : parsed && typeof parsed === "object" ? root.records ?? root.files : null;
|
|
5305
|
+
if (!Array.isArray(rawRecords)) throw new Error("Manifest must be an array or contain a records/files array");
|
|
5306
|
+
const records = rawRecords.map((raw, index) => normalizeRecord(raw, index, manifestDir));
|
|
5307
|
+
const keys = /* @__PURE__ */ new Set();
|
|
5308
|
+
for (const record of records) {
|
|
5309
|
+
if (keys.has(record.localKey)) throw new Error(`Duplicate local key in manifest: ${record.localKey}`);
|
|
5310
|
+
keys.add(record.localKey);
|
|
5311
|
+
}
|
|
5312
|
+
return {
|
|
5313
|
+
records,
|
|
5314
|
+
collections: normalizeCollections(readArray(root.collections, "collections"), false),
|
|
5315
|
+
styleCollections: normalizeStyleCollections(readArray(root.styleCollections, "styleCollections")),
|
|
5316
|
+
collectionItems: [...records.flatMap((record) => record.collectionItems), ...normalizeCollectionItems(readArray(root.collectionItems, "collectionItems"), "collectionItems")],
|
|
5317
|
+
relations: [...records.flatMap((record) => record.relations), ...normalizeRelations(readArray(root.relations, "relations"), "relations")],
|
|
5318
|
+
compositions: normalizeCompositions(readArray(root.compositions, "compositions")),
|
|
5319
|
+
compositionItems: [...records.flatMap((record) => record.compositionItems), ...normalizeCompositionItems(readArray(root.compositionItems, "compositionItems"), "compositionItems")],
|
|
5320
|
+
stylePresets: normalizeStylePresets(readArray(root.stylePresets, "stylePresets"))
|
|
5321
|
+
};
|
|
5322
|
+
}
|
|
5323
|
+
function normalizeRecord(raw, index, manifestDir) {
|
|
5324
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) throw new Error(`Record ${index + 1} must be an object`);
|
|
5325
|
+
const record = raw;
|
|
5326
|
+
const displayPath = record.file ?? record.path;
|
|
5327
|
+
if (!displayPath) throw new Error(`Record ${index + 1} is missing file`);
|
|
5328
|
+
const filePath = path.resolve(manifestDir, displayPath);
|
|
5329
|
+
const mediaType = resolveMediaType(path.extname(filePath).toLowerCase(), record.mediaKind);
|
|
5330
|
+
const assetId = record.assetId ?? record.targetAssetId;
|
|
5331
|
+
const assetName = record.assetName ?? record.name;
|
|
5332
|
+
if (assetId && assetName) throw new Error(`Record ${index + 1} must set either assetId or name, not both`);
|
|
5333
|
+
if (!assetId && !assetName) throw new Error(`Record ${index + 1} must set assetId for an existing asset or name for a new asset`);
|
|
5334
|
+
const lineage = normalizeLineage(record.lineage ?? [], index);
|
|
5335
|
+
const activeVariantBehavior = normalizeActiveBehavior(record.activeVariantBehavior, index);
|
|
5336
|
+
const providerMetadata = record.providerMetadata ?? record.provider_metadata;
|
|
5337
|
+
const generationProvenance = record.generationProvenance ?? record.generation_provenance ?? {};
|
|
5338
|
+
validateObjectField(providerMetadata, `Record ${index + 1} providerMetadata`);
|
|
5339
|
+
validateObjectField(generationProvenance, `Record ${index + 1} generationProvenance`);
|
|
5340
|
+
const localKey = record.localKey ?? record.key ?? displayPath;
|
|
5341
|
+
return {
|
|
5342
|
+
index,
|
|
5343
|
+
localKey,
|
|
5344
|
+
filePath,
|
|
5345
|
+
displayPath,
|
|
5346
|
+
fileName: path.basename(filePath),
|
|
5347
|
+
assetName,
|
|
5348
|
+
assetType: record.assetType ?? record.type ?? "character",
|
|
5349
|
+
assetId,
|
|
5350
|
+
mediaKind: mediaType.mediaKind,
|
|
5351
|
+
mimeType: mediaType.mimeType,
|
|
5352
|
+
activeVariantBehavior,
|
|
5353
|
+
prompt: record.prompt,
|
|
5354
|
+
model: record.model,
|
|
5355
|
+
provider: record.provider,
|
|
5356
|
+
providerMetadata,
|
|
5357
|
+
generationProvenance,
|
|
5358
|
+
lineage,
|
|
5359
|
+
collectionItems: normalizeCollectionItems([...readArray(record.collections, `Record ${index + 1} collections`), ...readArray(record.collectionItems, `Record ${index + 1} collectionItems`)], `Record ${index + 1} collections`, localKey),
|
|
5360
|
+
relations: normalizeRelations(readArray(record.relations, `Record ${index + 1} relations`), `Record ${index + 1} relations`, localKey),
|
|
5361
|
+
compositionItems: normalizeCompositionItems(readArray(record.compositionItems, `Record ${index + 1} compositionItems`), `Record ${index + 1} compositionItems`, localKey),
|
|
5362
|
+
styleCollections: normalizeStyleCollections(readArray(record.styleCollections, `Record ${index + 1} styleCollections`), localKey)
|
|
5363
|
+
};
|
|
5364
|
+
}
|
|
5365
|
+
function readArray(value, label) {
|
|
5366
|
+
if (value === void 0) return [];
|
|
5367
|
+
if (!Array.isArray(value)) throw new Error(`${label} must be an array`);
|
|
5368
|
+
return value;
|
|
5369
|
+
}
|
|
5370
|
+
function normalizeLineage(inputs, recordIndex) {
|
|
5371
|
+
if (!Array.isArray(inputs)) throw new Error(`Record ${recordIndex + 1} lineage must be an array`);
|
|
5372
|
+
return inputs.map((input, index) => {
|
|
5373
|
+
if (!input || typeof input !== "object" || Array.isArray(input)) throw new Error(`Record ${recordIndex + 1} lineage[${index}] must be an object`);
|
|
5374
|
+
const sourceVariantId = input.sourceVariantId ?? input.parentVariantId;
|
|
5375
|
+
if (sourceVariantId && input.sourceFile || !sourceVariantId && !input.sourceFile) throw new Error(`Record ${recordIndex + 1} lineage[${index}] must set exactly one of sourceVariantId or sourceFile`);
|
|
5376
|
+
if (input.relationType !== "derived" && input.relationType !== "refined" && input.relationType !== "forked") throw new Error(`Record ${recordIndex + 1} lineage[${index}] relationType must be derived, refined, or forked`);
|
|
5377
|
+
return {
|
|
5378
|
+
relationType: input.relationType,
|
|
5379
|
+
...sourceVariantId ? { sourceVariantId } : { sourceFile: input.sourceFile }
|
|
5380
|
+
};
|
|
5381
|
+
});
|
|
5382
|
+
}
|
|
5383
|
+
function normalizeCollections(inputs, styleOnly) {
|
|
5384
|
+
return inputs.map((input, index) => {
|
|
5385
|
+
const collection = requireObject(input, `collections[${index}]`);
|
|
5386
|
+
const name = collection.name ?? collection.collectionName ?? collection.collection;
|
|
5387
|
+
if (!name || typeof name !== "string") throw new Error(`collections[${index}] name is required`);
|
|
5388
|
+
if (collection.description !== void 0 && collection.description !== null && typeof collection.description !== "string") throw new Error(`collections[${index}] description must be a string or null`);
|
|
5389
|
+
validateSortIndex(collection.sortIndex, `collections[${index}] sortIndex`);
|
|
5390
|
+
return {
|
|
5391
|
+
key: collection.id ?? name,
|
|
5392
|
+
name,
|
|
5393
|
+
description: collection.description,
|
|
5394
|
+
sortIndex: collection.sortIndex,
|
|
5395
|
+
create: styleOnly || collection.create === true || collection.createIfMissing === true
|
|
5396
|
+
};
|
|
5397
|
+
});
|
|
5398
|
+
}
|
|
5399
|
+
function normalizeStyleCollections(inputs, recordKey) {
|
|
5400
|
+
return inputs.map((input, index) => {
|
|
5401
|
+
if (typeof input === "string") return {
|
|
5402
|
+
key: input,
|
|
5403
|
+
name: input,
|
|
5404
|
+
create: false,
|
|
5405
|
+
refs: recordKey ? [recordKey] : []
|
|
5406
|
+
};
|
|
5407
|
+
const collection = requireObject(input, labelFor("styleCollections", index, recordKey));
|
|
5408
|
+
const name = collection.name ?? collection.collectionName ?? collection.collection;
|
|
5409
|
+
if (!name || typeof name !== "string") throw new Error(`${labelFor("styleCollections", index, recordKey)} name is required`);
|
|
5410
|
+
validateSortIndex(collection.sortIndex, `${labelFor("styleCollections", index, recordKey)} sortIndex`);
|
|
5411
|
+
const refs = [
|
|
5412
|
+
...collection.refs ?? [],
|
|
5413
|
+
...collection.records ?? [],
|
|
5414
|
+
...recordKey ? [recordKey] : []
|
|
5415
|
+
];
|
|
5416
|
+
if (!refs.every((ref) => typeof ref === "string" && ref.trim())) throw new Error(`${labelFor("styleCollections", index, recordKey)} refs must be strings`);
|
|
5417
|
+
return {
|
|
5418
|
+
key: collection.id ?? name,
|
|
5419
|
+
name,
|
|
5420
|
+
description: collection.description,
|
|
5421
|
+
sortIndex: collection.sortIndex,
|
|
5422
|
+
create: collection.create === true || collection.createIfMissing === true,
|
|
5423
|
+
refs
|
|
5424
|
+
};
|
|
5425
|
+
});
|
|
5426
|
+
}
|
|
5427
|
+
function normalizeCollectionItems(inputs, label, defaultRecordKey) {
|
|
5428
|
+
return inputs.map((input, index) => {
|
|
5429
|
+
const item = requireObject(input, `${label}[${index}]`);
|
|
5430
|
+
const collectionName = item.collectionName ?? item.collection ?? item.collectionId;
|
|
5431
|
+
if (!collectionName || typeof collectionName !== "string") throw new Error(`${label}[${index}] collection is required`);
|
|
5432
|
+
if (item.role !== void 0 && typeof item.role !== "string") throw new Error(`${label}[${index}] role must be a string`);
|
|
5433
|
+
const subjectType = normalizeSubjectType(item.subjectType ?? (item.variantId ? "variant" : "asset"), `${label}[${index}] subjectType`);
|
|
5434
|
+
const recordKey = item.recordKey ?? item.sourceFile ?? defaultRecordKey;
|
|
5435
|
+
validateSortIndex(item.sortIndex, `${label}[${index}] sortIndex`);
|
|
5436
|
+
if (item.pinnedVariantId !== void 0 && item.pinnedVariantId !== null && typeof item.pinnedVariantId !== "string") throw new Error(`${label}[${index}] pinnedVariantId must be a string or null`);
|
|
5437
|
+
return {
|
|
5438
|
+
id: item.id,
|
|
5439
|
+
collectionName,
|
|
5440
|
+
role: item.role ?? "member",
|
|
5441
|
+
subjectType,
|
|
5442
|
+
assetId: item.assetId,
|
|
5443
|
+
variantId: item.variantId,
|
|
5444
|
+
recordKey,
|
|
5445
|
+
pinnedVariantId: item.pinnedVariantId,
|
|
5446
|
+
pinnedVariantBehavior: normalizePinnedVariantBehavior(item.pinnedVariantBehavior, `${label}[${index}] pinnedVariantBehavior`),
|
|
5447
|
+
sortIndex: item.sortIndex
|
|
5448
|
+
};
|
|
5449
|
+
});
|
|
5450
|
+
}
|
|
5451
|
+
function normalizeRelations(inputs, label, defaultSubjectRecordKey) {
|
|
5452
|
+
return inputs.map((input, index) => {
|
|
5453
|
+
const relation = requireObject(input, `${label}[${index}]`);
|
|
5454
|
+
const subject = relation.subject ? normalizeSubject(relation.subject, `${label}[${index}] subject`) : normalizeSubject({
|
|
5455
|
+
subjectType: relation.subjectType,
|
|
5456
|
+
assetId: relation.subjectAssetId,
|
|
5457
|
+
variantId: relation.subjectVariantId,
|
|
5458
|
+
recordKey: defaultSubjectRecordKey
|
|
5459
|
+
}, `${label}[${index}] subject`);
|
|
5460
|
+
const object = normalizeSubject(relation.object ?? relation.target ?? {
|
|
5461
|
+
subjectType: relation.objectType,
|
|
5462
|
+
assetId: relation.objectAssetId,
|
|
5463
|
+
variantId: relation.objectVariantId
|
|
5464
|
+
}, `${label}[${index}] object`);
|
|
5465
|
+
const relationType = normalizeRelationType(relation.relationType, `${label}[${index}] relationType`);
|
|
5466
|
+
validateObjectField(relation.metadata, `${label}[${index}] metadata`);
|
|
5467
|
+
validateSortIndex(relation.sortIndex, `${label}[${index}] sortIndex`);
|
|
5468
|
+
if (relation.label !== void 0 && relation.label !== null && typeof relation.label !== "string") throw new Error(`${label}[${index}] label must be a string or null`);
|
|
5469
|
+
if (relation.context !== void 0 && relation.context !== null && typeof relation.context !== "string" && (typeof relation.context !== "object" || Array.isArray(relation.context))) throw new Error(`${label}[${index}] context must be a string, object, or null`);
|
|
5470
|
+
return {
|
|
5471
|
+
id: relation.id,
|
|
5472
|
+
subject,
|
|
5473
|
+
object,
|
|
5474
|
+
relationType,
|
|
5475
|
+
label: relation.label,
|
|
5476
|
+
context: relation.context,
|
|
5477
|
+
metadata: relation.metadata,
|
|
5478
|
+
sortIndex: relation.sortIndex
|
|
5479
|
+
};
|
|
5480
|
+
});
|
|
5481
|
+
}
|
|
5482
|
+
function normalizeCompositions(inputs) {
|
|
5483
|
+
return inputs.map((input, index) => {
|
|
5484
|
+
const composition = requireObject(input, `compositions[${index}]`);
|
|
5485
|
+
const name = composition.name ?? composition.compositionName ?? composition.composition;
|
|
5486
|
+
if (!name || typeof name !== "string") throw new Error(`compositions[${index}] name is required`);
|
|
5487
|
+
if (composition.description !== void 0 && composition.description !== null && typeof composition.description !== "string") throw new Error(`compositions[${index}] description must be a string or null`);
|
|
5488
|
+
validateObjectField(composition.metadata, `compositions[${index}] metadata`);
|
|
5489
|
+
validateSortIndex(composition.sortIndex, `compositions[${index}] sortIndex`);
|
|
5490
|
+
const output = composition.output ? normalizeSubject(composition.output, `compositions[${index}] output`) : composition.outputRecordKey || composition.outputAssetId || composition.outputVariantId ? normalizeSubject({
|
|
5491
|
+
subjectType: composition.outputVariantId || composition.outputRecordKey ? "variant" : "asset",
|
|
5492
|
+
assetId: composition.outputAssetId ?? void 0,
|
|
5493
|
+
variantId: composition.outputVariantId ?? void 0,
|
|
5494
|
+
recordKey: composition.outputRecordKey
|
|
5495
|
+
}, `compositions[${index}] output`) : void 0;
|
|
5496
|
+
return {
|
|
5497
|
+
key: composition.id ?? name,
|
|
5498
|
+
name,
|
|
5499
|
+
description: composition.description,
|
|
5500
|
+
status: normalizeCompositionStatus(composition.status, `compositions[${index}] status`),
|
|
5501
|
+
output,
|
|
5502
|
+
metadata: composition.metadata,
|
|
5503
|
+
sortIndex: composition.sortIndex,
|
|
5504
|
+
create: composition.create === true || composition.createIfMissing === true
|
|
5505
|
+
};
|
|
5506
|
+
});
|
|
5507
|
+
}
|
|
5508
|
+
function normalizeCompositionItems(inputs, label, defaultRecordKey) {
|
|
5509
|
+
return inputs.map((input, index) => {
|
|
5510
|
+
const item = requireObject(input, `${label}[${index}]`);
|
|
5511
|
+
const compositionName = item.compositionName ?? item.composition ?? item.compositionId;
|
|
5512
|
+
if (!compositionName || typeof compositionName !== "string") throw new Error(`${label}[${index}] composition is required`);
|
|
5513
|
+
const role = normalizeCompositionItemRole(item.role, `${label}[${index}] role`);
|
|
5514
|
+
validateObjectField(item.metadata, `${label}[${index}] metadata`);
|
|
5515
|
+
validateSortIndex(item.sortIndex, `${label}[${index}] sortIndex`);
|
|
5516
|
+
if (item.label !== void 0 && item.label !== null && typeof item.label !== "string") throw new Error(`${label}[${index}] label must be a string or null`);
|
|
5517
|
+
return {
|
|
5518
|
+
id: item.id,
|
|
5519
|
+
compositionName,
|
|
5520
|
+
role,
|
|
5521
|
+
label: item.label,
|
|
5522
|
+
assetId: item.assetId,
|
|
5523
|
+
variantId: item.variantId,
|
|
5524
|
+
recordKey: item.recordKey ?? item.sourceFile ?? defaultRecordKey,
|
|
5525
|
+
metadata: item.metadata,
|
|
5526
|
+
sortIndex: item.sortIndex
|
|
5527
|
+
};
|
|
5528
|
+
});
|
|
5529
|
+
}
|
|
5530
|
+
function normalizeStylePresets(inputs) {
|
|
5531
|
+
return inputs.map((input, index) => {
|
|
5532
|
+
const preset = requireObject(input, `stylePresets[${index}]`);
|
|
5533
|
+
const name = preset.name ?? preset.presetName;
|
|
5534
|
+
if (!name || typeof name !== "string") throw new Error(`stylePresets[${index}] name is required`);
|
|
5535
|
+
const stylePrompt = preset.stylePrompt ?? preset.prompt;
|
|
5536
|
+
if (stylePrompt !== void 0 && typeof stylePrompt !== "string") throw new Error(`stylePresets[${index}] stylePrompt must be a string`);
|
|
5537
|
+
if (preset.description !== void 0 && preset.description !== null && typeof preset.description !== "string") throw new Error(`stylePresets[${index}] description must be a string or null`);
|
|
5538
|
+
if ([
|
|
5539
|
+
preset.create,
|
|
5540
|
+
preset.update,
|
|
5541
|
+
preset.upsert
|
|
5542
|
+
].filter((value) => value === true).length !== 1) throw new Error(`stylePresets[${index}] must set exactly one of create, update, or upsert`);
|
|
5543
|
+
return {
|
|
5544
|
+
id: preset.id,
|
|
5545
|
+
name,
|
|
5546
|
+
description: preset.description,
|
|
5547
|
+
stylePrompt,
|
|
5548
|
+
collectionName: preset.collectionName ?? preset.collection ?? void 0,
|
|
5549
|
+
collectionId: preset.collectionId,
|
|
5550
|
+
enabled: preset.enabled,
|
|
5551
|
+
isDefault: preset.isDefault ?? preset.default,
|
|
5552
|
+
action: preset.create ? "create" : preset.update ? "update" : "upsert"
|
|
5553
|
+
};
|
|
5554
|
+
});
|
|
5555
|
+
}
|
|
5556
|
+
function normalizeSubject(input, label) {
|
|
5557
|
+
const subjectType = normalizeSubjectType(input.subjectType ?? input.type ?? (input.assetId ? "asset" : "variant"), `${label} subjectType`);
|
|
5558
|
+
const recordKey = input.recordKey ?? input.sourceFile;
|
|
5559
|
+
if (subjectType === "asset" && input.variantId && !recordKey && !input.assetId) throw new Error(`${label} asset subject must use assetId or recordKey`);
|
|
5560
|
+
if (subjectType === "variant" && input.assetId && !input.variantId && !recordKey) throw new Error(`${label} variant subject must use variantId or recordKey`);
|
|
5561
|
+
return {
|
|
5562
|
+
subjectType,
|
|
5563
|
+
assetId: input.assetId,
|
|
5564
|
+
variantId: input.variantId,
|
|
5565
|
+
recordKey
|
|
5566
|
+
};
|
|
5567
|
+
}
|
|
5568
|
+
function normalizeSubjectType(value, label) {
|
|
5569
|
+
if (value === "asset" || value === "variant") return value;
|
|
5570
|
+
throw new Error(`${label} must be asset or variant`);
|
|
5571
|
+
}
|
|
5572
|
+
function normalizeRelationType(value, label) {
|
|
5573
|
+
if ([
|
|
5574
|
+
"appears_in",
|
|
5575
|
+
"background_for",
|
|
5576
|
+
"style_reference_for",
|
|
5577
|
+
"thumbnail_for",
|
|
5578
|
+
"alternate_of",
|
|
5579
|
+
"prop_in",
|
|
5580
|
+
"map_for",
|
|
5581
|
+
"part_of",
|
|
5582
|
+
"reference_for",
|
|
5583
|
+
"custom"
|
|
5584
|
+
].includes(value)) return value;
|
|
5585
|
+
throw new Error(`${label} is invalid`);
|
|
5586
|
+
}
|
|
5587
|
+
function normalizeCompositionItemRole(value, label) {
|
|
5588
|
+
if ([
|
|
5589
|
+
"output",
|
|
5590
|
+
"background",
|
|
5591
|
+
"character",
|
|
5592
|
+
"prop",
|
|
5593
|
+
"style_ref",
|
|
5594
|
+
"overlay",
|
|
5595
|
+
"map",
|
|
5596
|
+
"thumbnail",
|
|
5597
|
+
"custom"
|
|
5598
|
+
].includes(value)) return value;
|
|
5599
|
+
throw new Error(`${label} is invalid`);
|
|
5600
|
+
}
|
|
5601
|
+
function normalizeCompositionStatus(value, label) {
|
|
5602
|
+
if (value === void 0) return void 0;
|
|
5603
|
+
if (value === "draft" || value === "final") return value;
|
|
5604
|
+
throw new Error(`${label} must be draft or final`);
|
|
5605
|
+
}
|
|
5606
|
+
function normalizePinnedVariantBehavior(value, label) {
|
|
5607
|
+
if (!value || value === "imported") return "imported";
|
|
5608
|
+
if (value === "none" || value === "unpin") return "none";
|
|
5609
|
+
throw new Error(`${label} must be imported or none`);
|
|
5610
|
+
}
|
|
5611
|
+
function requireObject(value, label) {
|
|
5612
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error(`${label} must be an object`);
|
|
5613
|
+
return value;
|
|
5614
|
+
}
|
|
5615
|
+
function validateSortIndex(value, label) {
|
|
5616
|
+
if (value !== void 0 && !Number.isInteger(value)) throw new Error(`${label} must be an integer`);
|
|
5617
|
+
}
|
|
5618
|
+
function labelFor(section, index, recordKey) {
|
|
5619
|
+
return recordKey ? `Record ${recordKey} ${section}[${index}]` : `${section}[${index}]`;
|
|
5620
|
+
}
|
|
5621
|
+
function normalizeActiveBehavior(value, recordIndex) {
|
|
5622
|
+
if (!value || value === "if-missing" || value === "if_missing") return "if-missing";
|
|
5623
|
+
if (value === "set-active" || value === "set_active") return "set-active";
|
|
5624
|
+
if (value === "keep") return "keep";
|
|
5625
|
+
throw new Error(`Record ${recordIndex + 1} activeVariantBehavior must be if-missing, set-active, or keep`);
|
|
5626
|
+
}
|
|
5627
|
+
function validateObjectField(value, label) {
|
|
5628
|
+
if (value === void 0) return;
|
|
5629
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error(`${label} must be an object`);
|
|
5630
|
+
}
|
|
5631
|
+
async function validateLocalRecords(records, deps) {
|
|
5632
|
+
for (const record of records) {
|
|
5633
|
+
let fileStat;
|
|
5634
|
+
try {
|
|
5635
|
+
fileStat = await deps.stat(record.filePath);
|
|
5636
|
+
} catch (error) {
|
|
5637
|
+
if (error.code === "ENOENT") throw new Error(`File not found for ${record.localKey}: ${record.displayPath}`);
|
|
5638
|
+
throw error;
|
|
5639
|
+
}
|
|
5640
|
+
if (!fileStat.isFile()) throw new Error(`Manifest file is not a file for ${record.localKey}: ${record.displayPath}`);
|
|
5641
|
+
if (fileStat.size > 10485760) throw new Error(`File too large for ${record.localKey} (${(fileStat.size / 1024 / 1024).toFixed(2)}MB). Maximum size: 10MB`);
|
|
5642
|
+
}
|
|
5643
|
+
}
|
|
5644
|
+
async function fetchSpaceState(ctx, deps) {
|
|
5645
|
+
const [assetsData, collectionsData, compositionsData, stylePresetsData] = await Promise.all([
|
|
5646
|
+
fetchJson$1(ctx, deps, `/api/spaces/${ctx.spaceId}/assets`),
|
|
5647
|
+
fetchJson$1(ctx, deps, `/api/spaces/${ctx.spaceId}/collections`),
|
|
5648
|
+
fetchJson$1(ctx, deps, `/api/spaces/${ctx.spaceId}/compositions`),
|
|
5649
|
+
fetchJson$1(ctx, deps, `/api/spaces/${ctx.spaceId}/style-presets`)
|
|
5650
|
+
]);
|
|
5651
|
+
const assets = assetsData.assets ?? [];
|
|
5652
|
+
const variantsById = /* @__PURE__ */ new Map();
|
|
5653
|
+
for (const asset of assets) {
|
|
5654
|
+
const details = await fetchJson$1(ctx, deps, `/api/spaces/${ctx.spaceId}/assets/${encodeURIComponent(asset.id)}`);
|
|
5655
|
+
for (const variant of details.variants ?? []) variantsById.set(variant.id, variant);
|
|
5656
|
+
}
|
|
5657
|
+
return {
|
|
5658
|
+
assets,
|
|
5659
|
+
variantsById,
|
|
5660
|
+
collections: collectionsData.collections ?? [],
|
|
5661
|
+
compositions: compositionsData.compositions ?? [],
|
|
5662
|
+
stylePresets: stylePresetsData.presets ?? []
|
|
5663
|
+
};
|
|
5664
|
+
}
|
|
5665
|
+
function validateSpaceReferences(records, state) {
|
|
5666
|
+
const assetsById = new Map(state.assets.map((asset) => [asset.id, asset]));
|
|
5667
|
+
const recordsByKey = new Map(records.map((record) => [record.localKey, record]));
|
|
5668
|
+
for (const record of records) {
|
|
5669
|
+
if (record.assetId) {
|
|
5670
|
+
const asset = assetsById.get(record.assetId);
|
|
5671
|
+
if (!asset) throw new Error(`Target asset not found for ${record.localKey}: ${record.assetId}`);
|
|
5672
|
+
if (asset.media_kind && asset.media_kind !== record.mediaKind) throw new Error(`Target asset ${record.assetId} is ${asset.media_kind}, but ${record.localKey} is ${record.mediaKind}`);
|
|
5673
|
+
}
|
|
5674
|
+
for (const lineage of record.lineage) {
|
|
5675
|
+
if (lineage.sourceVariantId && !state.variantsById.has(lineage.sourceVariantId)) throw new Error(`Source variant not found in space for ${record.localKey}: ${lineage.sourceVariantId}`);
|
|
5676
|
+
if (lineage.sourceFile) {
|
|
5677
|
+
const sourceRecord = recordsByKey.get(lineage.sourceFile);
|
|
5678
|
+
if (!sourceRecord) throw new Error(`Source file key not found for ${record.localKey}: ${lineage.sourceFile}`);
|
|
5679
|
+
if (sourceRecord.localKey === record.localKey) throw new Error(`Record ${record.localKey} cannot use itself as a lineage source`);
|
|
5680
|
+
}
|
|
5681
|
+
}
|
|
5682
|
+
}
|
|
5683
|
+
}
|
|
5684
|
+
function validateManifestPlan(manifest, state) {
|
|
5685
|
+
validateSpaceReferences(manifest.records, state);
|
|
5686
|
+
const recordsByKey = new Map(manifest.records.map((record) => [record.localKey, record]));
|
|
5687
|
+
const collectionsByName = new Map(state.collections.map((collection) => [collection.name, collection]));
|
|
5688
|
+
const compositionsByName = new Map(state.compositions.map((composition) => [composition.name, composition]));
|
|
5689
|
+
const stylePresetsByName = new Map(state.stylePresets.map((preset) => [preset.name, preset]));
|
|
5690
|
+
const stylePresetsById = new Map(state.stylePresets.map((preset) => [preset.id, preset]));
|
|
5691
|
+
const collections = dedupeCollections([
|
|
5692
|
+
...manifest.collections,
|
|
5693
|
+
...manifest.styleCollections,
|
|
5694
|
+
...manifest.records.flatMap((record) => record.styleCollections)
|
|
5695
|
+
]);
|
|
5696
|
+
const collectionItems = [
|
|
5697
|
+
...manifest.collectionItems,
|
|
5698
|
+
...manifest.styleCollections.flatMap((collection) => styleCollectionItems(collection)),
|
|
5699
|
+
...manifest.records.flatMap((record) => record.styleCollections.flatMap((collection) => styleCollectionItems(collection)))
|
|
5700
|
+
];
|
|
5701
|
+
const compositions = dedupeCompositions(manifest.compositions);
|
|
5702
|
+
const compositionItems = manifest.compositionItems;
|
|
5703
|
+
for (const collection of collections) if (!collectionsByName.has(collection.name) && !collection.create) throw new Error(`Collection not found: ${collection.name}. Add it to manifest collections with create: true.`);
|
|
5704
|
+
for (const item of collectionItems) {
|
|
5705
|
+
if (!collectionsByName.has(item.collectionName) && !collections.some((collection) => collection.name === item.collectionName && collection.create)) throw new Error(`Collection not found for collection item: ${item.collectionName}`);
|
|
5706
|
+
validateCollectionSubject(item, recordsByKey, state);
|
|
5707
|
+
}
|
|
5708
|
+
for (const relation of manifest.relations) {
|
|
5709
|
+
validateSubjectReference(relation.subject, recordsByKey, state, "Relation subject");
|
|
5710
|
+
validateSubjectReference(relation.object, recordsByKey, state, "Relation object");
|
|
5711
|
+
}
|
|
5712
|
+
for (const composition of compositions) {
|
|
5713
|
+
if (!compositionsByName.has(composition.name) && !composition.create) throw new Error(`Composition not found: ${composition.name}. Add it to manifest compositions with create: true.`);
|
|
5714
|
+
if (composition.output) {
|
|
5715
|
+
validateSubjectReference(composition.output, recordsByKey, state, `Composition ${composition.name} output`);
|
|
5716
|
+
if (composition.output.subjectType !== "variant") throw new Error(`Composition ${composition.name} output must reference a variant`);
|
|
5717
|
+
}
|
|
5718
|
+
}
|
|
5719
|
+
for (const item of compositionItems) {
|
|
5720
|
+
if (!compositionsByName.has(item.compositionName) && !compositions.some((composition) => composition.name === item.compositionName && composition.create)) throw new Error(`Composition not found for composition item: ${item.compositionName}`);
|
|
5721
|
+
if (item.recordKey) {
|
|
5722
|
+
if (!recordsByKey.has(item.recordKey)) throw new Error(`Composition item references unknown same-batch record: ${item.recordKey}`);
|
|
5723
|
+
} else if (!item.variantId) throw new Error(`Composition item for ${item.compositionName} must set variantId or recordKey`);
|
|
5724
|
+
else if (!state.variantsById.has(item.variantId)) throw new Error(`Composition item references unknown variant: ${item.variantId}`);
|
|
5725
|
+
if (item.assetId && !state.assets.some((asset) => asset.id === item.assetId)) throw new Error(`Composition item references unknown asset: ${item.assetId}`);
|
|
5726
|
+
}
|
|
5727
|
+
for (const preset of manifest.stylePresets) {
|
|
5728
|
+
const existingPresetById = preset.id ? stylePresetsById.get(preset.id) : void 0;
|
|
5729
|
+
const existingPresetByName = stylePresetsByName.get(preset.name);
|
|
5730
|
+
const existingPreset = preset.id ? existingPresetById : existingPresetByName;
|
|
5731
|
+
const createConflict = preset.id ? existingPresetById ?? existingPresetByName : existingPresetByName;
|
|
5732
|
+
if (preset.action === "create" && createConflict) throw new Error(`Style preset already exists: ${preset.name}`);
|
|
5733
|
+
if (preset.action === "update" && !existingPreset) throw new Error(`Style preset not found for update: ${preset.id ?? preset.name}`);
|
|
5734
|
+
if (preset.collectionName) {
|
|
5735
|
+
const willCreate = collections.some((collection) => collection.name === preset.collectionName && collection.create);
|
|
5736
|
+
if (!collectionsByName.has(preset.collectionName) && !willCreate) throw new Error(`Style preset ${preset.name} references missing collection: ${preset.collectionName}`);
|
|
5737
|
+
}
|
|
5738
|
+
}
|
|
5739
|
+
return {
|
|
5740
|
+
...manifest,
|
|
5741
|
+
collections,
|
|
5742
|
+
collectionItems,
|
|
5743
|
+
compositions,
|
|
5744
|
+
compositionItems
|
|
5745
|
+
};
|
|
5746
|
+
}
|
|
5747
|
+
function dedupeCollections(collections) {
|
|
5748
|
+
const byName = /* @__PURE__ */ new Map();
|
|
5749
|
+
for (const collection of collections) {
|
|
5750
|
+
const existing = byName.get(collection.name);
|
|
5751
|
+
byName.set(collection.name, {
|
|
5752
|
+
key: collection.key,
|
|
5753
|
+
name: collection.name,
|
|
5754
|
+
description: collection.description ?? existing?.description,
|
|
5755
|
+
sortIndex: collection.sortIndex ?? existing?.sortIndex,
|
|
5756
|
+
create: Boolean(existing?.create || collection.create)
|
|
5757
|
+
});
|
|
5758
|
+
}
|
|
5759
|
+
return [...byName.values()];
|
|
5760
|
+
}
|
|
5761
|
+
function dedupeCompositions(compositions) {
|
|
5762
|
+
const byName = /* @__PURE__ */ new Map();
|
|
5763
|
+
for (const composition of compositions) {
|
|
5764
|
+
const existing = byName.get(composition.name);
|
|
5765
|
+
byName.set(composition.name, {
|
|
5766
|
+
...existing,
|
|
5767
|
+
...composition,
|
|
5768
|
+
create: Boolean(existing?.create || composition.create)
|
|
5769
|
+
});
|
|
5770
|
+
}
|
|
5771
|
+
return [...byName.values()];
|
|
5772
|
+
}
|
|
5773
|
+
function styleCollectionItems(collection) {
|
|
5774
|
+
return collection.refs.map((recordKey, index) => ({
|
|
5775
|
+
collectionName: collection.name,
|
|
5776
|
+
role: "style_ref",
|
|
5777
|
+
subjectType: "asset",
|
|
5778
|
+
recordKey,
|
|
5779
|
+
pinnedVariantBehavior: "imported",
|
|
5780
|
+
sortIndex: index
|
|
5781
|
+
}));
|
|
5782
|
+
}
|
|
5783
|
+
function validateCollectionSubject(item, recordsByKey, state) {
|
|
5784
|
+
if (item.recordKey) {
|
|
5785
|
+
if (!recordsByKey.has(item.recordKey)) throw new Error(`Collection item references unknown same-batch record: ${item.recordKey}`);
|
|
5786
|
+
return;
|
|
5787
|
+
}
|
|
5788
|
+
if (item.subjectType === "asset") {
|
|
5789
|
+
if (!item.assetId) throw new Error(`Collection item for ${item.collectionName} must set assetId or recordKey`);
|
|
5790
|
+
if (!state.assets.some((asset) => asset.id === item.assetId)) throw new Error(`Collection item references unknown asset: ${item.assetId}`);
|
|
5791
|
+
if (item.pinnedVariantId && !state.variantsById.has(item.pinnedVariantId)) throw new Error(`Collection item references unknown pinned variant: ${item.pinnedVariantId}`);
|
|
5792
|
+
return;
|
|
5793
|
+
}
|
|
5794
|
+
if (!item.variantId) throw new Error(`Collection item for ${item.collectionName} must set variantId or recordKey`);
|
|
5795
|
+
if (!state.variantsById.has(item.variantId)) throw new Error(`Collection item references unknown variant: ${item.variantId}`);
|
|
5796
|
+
}
|
|
5797
|
+
function validateSubjectReference(subject, recordsByKey, state, label) {
|
|
5798
|
+
if (subject.recordKey) {
|
|
5799
|
+
if (!recordsByKey.has(subject.recordKey)) throw new Error(`${label} references unknown same-batch record: ${subject.recordKey}`);
|
|
5800
|
+
return;
|
|
5801
|
+
}
|
|
5802
|
+
if (subject.subjectType === "asset") {
|
|
5803
|
+
if (!subject.assetId) throw new Error(`${label} must set assetId or recordKey`);
|
|
5804
|
+
if (!state.assets.some((asset) => asset.id === subject.assetId)) throw new Error(`${label} references unknown asset: ${subject.assetId}`);
|
|
5805
|
+
return;
|
|
5806
|
+
}
|
|
5807
|
+
if (!subject.variantId) throw new Error(`${label} must set variantId or recordKey`);
|
|
5808
|
+
if (!state.variantsById.has(subject.variantId)) throw new Error(`${label} references unknown variant: ${subject.variantId}`);
|
|
5809
|
+
}
|
|
5810
|
+
function buildUploadOrder(records) {
|
|
5811
|
+
const pending = new Map(records.map((record) => [record.localKey, record]));
|
|
5812
|
+
const uploaded = /* @__PURE__ */ new Set();
|
|
5813
|
+
const order = [];
|
|
5814
|
+
while (pending.size > 0) {
|
|
5815
|
+
let progressed = false;
|
|
5816
|
+
for (const [key, record] of pending) {
|
|
5817
|
+
if (!record.lineage.every((lineage) => !lineage.sourceFile || uploaded.has(lineage.sourceFile))) continue;
|
|
5818
|
+
order.push(record);
|
|
5819
|
+
uploaded.add(key);
|
|
5820
|
+
pending.delete(key);
|
|
5821
|
+
progressed = true;
|
|
5822
|
+
}
|
|
5823
|
+
if (!progressed) throw new Error(`Same-batch lineage contains a cycle or unresolved dependency: ${[...pending.keys()].join(", ")}`);
|
|
5824
|
+
}
|
|
5825
|
+
return order;
|
|
5826
|
+
}
|
|
5827
|
+
async function uploadRecord(ctx, deps, record, lineage, options) {
|
|
5828
|
+
const fileBuffer = await deps.readFile(record.filePath);
|
|
5829
|
+
const formData = new FormData();
|
|
5830
|
+
formData.append("file", new Blob([fileBuffer], { type: record.mimeType }), record.fileName);
|
|
5831
|
+
formData.append("operation", "import");
|
|
5832
|
+
formData.append("mediaKind", record.mediaKind);
|
|
5833
|
+
formData.append("assetType", record.assetType);
|
|
5834
|
+
formData.append("activeVariantBehavior", record.activeVariantBehavior);
|
|
5835
|
+
formData.append("generationProvenance", JSON.stringify(record.generationProvenance));
|
|
5836
|
+
if (record.assetId) formData.append("assetId", record.assetId);
|
|
5837
|
+
else formData.append("assetName", record.assetName);
|
|
5838
|
+
if (record.prompt) formData.append("prompt", record.prompt);
|
|
5839
|
+
if (record.model) formData.append("model", record.model);
|
|
5840
|
+
if (record.provider) formData.append("provider", record.provider);
|
|
5841
|
+
if (record.providerMetadata) formData.append("providerMetadata", JSON.stringify(record.providerMetadata));
|
|
5842
|
+
if (lineage.length > 0) formData.append("lineage", JSON.stringify(lineage));
|
|
5843
|
+
if (!options.quiet) deps.print(`Importing ${record.displayPath}...`);
|
|
5844
|
+
const response = await deps.fetch(`${ctx.baseUrl}/api/spaces/${ctx.spaceId}/upload`, {
|
|
5845
|
+
method: "POST",
|
|
5846
|
+
headers: { Authorization: `Bearer ${ctx.accessToken}` },
|
|
5847
|
+
body: formData
|
|
5848
|
+
});
|
|
5849
|
+
const data = await response.json();
|
|
5850
|
+
if (!response.ok) throw new Error(`Import failed for ${record.localKey}: ${"error" in data ? data.error : response.statusText}`);
|
|
5851
|
+
return data;
|
|
5852
|
+
}
|
|
5853
|
+
async function applyOrganizationPlan(ctx, deps, plan, uploadedByKey) {
|
|
5854
|
+
const collectionIds = [];
|
|
5855
|
+
const collectionItemIds = [];
|
|
5856
|
+
const relationIds = [];
|
|
5857
|
+
const compositionIds = [];
|
|
5858
|
+
const compositionItemIds = [];
|
|
5859
|
+
const stylePresetIds = [];
|
|
5860
|
+
const collections = await fetchJson$1(ctx, deps, `/api/spaces/${ctx.spaceId}/collections`);
|
|
5861
|
+
const collectionsByName = new Map((collections.collections ?? []).map((collection) => [collection.name, collection]));
|
|
5862
|
+
for (const collection of plan.collections) if (!collectionsByName.has(collection.name) && collection.create) {
|
|
5863
|
+
const created = await postJson(ctx, deps, `/api/spaces/${ctx.spaceId}/collections`, {
|
|
5864
|
+
name: collection.name,
|
|
5865
|
+
description: collection.description,
|
|
5866
|
+
sortIndex: collection.sortIndex
|
|
5867
|
+
});
|
|
5868
|
+
collectionsByName.set(created.collection.name, created.collection);
|
|
5869
|
+
collectionIds.push(created.collection.id);
|
|
5870
|
+
}
|
|
5871
|
+
for (const item of plan.collectionItems) {
|
|
5872
|
+
const collection = collectionsByName.get(item.collectionName);
|
|
5873
|
+
if (!collection) throw new Error(`Collection not found during import: ${item.collectionName}`);
|
|
5874
|
+
const created = await postJson(ctx, deps, `/api/spaces/${ctx.spaceId}/collections/${encodeURIComponent(collection.id)}/items`, resolveCollectionItemRequest(item, uploadedByKey));
|
|
5875
|
+
collectionItemIds.push(created.item.id);
|
|
5876
|
+
}
|
|
5877
|
+
for (const relation of plan.relations) {
|
|
5878
|
+
const created = await postJson(ctx, deps, `/api/spaces/${ctx.spaceId}/relations`, {
|
|
5879
|
+
id: relation.id,
|
|
5880
|
+
subject: resolveSubject(relation.subject, uploadedByKey),
|
|
5881
|
+
object: resolveSubject(relation.object, uploadedByKey),
|
|
5882
|
+
relationType: relation.relationType,
|
|
5883
|
+
label: relation.label,
|
|
5884
|
+
context: relation.context,
|
|
5885
|
+
metadata: relation.metadata,
|
|
5886
|
+
sortIndex: relation.sortIndex
|
|
5887
|
+
});
|
|
5888
|
+
relationIds.push(created.relation.id);
|
|
5889
|
+
}
|
|
5890
|
+
const compositions = await fetchJson$1(ctx, deps, `/api/spaces/${ctx.spaceId}/compositions`);
|
|
5891
|
+
const compositionsByName = new Map((compositions.compositions ?? []).map((composition) => [composition.name, composition]));
|
|
5892
|
+
for (const composition of plan.compositions) if (!compositionsByName.has(composition.name) && composition.create) {
|
|
5893
|
+
const output = composition.output ? resolveSubject(composition.output, uploadedByKey) : void 0;
|
|
5894
|
+
const created = await postJson(ctx, deps, `/api/spaces/${ctx.spaceId}/compositions`, {
|
|
5895
|
+
name: composition.name,
|
|
5896
|
+
description: composition.description,
|
|
5897
|
+
status: composition.status,
|
|
5898
|
+
outputAssetId: output?.assetId,
|
|
5899
|
+
outputVariantId: output?.variantId,
|
|
5900
|
+
metadata: composition.metadata,
|
|
5901
|
+
sortIndex: composition.sortIndex
|
|
5902
|
+
});
|
|
5903
|
+
compositionsByName.set(created.composition.name, created.composition);
|
|
5904
|
+
compositionIds.push(created.composition.id);
|
|
5905
|
+
}
|
|
5906
|
+
for (const item of plan.compositionItems) {
|
|
5907
|
+
const composition = compositionsByName.get(item.compositionName);
|
|
5908
|
+
if (!composition) throw new Error(`Composition not found during import: ${item.compositionName}`);
|
|
5909
|
+
const created = await postJson(ctx, deps, `/api/spaces/${ctx.spaceId}/compositions/${encodeURIComponent(composition.id)}/items`, resolveCompositionItemRequest(item, uploadedByKey));
|
|
5910
|
+
compositionItemIds.push(created.item.id);
|
|
5911
|
+
}
|
|
5912
|
+
const presets = await fetchJson$1(ctx, deps, `/api/spaces/${ctx.spaceId}/style-presets`);
|
|
5913
|
+
const presetsByName = new Map((presets.presets ?? []).map((preset) => [preset.name, preset]));
|
|
5914
|
+
const presetsById = new Map((presets.presets ?? []).map((preset) => [preset.id, preset]));
|
|
5915
|
+
for (const preset of plan.stylePresets) {
|
|
5916
|
+
const collectionId = preset.collectionId === null ? null : preset.collectionId ?? (preset.collectionName ? collectionsByName.get(preset.collectionName)?.id : void 0);
|
|
5917
|
+
if (preset.collectionName && collectionId === void 0) throw new Error(`Style preset ${preset.name} references missing collection during import: ${preset.collectionName}`);
|
|
5918
|
+
const request = {
|
|
5919
|
+
id: preset.id,
|
|
5920
|
+
name: preset.name,
|
|
5921
|
+
description: preset.description,
|
|
5922
|
+
stylePrompt: preset.stylePrompt,
|
|
5923
|
+
collectionId,
|
|
5924
|
+
enabled: preset.enabled,
|
|
5925
|
+
isDefault: preset.isDefault
|
|
5926
|
+
};
|
|
5927
|
+
const existing = preset.id ? presetsById.get(preset.id) : presetsByName.get(preset.name);
|
|
5928
|
+
if (preset.action === "update" || preset.action === "upsert" && existing) {
|
|
5929
|
+
const updated = await patchJson(ctx, deps, `/api/spaces/${ctx.spaceId}/style-presets/${encodeURIComponent(existing.id)}`, request);
|
|
5930
|
+
stylePresetIds.push(updated.preset.id);
|
|
5931
|
+
presetsByName.set(updated.preset.name, updated.preset);
|
|
5932
|
+
presetsById.set(updated.preset.id, updated.preset);
|
|
5933
|
+
} else {
|
|
5934
|
+
const created = await postJson(ctx, deps, `/api/spaces/${ctx.spaceId}/style-presets`, request);
|
|
5935
|
+
stylePresetIds.push(created.preset.id);
|
|
5936
|
+
presetsByName.set(created.preset.name, created.preset);
|
|
5937
|
+
presetsById.set(created.preset.id, created.preset);
|
|
5938
|
+
}
|
|
5939
|
+
}
|
|
5940
|
+
return {
|
|
5941
|
+
collectionIds,
|
|
5942
|
+
collectionItemIds,
|
|
5943
|
+
relationIds,
|
|
5944
|
+
compositionIds,
|
|
5945
|
+
compositionItemIds,
|
|
5946
|
+
stylePresetIds
|
|
5947
|
+
};
|
|
5948
|
+
}
|
|
5949
|
+
function resolveCollectionItemRequest(item, uploadedByKey) {
|
|
5950
|
+
const subject = item.recordKey ? resolveSubject({
|
|
5951
|
+
subjectType: item.subjectType,
|
|
5952
|
+
recordKey: item.recordKey
|
|
5953
|
+
}, uploadedByKey) : {
|
|
5954
|
+
subjectType: item.subjectType,
|
|
5955
|
+
assetId: item.assetId,
|
|
5956
|
+
variantId: item.variantId
|
|
5957
|
+
};
|
|
5958
|
+
return {
|
|
5959
|
+
id: item.id,
|
|
5960
|
+
...subject,
|
|
5961
|
+
role: item.role,
|
|
5962
|
+
pinnedVariantId: item.pinnedVariantBehavior === "none" ? item.pinnedVariantId ?? null : item.pinnedVariantId ?? (item.recordKey ? uploadedByKey.get(item.recordKey).variantId : void 0),
|
|
5963
|
+
sortIndex: item.sortIndex
|
|
5964
|
+
};
|
|
5965
|
+
}
|
|
5966
|
+
function resolveCompositionItemRequest(item, uploadedByKey) {
|
|
5967
|
+
const uploaded = item.recordKey ? uploadedByKey.get(item.recordKey) : void 0;
|
|
5968
|
+
if (item.recordKey && !uploaded) throw new Error(`Could not resolve same-batch composition item: ${item.recordKey}`);
|
|
5969
|
+
return {
|
|
5970
|
+
id: item.id,
|
|
5971
|
+
role: item.role,
|
|
5972
|
+
label: item.label,
|
|
5973
|
+
assetId: item.assetId ?? uploaded?.assetId,
|
|
5974
|
+
variantId: item.variantId ?? uploaded.variantId,
|
|
5975
|
+
metadata: item.metadata,
|
|
5976
|
+
sortIndex: item.sortIndex
|
|
5977
|
+
};
|
|
5978
|
+
}
|
|
5979
|
+
function resolveSubject(subject, uploadedByKey) {
|
|
5980
|
+
if (!subject.recordKey) return {
|
|
5981
|
+
subjectType: subject.subjectType,
|
|
5982
|
+
assetId: subject.assetId,
|
|
5983
|
+
variantId: subject.variantId
|
|
5984
|
+
};
|
|
5985
|
+
const uploaded = uploadedByKey.get(subject.recordKey);
|
|
5986
|
+
if (!uploaded) throw new Error(`Could not resolve same-batch reference: ${subject.recordKey}`);
|
|
5987
|
+
return subject.subjectType === "asset" ? {
|
|
5988
|
+
subjectType: "asset",
|
|
5989
|
+
assetId: uploaded.assetId
|
|
5990
|
+
} : {
|
|
5991
|
+
subjectType: "variant",
|
|
5992
|
+
variantId: uploaded.variantId
|
|
5993
|
+
};
|
|
5994
|
+
}
|
|
5995
|
+
async function postJson(ctx, deps, requestPath, json) {
|
|
5996
|
+
return sendJson(ctx, deps, "POST", requestPath, json);
|
|
5997
|
+
}
|
|
5998
|
+
async function patchJson(ctx, deps, requestPath, json) {
|
|
5999
|
+
return sendJson(ctx, deps, "PATCH", requestPath, json);
|
|
6000
|
+
}
|
|
6001
|
+
async function sendJson(ctx, deps, method, requestPath, json) {
|
|
6002
|
+
const response = await deps.fetch(`${ctx.baseUrl}${requestPath}`, {
|
|
6003
|
+
method,
|
|
6004
|
+
headers: {
|
|
6005
|
+
Authorization: `Bearer ${ctx.accessToken}`,
|
|
6006
|
+
Accept: "application/json",
|
|
6007
|
+
"Content-Type": "application/json"
|
|
6008
|
+
},
|
|
6009
|
+
body: JSON.stringify(stripUndefined(json))
|
|
6010
|
+
});
|
|
6011
|
+
const data = await response.json().catch(() => ({}));
|
|
6012
|
+
if (!response.ok) throw new Error("error" in data ? data.error : `Request failed: ${response.status}`);
|
|
6013
|
+
return data;
|
|
6014
|
+
}
|
|
6015
|
+
function stripUndefined(value) {
|
|
6016
|
+
return Object.fromEntries(Object.entries(value).filter(([, entry]) => entry !== void 0));
|
|
6017
|
+
}
|
|
6018
|
+
async function fetchJson$1(ctx, deps, requestPath) {
|
|
6019
|
+
const response = await deps.fetch(`${ctx.baseUrl}${requestPath}`, { headers: {
|
|
6020
|
+
Authorization: `Bearer ${ctx.accessToken}`,
|
|
6021
|
+
Accept: "application/json"
|
|
6022
|
+
} });
|
|
6023
|
+
const data = await response.json().catch(() => ({}));
|
|
6024
|
+
if (!response.ok) throw new Error("error" in data ? data.error : `Request failed: ${response.status}`);
|
|
6025
|
+
return data;
|
|
6026
|
+
}
|
|
6027
|
+
function printResult$1(result, parsed, deps) {
|
|
6028
|
+
if (parsed.options.json === "true") {
|
|
6029
|
+
deps.print(JSON.stringify(result, null, 2));
|
|
6030
|
+
return;
|
|
6031
|
+
}
|
|
6032
|
+
if (result.dryRun) {
|
|
6033
|
+
deps.print(`Dry run passed for ${result.records.length} import records.`);
|
|
6034
|
+
const organizationCount = result.collections.length + result.collectionItems + result.relations + result.compositions.length + result.compositionItems + result.stylePresets.length;
|
|
6035
|
+
if (organizationCount > 0) deps.print(` Organization changes: ${organizationCount}`);
|
|
6036
|
+
return;
|
|
6037
|
+
}
|
|
6038
|
+
deps.print(`Imported ${result.records.length} records.`);
|
|
6039
|
+
for (const record of result.records) deps.print(` ${record.key}: asset ${record.assetId}, variant ${record.variantId}`);
|
|
6040
|
+
const organizationCount = result.collectionIds.length + result.collectionItemIds.length + result.relationIds.length + result.compositionIds.length + result.compositionItemIds.length + result.stylePresetIds.length;
|
|
6041
|
+
if (organizationCount > 0) deps.print(` Organization records: ${organizationCount}`);
|
|
6042
|
+
}
|
|
6043
|
+
function printUsage$11() {
|
|
6044
|
+
console.log(`
|
|
6045
|
+
Usage:
|
|
6046
|
+
makefx import <manifest.json> [--space <id>]
|
|
6047
|
+
makefx import <manifest.json> --dry-run [--json]
|
|
6048
|
+
|
|
6049
|
+
Manifest:
|
|
6050
|
+
Top-level array, or { "records": [...] }. Each record sets file plus either
|
|
6051
|
+
assetId for an existing asset or name for a new asset. Records can include
|
|
6052
|
+
prompt, model, provider, providerMetadata, and generationProvenance for
|
|
6053
|
+
immutable import provenance. Lineage entries use sourceVariantId or sourceFile
|
|
6054
|
+
with relationType derived, refined, or forked; lineage is not editable
|
|
6055
|
+
organization state. Optional collections, collectionItems, relations,
|
|
6056
|
+
compositions, compositionItems, styleCollections, and stylePresets sections
|
|
6057
|
+
organize imported records after upload. Style references are normal assets in
|
|
6058
|
+
collections and presets point to those collections. Missing
|
|
6059
|
+
collections/compositions are only created when their manifest entry sets
|
|
6060
|
+
create: true.
|
|
5175
6061
|
`);
|
|
5176
6062
|
}
|
|
5177
6063
|
//#endregion
|
|
@@ -19110,7 +19996,8 @@ var UserProfileSchema = object({
|
|
|
19110
19996
|
}).openapi("UserProfile");
|
|
19111
19997
|
var SessionConfigSchema = object({
|
|
19112
19998
|
googleClientId: string$1(),
|
|
19113
|
-
environment: string$1()
|
|
19999
|
+
environment: string$1(),
|
|
20000
|
+
features: object({ rotation: boolean$1() })
|
|
19114
20001
|
}).openapi("SessionConfig");
|
|
19115
20002
|
var AuthSessionResponseSchema = object({
|
|
19116
20003
|
user: ApiUserSchema.nullable(),
|
|
@@ -19138,6 +20025,33 @@ var UserSettingsResponseSchema = object({
|
|
|
19138
20025
|
success: literal(true),
|
|
19139
20026
|
user: ApiUserSchema
|
|
19140
20027
|
}).openapi("UserSettingsResponse");
|
|
20028
|
+
var ProviderKeyProviderSchema = _enum([
|
|
20029
|
+
"google_ai",
|
|
20030
|
+
"anthropic",
|
|
20031
|
+
"elevenlabs",
|
|
20032
|
+
"lyria"
|
|
20033
|
+
]).openapi("ProviderKeyProvider");
|
|
20034
|
+
var ProviderKeyParamsSchema = object({ provider: ProviderKeyProviderSchema.openapi({ param: {
|
|
20035
|
+
name: "provider",
|
|
20036
|
+
in: "path"
|
|
20037
|
+
} }) });
|
|
20038
|
+
var ProviderKeySummarySchema = object({
|
|
20039
|
+
provider: ProviderKeyProviderSchema,
|
|
20040
|
+
label: string$1(),
|
|
20041
|
+
configured: boolean$1(),
|
|
20042
|
+
keyHint: string$1().nullable(),
|
|
20043
|
+
updatedAt: string$1().nullable(),
|
|
20044
|
+
platformConfigured: boolean$1()
|
|
20045
|
+
}).openapi("ProviderKeySummary");
|
|
20046
|
+
var ListProviderKeysResponseSchema = object({
|
|
20047
|
+
success: literal(true),
|
|
20048
|
+
providers: array(ProviderKeySummarySchema)
|
|
20049
|
+
}).openapi("ListProviderKeysResponse");
|
|
20050
|
+
var UpsertProviderKeyRequestSchema = object({ apiKey: string$1() }).openapi("UpsertProviderKeyRequest");
|
|
20051
|
+
var ProviderKeyResponseSchema = object({
|
|
20052
|
+
success: literal(true),
|
|
20053
|
+
provider: ProviderKeySummarySchema
|
|
20054
|
+
}).openapi("ProviderKeyResponse");
|
|
19141
20055
|
var SpaceRoleSchema = _enum([
|
|
19142
20056
|
"owner",
|
|
19143
20057
|
"editor",
|
|
@@ -19191,6 +20105,12 @@ var VariantStatusSchema = _enum([
|
|
|
19191
20105
|
"completed",
|
|
19192
20106
|
"failed"
|
|
19193
20107
|
]);
|
|
20108
|
+
var PlatformUsageTypeSchema = _enum([
|
|
20109
|
+
"storage",
|
|
20110
|
+
"workflow",
|
|
20111
|
+
"delivery"
|
|
20112
|
+
]);
|
|
20113
|
+
var PlatformUsageUnitSchema = _enum(["byte", "run"]);
|
|
19194
20114
|
var BooleanFromSqliteSchema = union([
|
|
19195
20115
|
boolean$1(),
|
|
19196
20116
|
literal(0),
|
|
@@ -19240,28 +20160,472 @@ var VariantSchema = object({
|
|
|
19240
20160
|
created_at: number$1(),
|
|
19241
20161
|
updated_at: number$1().nullable()
|
|
19242
20162
|
}).passthrough().openapi("Variant");
|
|
20163
|
+
var LineageSchema = object({
|
|
20164
|
+
id: string$1(),
|
|
20165
|
+
parent_variant_id: string$1(),
|
|
20166
|
+
child_variant_id: string$1(),
|
|
20167
|
+
relation_type: _enum([
|
|
20168
|
+
"derived",
|
|
20169
|
+
"refined",
|
|
20170
|
+
"forked"
|
|
20171
|
+
]),
|
|
20172
|
+
severed: BooleanFromSqliteSchema.optional(),
|
|
20173
|
+
created_at: number$1().optional()
|
|
20174
|
+
}).passthrough().openapi("Lineage");
|
|
19243
20175
|
var ListSpaceAssetsResponseSchema = object({
|
|
19244
20176
|
success: literal(true),
|
|
19245
20177
|
assets: array(AssetSchema)
|
|
19246
20178
|
}).openapi("ListSpaceAssetsResponse");
|
|
19247
|
-
var
|
|
20179
|
+
var SpaceSubjectTypeSchema = _enum(["asset", "variant"]);
|
|
20180
|
+
var CollectionKindSchema = _enum([
|
|
20181
|
+
"cast",
|
|
20182
|
+
"style_refs",
|
|
20183
|
+
"backgrounds",
|
|
20184
|
+
"scenes",
|
|
20185
|
+
"thumbnails",
|
|
20186
|
+
"maps",
|
|
20187
|
+
"deliverables",
|
|
20188
|
+
"custom"
|
|
20189
|
+
]);
|
|
20190
|
+
var SpaceRelationTypeSchema = _enum([
|
|
20191
|
+
"appears_in",
|
|
20192
|
+
"background_for",
|
|
20193
|
+
"style_reference_for",
|
|
20194
|
+
"thumbnail_for",
|
|
20195
|
+
"alternate_of",
|
|
20196
|
+
"prop_in",
|
|
20197
|
+
"map_for",
|
|
20198
|
+
"part_of",
|
|
20199
|
+
"reference_for",
|
|
20200
|
+
"custom"
|
|
20201
|
+
]);
|
|
20202
|
+
var CompositionItemRoleSchema = _enum([
|
|
20203
|
+
"output",
|
|
20204
|
+
"background",
|
|
20205
|
+
"character",
|
|
20206
|
+
"prop",
|
|
20207
|
+
"style_ref",
|
|
20208
|
+
"overlay",
|
|
20209
|
+
"map",
|
|
20210
|
+
"thumbnail",
|
|
20211
|
+
"custom"
|
|
20212
|
+
]);
|
|
20213
|
+
var CompositionStatusSchema = _enum(["draft", "final"]);
|
|
20214
|
+
var CollectionIdParamsSchema = SpaceIdParamsSchema.extend({ collectionId: string$1().openapi({ param: {
|
|
20215
|
+
name: "collectionId",
|
|
20216
|
+
in: "path"
|
|
20217
|
+
} }) });
|
|
20218
|
+
var CollectionItemParamsSchema = CollectionIdParamsSchema.extend({ itemId: string$1().openapi({ param: {
|
|
20219
|
+
name: "itemId",
|
|
20220
|
+
in: "path"
|
|
20221
|
+
} }) });
|
|
20222
|
+
var StylePresetParamsSchema = SpaceIdParamsSchema.extend({ presetId: string$1().openapi({ param: {
|
|
20223
|
+
name: "presetId",
|
|
20224
|
+
in: "path"
|
|
20225
|
+
} }) });
|
|
20226
|
+
var RelationParamsSchema = SpaceIdParamsSchema.extend({ relationId: string$1().openapi({ param: {
|
|
20227
|
+
name: "relationId",
|
|
20228
|
+
in: "path"
|
|
20229
|
+
} }) });
|
|
20230
|
+
var CompositionIdParamsSchema = SpaceIdParamsSchema.extend({ compositionId: string$1().openapi({ param: {
|
|
20231
|
+
name: "compositionId",
|
|
20232
|
+
in: "path"
|
|
20233
|
+
} }) });
|
|
20234
|
+
var CompositionItemParamsSchema = CompositionIdParamsSchema.extend({ itemId: string$1().openapi({ param: {
|
|
20235
|
+
name: "itemId",
|
|
20236
|
+
in: "path"
|
|
20237
|
+
} }) });
|
|
20238
|
+
var SpaceSubjectSchema = object({
|
|
20239
|
+
subjectType: SpaceSubjectTypeSchema,
|
|
20240
|
+
assetId: string$1().optional(),
|
|
20241
|
+
variantId: string$1().optional()
|
|
20242
|
+
}).openapi("SpaceSubject");
|
|
20243
|
+
var SpaceCollectionSchema = object({
|
|
19248
20244
|
id: string$1(),
|
|
19249
|
-
|
|
20245
|
+
name: string$1(),
|
|
20246
|
+
kind: CollectionKindSchema,
|
|
20247
|
+
color: string$1().nullable(),
|
|
20248
|
+
description: string$1().nullable(),
|
|
20249
|
+
sort_index: number$1().int(),
|
|
20250
|
+
created_by: string$1(),
|
|
20251
|
+
created_at: number$1(),
|
|
20252
|
+
updated_at: number$1()
|
|
20253
|
+
}).openapi("SpaceCollection");
|
|
20254
|
+
var CollectionItemSchema = object({
|
|
20255
|
+
id: string$1(),
|
|
20256
|
+
collection_id: string$1(),
|
|
20257
|
+
subject_type: SpaceSubjectTypeSchema,
|
|
20258
|
+
asset_id: string$1().nullable(),
|
|
20259
|
+
variant_id: string$1().nullable(),
|
|
20260
|
+
role: string$1(),
|
|
20261
|
+
pinned_variant_id: string$1().nullable(),
|
|
20262
|
+
sort_index: number$1().int(),
|
|
20263
|
+
created_by: string$1(),
|
|
20264
|
+
created_at: number$1(),
|
|
20265
|
+
updated_at: number$1()
|
|
20266
|
+
}).openapi("CollectionItem");
|
|
20267
|
+
var StyleReferenceCollectionSchema = SpaceCollectionSchema.extend({
|
|
20268
|
+
reference_count: number$1().int(),
|
|
20269
|
+
preset_count: number$1().int()
|
|
20270
|
+
}).openapi("StyleReferenceCollection");
|
|
20271
|
+
var StylePresetSchema = object({
|
|
20272
|
+
id: string$1(),
|
|
20273
|
+
name: string$1(),
|
|
20274
|
+
description: string$1().nullable(),
|
|
20275
|
+
style_prompt: string$1(),
|
|
20276
|
+
collection_id: string$1().nullable(),
|
|
20277
|
+
enabled: BooleanFromSqliteSchema,
|
|
20278
|
+
is_default: BooleanFromSqliteSchema,
|
|
20279
|
+
created_by: string$1(),
|
|
20280
|
+
created_at: number$1(),
|
|
20281
|
+
updated_at: number$1(),
|
|
20282
|
+
collection_name: string$1().nullable(),
|
|
20283
|
+
reference_count: number$1().int(),
|
|
20284
|
+
style_reference_variant_ids: array(string$1()),
|
|
20285
|
+
style_reference_image_keys: array(string$1())
|
|
20286
|
+
}).openapi("StylePreset");
|
|
20287
|
+
var SpaceRelationSchema = object({
|
|
20288
|
+
id: string$1(),
|
|
20289
|
+
subject_type: SpaceSubjectTypeSchema,
|
|
20290
|
+
subject_asset_id: string$1().nullable(),
|
|
20291
|
+
subject_variant_id: string$1().nullable(),
|
|
20292
|
+
object_type: SpaceSubjectTypeSchema,
|
|
20293
|
+
object_asset_id: string$1().nullable(),
|
|
20294
|
+
object_variant_id: string$1().nullable(),
|
|
20295
|
+
relation_type: SpaceRelationTypeSchema,
|
|
20296
|
+
label: string$1().nullable(),
|
|
20297
|
+
context: string$1().nullable(),
|
|
20298
|
+
metadata: string$1(),
|
|
20299
|
+
sort_index: number$1().int(),
|
|
20300
|
+
created_by: string$1(),
|
|
20301
|
+
created_at: number$1(),
|
|
20302
|
+
updated_at: number$1()
|
|
20303
|
+
}).openapi("SpaceRelation");
|
|
20304
|
+
var CompositionSchema = object({
|
|
20305
|
+
id: string$1(),
|
|
20306
|
+
name: string$1(),
|
|
20307
|
+
description: string$1().nullable(),
|
|
20308
|
+
status: CompositionStatusSchema,
|
|
20309
|
+
output_asset_id: string$1().nullable(),
|
|
20310
|
+
output_variant_id: string$1().nullable(),
|
|
20311
|
+
metadata: string$1(),
|
|
20312
|
+
sort_index: number$1().int(),
|
|
20313
|
+
created_by: string$1(),
|
|
20314
|
+
created_at: number$1(),
|
|
20315
|
+
updated_at: number$1()
|
|
20316
|
+
}).openapi("Composition");
|
|
20317
|
+
var CompositionItemSchema = object({
|
|
20318
|
+
id: string$1(),
|
|
20319
|
+
composition_id: string$1(),
|
|
20320
|
+
role: CompositionItemRoleSchema,
|
|
20321
|
+
label: string$1().nullable(),
|
|
20322
|
+
asset_id: string$1().nullable(),
|
|
19250
20323
|
variant_id: string$1(),
|
|
19251
|
-
asset_id: string$1(),
|
|
19252
|
-
media_kind: MediaKindSchema,
|
|
19253
|
-
shot_id: string$1().nullable(),
|
|
19254
|
-
scene_label: string$1(),
|
|
19255
|
-
timeline_start_ms: number$1().int().nonnegative(),
|
|
19256
|
-
duration_ms: number$1().int().nonnegative().nullable(),
|
|
19257
|
-
motion_prompt: string$1().nullable(),
|
|
19258
|
-
source_refs: string$1(),
|
|
19259
|
-
source_variant_ids: string$1(),
|
|
19260
20324
|
metadata: string$1(),
|
|
20325
|
+
sort_index: number$1().int(),
|
|
19261
20326
|
created_by: string$1(),
|
|
19262
20327
|
created_at: number$1(),
|
|
19263
20328
|
updated_at: number$1()
|
|
19264
|
-
}).openapi("
|
|
20329
|
+
}).openapi("CompositionItem");
|
|
20330
|
+
var UpsertCollectionRequestSchema = object({
|
|
20331
|
+
id: string$1().optional(),
|
|
20332
|
+
name: string$1().min(1),
|
|
20333
|
+
kind: CollectionKindSchema.optional(),
|
|
20334
|
+
color: string$1().nullable().optional(),
|
|
20335
|
+
description: string$1().nullable().optional(),
|
|
20336
|
+
sortIndex: number$1().int().optional()
|
|
20337
|
+
}).openapi("UpsertCollectionRequest");
|
|
20338
|
+
var UpdateCollectionRequestSchema = UpsertCollectionRequestSchema.omit({ id: true }).partial().openapi("UpdateCollectionRequest");
|
|
20339
|
+
var UpsertCollectionItemRequestSchema = object({
|
|
20340
|
+
id: string$1().optional(),
|
|
20341
|
+
subjectType: SpaceSubjectTypeSchema,
|
|
20342
|
+
assetId: string$1().optional(),
|
|
20343
|
+
variantId: string$1().optional(),
|
|
20344
|
+
role: string$1().optional(),
|
|
20345
|
+
pinnedVariantId: string$1().nullable().optional(),
|
|
20346
|
+
sortIndex: number$1().int().optional()
|
|
20347
|
+
}).openapi("UpsertCollectionItemRequest");
|
|
20348
|
+
var UpsertStylePresetRequestSchema = object({
|
|
20349
|
+
id: string$1().optional(),
|
|
20350
|
+
name: string$1().min(1),
|
|
20351
|
+
description: string$1().nullable().optional(),
|
|
20352
|
+
stylePrompt: string$1().optional(),
|
|
20353
|
+
collectionId: string$1().nullable().optional(),
|
|
20354
|
+
enabled: boolean$1().optional(),
|
|
20355
|
+
isDefault: boolean$1().optional()
|
|
20356
|
+
}).openapi("UpsertStylePresetRequest");
|
|
20357
|
+
var UpdateStylePresetRequestSchema = UpsertStylePresetRequestSchema.omit({
|
|
20358
|
+
id: true,
|
|
20359
|
+
name: true
|
|
20360
|
+
}).extend({ name: string$1().min(1).optional() }).openapi("UpdateStylePresetRequest");
|
|
20361
|
+
var UpdateCollectionItemRequestSchema = object({
|
|
20362
|
+
role: string$1().optional(),
|
|
20363
|
+
pinnedVariantId: string$1().nullable().optional(),
|
|
20364
|
+
sortIndex: number$1().int().optional()
|
|
20365
|
+
}).openapi("UpdateCollectionItemRequest");
|
|
20366
|
+
var ReorderItemsRequestSchema = object({ itemIds: array(string$1()) }).openapi("ReorderItemsRequest");
|
|
20367
|
+
var UpsertRelationRequestSchema = object({
|
|
20368
|
+
id: string$1().optional(),
|
|
20369
|
+
subject: SpaceSubjectSchema,
|
|
20370
|
+
object: SpaceSubjectSchema,
|
|
20371
|
+
relationType: SpaceRelationTypeSchema,
|
|
20372
|
+
label: string$1().nullable().optional(),
|
|
20373
|
+
context: union([string$1(), record(string$1(), unknown())]).nullable().optional(),
|
|
20374
|
+
metadata: record(string$1(), unknown()).optional(),
|
|
20375
|
+
sortIndex: number$1().int().optional()
|
|
20376
|
+
}).openapi("UpsertRelationRequest");
|
|
20377
|
+
var UpdateRelationRequestSchema = object({
|
|
20378
|
+
relationType: SpaceRelationTypeSchema.optional(),
|
|
20379
|
+
label: string$1().nullable().optional(),
|
|
20380
|
+
context: union([string$1(), record(string$1(), unknown())]).nullable().optional(),
|
|
20381
|
+
metadata: record(string$1(), unknown()).optional(),
|
|
20382
|
+
sortIndex: number$1().int().optional()
|
|
20383
|
+
}).openapi("UpdateRelationRequest");
|
|
20384
|
+
var UpsertCompositionRequestSchema = object({
|
|
20385
|
+
id: string$1().optional(),
|
|
20386
|
+
name: string$1().min(1),
|
|
20387
|
+
description: string$1().nullable().optional(),
|
|
20388
|
+
status: CompositionStatusSchema.optional(),
|
|
20389
|
+
outputAssetId: string$1().nullable().optional(),
|
|
20390
|
+
outputVariantId: string$1().nullable().optional(),
|
|
20391
|
+
metadata: record(string$1(), unknown()).optional(),
|
|
20392
|
+
sortIndex: number$1().int().optional()
|
|
20393
|
+
}).openapi("UpsertCompositionRequest");
|
|
20394
|
+
var UpdateCompositionRequestSchema = UpsertCompositionRequestSchema.omit({
|
|
20395
|
+
id: true,
|
|
20396
|
+
name: true
|
|
20397
|
+
}).extend({ name: string$1().min(1).optional() }).openapi("UpdateCompositionRequest");
|
|
20398
|
+
var UpsertCompositionItemRequestSchema = object({
|
|
20399
|
+
id: string$1().optional(),
|
|
20400
|
+
role: CompositionItemRoleSchema,
|
|
20401
|
+
label: string$1().nullable().optional(),
|
|
20402
|
+
assetId: string$1().nullable().optional(),
|
|
20403
|
+
variantId: string$1().min(1),
|
|
20404
|
+
metadata: record(string$1(), unknown()).optional(),
|
|
20405
|
+
sortIndex: number$1().int().optional()
|
|
20406
|
+
}).openapi("UpsertCompositionItemRequest");
|
|
20407
|
+
var UpdateCompositionItemRequestSchema = object({
|
|
20408
|
+
role: CompositionItemRoleSchema.optional(),
|
|
20409
|
+
label: string$1().nullable().optional(),
|
|
20410
|
+
assetId: string$1().nullable().optional(),
|
|
20411
|
+
variantId: string$1().optional(),
|
|
20412
|
+
metadata: record(string$1(), unknown()).optional(),
|
|
20413
|
+
sortIndex: number$1().int().optional()
|
|
20414
|
+
}).openapi("UpdateCompositionItemRequest");
|
|
20415
|
+
var ListCollectionsResponseSchema = object({
|
|
20416
|
+
success: literal(true),
|
|
20417
|
+
collections: array(SpaceCollectionSchema)
|
|
20418
|
+
}).openapi("ListCollectionsResponse");
|
|
20419
|
+
var CollectionResponseSchema = object({
|
|
20420
|
+
success: literal(true),
|
|
20421
|
+
collection: SpaceCollectionSchema
|
|
20422
|
+
}).openapi("CollectionResponse");
|
|
20423
|
+
var ListCollectionItemsResponseSchema = object({
|
|
20424
|
+
success: literal(true),
|
|
20425
|
+
items: array(CollectionItemSchema)
|
|
20426
|
+
}).openapi("ListCollectionItemsResponse");
|
|
20427
|
+
var CollectionItemResponseSchema = object({
|
|
20428
|
+
success: literal(true),
|
|
20429
|
+
item: CollectionItemSchema
|
|
20430
|
+
}).openapi("CollectionItemResponse");
|
|
20431
|
+
var ListStyleReferenceCollectionsResponseSchema = object({
|
|
20432
|
+
success: literal(true),
|
|
20433
|
+
collections: array(StyleReferenceCollectionSchema)
|
|
20434
|
+
}).openapi("ListStyleReferenceCollectionsResponse");
|
|
20435
|
+
var ListStylePresetsResponseSchema = object({
|
|
20436
|
+
success: literal(true),
|
|
20437
|
+
presets: array(StylePresetSchema)
|
|
20438
|
+
}).openapi("ListStylePresetsResponse");
|
|
20439
|
+
var StylePresetResponseSchema = object({
|
|
20440
|
+
success: literal(true),
|
|
20441
|
+
preset: StylePresetSchema
|
|
20442
|
+
}).openapi("StylePresetResponse");
|
|
20443
|
+
var ListRelationsResponseSchema = object({
|
|
20444
|
+
success: literal(true),
|
|
20445
|
+
relations: array(SpaceRelationSchema)
|
|
20446
|
+
}).openapi("ListRelationsResponse");
|
|
20447
|
+
var RelationResponseSchema = object({
|
|
20448
|
+
success: literal(true),
|
|
20449
|
+
relation: SpaceRelationSchema
|
|
20450
|
+
}).openapi("RelationResponse");
|
|
20451
|
+
var ListCompositionsResponseSchema = object({
|
|
20452
|
+
success: literal(true),
|
|
20453
|
+
compositions: array(CompositionSchema)
|
|
20454
|
+
}).openapi("ListCompositionsResponse");
|
|
20455
|
+
var CompositionResponseSchema = object({
|
|
20456
|
+
success: literal(true),
|
|
20457
|
+
composition: CompositionSchema
|
|
20458
|
+
}).openapi("CompositionResponse");
|
|
20459
|
+
var ListCompositionItemsResponseSchema = object({
|
|
20460
|
+
success: literal(true),
|
|
20461
|
+
items: array(CompositionItemSchema)
|
|
20462
|
+
}).openapi("ListCompositionItemsResponse");
|
|
20463
|
+
var CompositionItemResponseSchema = object({
|
|
20464
|
+
success: literal(true),
|
|
20465
|
+
item: CompositionItemSchema
|
|
20466
|
+
}).openapi("CompositionItemResponse");
|
|
20467
|
+
var UsageSummaryQuerySchema = object({
|
|
20468
|
+
from: string$1().optional(),
|
|
20469
|
+
to: string$1().optional()
|
|
20470
|
+
});
|
|
20471
|
+
var PlatformUsageTypeSummarySchema = object({
|
|
20472
|
+
usageType: PlatformUsageTypeSchema,
|
|
20473
|
+
unit: PlatformUsageUnitSchema,
|
|
20474
|
+
quantity: number$1().int(),
|
|
20475
|
+
events: number$1().int().nonnegative()
|
|
20476
|
+
}).openapi("PlatformUsageTypeSummary");
|
|
20477
|
+
var PlatformUsageMediaKindSummarySchema = object({
|
|
20478
|
+
mediaKind: MediaKindSchema.nullable(),
|
|
20479
|
+
storageBytes: number$1().int(),
|
|
20480
|
+
workflowRuns: number$1().int(),
|
|
20481
|
+
deliveryBytes: number$1().int(),
|
|
20482
|
+
events: number$1().int().nonnegative()
|
|
20483
|
+
}).openapi("PlatformUsageMediaKindSummary");
|
|
20484
|
+
var PlatformUsageSummaryResponseSchema = object({
|
|
20485
|
+
success: literal(true),
|
|
20486
|
+
spaceId: string$1(),
|
|
20487
|
+
period: object({
|
|
20488
|
+
from: string$1().nullable(),
|
|
20489
|
+
to: string$1().nullable()
|
|
20490
|
+
}),
|
|
20491
|
+
totals: object({
|
|
20492
|
+
storageBytes: number$1().int(),
|
|
20493
|
+
workflowRuns: number$1().int(),
|
|
20494
|
+
deliveryBytes: number$1().int()
|
|
20495
|
+
}),
|
|
20496
|
+
byType: array(PlatformUsageTypeSummarySchema),
|
|
20497
|
+
byMediaKind: array(PlatformUsageMediaKindSummarySchema)
|
|
20498
|
+
}).openapi("PlatformUsageSummaryResponse");
|
|
20499
|
+
var ProviderSpendSummaryQuerySchema = object({
|
|
20500
|
+
from: string$1().optional(),
|
|
20501
|
+
to: string$1().optional(),
|
|
20502
|
+
user_id: string$1().optional(),
|
|
20503
|
+
userId: string$1().optional(),
|
|
20504
|
+
space_id: string$1().optional(),
|
|
20505
|
+
spaceId: string$1().optional(),
|
|
20506
|
+
provider: string$1().optional(),
|
|
20507
|
+
media_kind: MediaKindSchema.optional(),
|
|
20508
|
+
mediaKind: MediaKindSchema.optional()
|
|
20509
|
+
});
|
|
20510
|
+
var ProviderSpendAggregateSchema = object({
|
|
20511
|
+
amountMicroUsd: number$1().int(),
|
|
20512
|
+
amountUsd: number$1(),
|
|
20513
|
+
quantity: number$1(),
|
|
20514
|
+
entries: number$1().int().nonnegative(),
|
|
20515
|
+
unpricedEntries: number$1().int().nonnegative()
|
|
20516
|
+
}).openapi("ProviderSpendAggregate");
|
|
20517
|
+
var ProviderSpendSummaryResponseSchema = object({
|
|
20518
|
+
success: literal(true),
|
|
20519
|
+
period: object({
|
|
20520
|
+
from: string$1().nullable(),
|
|
20521
|
+
to: string$1().nullable()
|
|
20522
|
+
}),
|
|
20523
|
+
filters: object({
|
|
20524
|
+
userId: number$1().int().nullable(),
|
|
20525
|
+
spaceId: string$1().nullable(),
|
|
20526
|
+
provider: string$1().nullable(),
|
|
20527
|
+
mediaKind: MediaKindSchema.nullable()
|
|
20528
|
+
}),
|
|
20529
|
+
totals: ProviderSpendAggregateSchema,
|
|
20530
|
+
byProvider: array(ProviderSpendAggregateSchema.extend({ provider: string$1() })),
|
|
20531
|
+
byModel: array(ProviderSpendAggregateSchema.extend({
|
|
20532
|
+
provider: string$1(),
|
|
20533
|
+
providerModel: string$1()
|
|
20534
|
+
})),
|
|
20535
|
+
byMediaKind: array(ProviderSpendAggregateSchema.extend({ mediaKind: MediaKindSchema.nullable() })),
|
|
20536
|
+
byMeterEventName: array(ProviderSpendAggregateSchema.extend({ meterEventName: string$1().nullable() })),
|
|
20537
|
+
bySpace: array(ProviderSpendAggregateSchema.extend({ spaceId: string$1().nullable() })),
|
|
20538
|
+
byAsset: array(ProviderSpendAggregateSchema.extend({
|
|
20539
|
+
spaceId: string$1().nullable(),
|
|
20540
|
+
assetId: string$1().nullable()
|
|
20541
|
+
}))
|
|
20542
|
+
}).openapi("ProviderSpendSummaryResponse");
|
|
20543
|
+
var BillingEntitlementSchema = _enum([
|
|
20544
|
+
"none",
|
|
20545
|
+
"paid",
|
|
20546
|
+
"internal"
|
|
20547
|
+
]).openapi("BillingEntitlement");
|
|
20548
|
+
var BillingPlanStatusSchema = _enum([
|
|
20549
|
+
"inactive",
|
|
20550
|
+
"active",
|
|
20551
|
+
"internal"
|
|
20552
|
+
]).openapi("BillingPlanStatus");
|
|
20553
|
+
var BillingPlanStatusResponseSchema = object({
|
|
20554
|
+
key: literal("paid_generation"),
|
|
20555
|
+
displayName: string$1(),
|
|
20556
|
+
status: BillingPlanStatusSchema,
|
|
20557
|
+
checkoutAvailable: boolean$1(),
|
|
20558
|
+
portalAvailable: boolean$1()
|
|
20559
|
+
}).openapi("BillingPlanStatusResponse");
|
|
20560
|
+
var BillingMeterStatusSchema = object({
|
|
20561
|
+
name: string$1(),
|
|
20562
|
+
consumed: number$1(),
|
|
20563
|
+
credited: number$1(),
|
|
20564
|
+
remaining: number$1(),
|
|
20565
|
+
percentUsed: number$1(),
|
|
20566
|
+
hasLimit: boolean$1(),
|
|
20567
|
+
status: _enum([
|
|
20568
|
+
"ok",
|
|
20569
|
+
"warning",
|
|
20570
|
+
"critical",
|
|
20571
|
+
"exceeded"
|
|
20572
|
+
])
|
|
20573
|
+
}).openapi("BillingMeterStatus");
|
|
20574
|
+
var BillingStatusResponseSchema = object({
|
|
20575
|
+
configured: boolean$1(),
|
|
20576
|
+
available: boolean$1(),
|
|
20577
|
+
hasSubscription: boolean$1(),
|
|
20578
|
+
entitlement: BillingEntitlementSchema,
|
|
20579
|
+
plan: BillingPlanStatusResponseSchema,
|
|
20580
|
+
meters: array(BillingMeterStatusSchema),
|
|
20581
|
+
subscription: object({
|
|
20582
|
+
status: string$1(),
|
|
20583
|
+
periodStart: string$1().nullable().optional(),
|
|
20584
|
+
renewsAt: string$1().nullable()
|
|
20585
|
+
}).nullable(),
|
|
20586
|
+
portalUrl: string$1().nullable(),
|
|
20587
|
+
error: string$1().optional()
|
|
20588
|
+
}).openapi("BillingStatusResponse");
|
|
20589
|
+
var BillingUsageMeterSchema = object({
|
|
20590
|
+
used: number$1(),
|
|
20591
|
+
limit: number$1().nullable(),
|
|
20592
|
+
remaining: number$1().nullable(),
|
|
20593
|
+
costUsd: number$1().optional()
|
|
20594
|
+
}).openapi("BillingUsageMeter");
|
|
20595
|
+
var BillingUsageResponseSchema = object({
|
|
20596
|
+
period: object({
|
|
20597
|
+
start: string$1(),
|
|
20598
|
+
end: string$1()
|
|
20599
|
+
}),
|
|
20600
|
+
usage: record(string$1(), BillingUsageMeterSchema),
|
|
20601
|
+
estimatedCost: object({
|
|
20602
|
+
amount: number$1(),
|
|
20603
|
+
currency: string$1()
|
|
20604
|
+
}).optional()
|
|
20605
|
+
}).openapi("BillingUsageResponse");
|
|
20606
|
+
var BillingUrlResponseSchema = object({ url: string$1() }).openapi("BillingUrlResponse");
|
|
20607
|
+
var BillingUrlQuerySchema = object({
|
|
20608
|
+
return_url: string$1().optional(),
|
|
20609
|
+
success_url: string$1().optional()
|
|
20610
|
+
});
|
|
20611
|
+
var ProductionRecordSchema = object({
|
|
20612
|
+
id: string$1(),
|
|
20613
|
+
production_id: string$1(),
|
|
20614
|
+
variant_id: string$1(),
|
|
20615
|
+
asset_id: string$1(),
|
|
20616
|
+
media_kind: MediaKindSchema,
|
|
20617
|
+
shot_id: string$1().nullable(),
|
|
20618
|
+
scene_label: string$1(),
|
|
20619
|
+
timeline_start_ms: number$1().int().nonnegative(),
|
|
20620
|
+
duration_ms: number$1().int().nonnegative().nullable(),
|
|
20621
|
+
motion_prompt: string$1().nullable(),
|
|
20622
|
+
source_refs: string$1(),
|
|
20623
|
+
source_variant_ids: string$1(),
|
|
20624
|
+
metadata: string$1(),
|
|
20625
|
+
created_by: string$1(),
|
|
20626
|
+
created_at: number$1(),
|
|
20627
|
+
updated_at: number$1()
|
|
20628
|
+
}).openapi("ProductionRecord");
|
|
19265
20629
|
var PlaceProductionRecordRequestSchema = object({
|
|
19266
20630
|
id: string$1().optional(),
|
|
19267
20631
|
productionId: string$1().min(1),
|
|
@@ -19413,7 +20777,14 @@ var UploadMediaRequestSchema = object({
|
|
|
19413
20777
|
assetName: string$1().optional(),
|
|
19414
20778
|
assetType: string$1().optional(),
|
|
19415
20779
|
mediaKind: MediaKindSchema.optional(),
|
|
19416
|
-
|
|
20780
|
+
operation: string$1().optional(),
|
|
20781
|
+
prompt: string$1().optional(),
|
|
20782
|
+
model: string$1().optional(),
|
|
20783
|
+
provider: string$1().optional(),
|
|
20784
|
+
providerMetadata: string$1().optional(),
|
|
20785
|
+
generationProvenance: string$1().optional(),
|
|
20786
|
+
lineage: string$1().optional(),
|
|
20787
|
+
activeVariantBehavior: string$1().optional(),
|
|
19417
20788
|
transcript: UploadFileSchema.optional(),
|
|
19418
20789
|
wordTimings: UploadFileSchema.optional(),
|
|
19419
20790
|
renderMetadata: UploadFileSchema.optional()
|
|
@@ -19421,14 +20792,9 @@ var UploadMediaRequestSchema = object({
|
|
|
19421
20792
|
var UploadMediaResponseSchema = object({
|
|
19422
20793
|
success: literal(true),
|
|
19423
20794
|
variant: VariantSchema,
|
|
19424
|
-
asset: AssetSchema.optional()
|
|
20795
|
+
asset: AssetSchema.optional(),
|
|
20796
|
+
lineage: array(LineageSchema).optional()
|
|
19425
20797
|
}).openapi("UploadMediaResponse");
|
|
19426
|
-
var UploadStyleImageRequestSchema = object({ file: UploadFileSchema }).openapi("UploadStyleImageRequest");
|
|
19427
|
-
var UploadStyleImageResponseSchema = object({
|
|
19428
|
-
success: literal(true),
|
|
19429
|
-
imageKey: string$1(),
|
|
19430
|
-
warning: string$1().optional()
|
|
19431
|
-
}).openapi("UploadStyleImageResponse");
|
|
19432
20798
|
var VariantMediaParamsSchema = object({
|
|
19433
20799
|
spaceId: string$1().openapi({ param: {
|
|
19434
20800
|
name: "spaceId",
|
|
@@ -19479,6 +20845,24 @@ var apiEndpoints = {
|
|
|
19479
20845
|
jsonSchema: UpdateUserProfileRequestSchema,
|
|
19480
20846
|
responseSchema: UserProfileUpdateResponseSchema
|
|
19481
20847
|
},
|
|
20848
|
+
"GET /api/user/provider-keys": {
|
|
20849
|
+
method: "GET",
|
|
20850
|
+
path: "/api/user/provider-keys",
|
|
20851
|
+
responseSchema: ListProviderKeysResponseSchema
|
|
20852
|
+
},
|
|
20853
|
+
"PUT /api/user/provider-keys/:provider": {
|
|
20854
|
+
method: "PUT",
|
|
20855
|
+
path: "/api/user/provider-keys/:provider",
|
|
20856
|
+
paramsSchema: ProviderKeyParamsSchema,
|
|
20857
|
+
jsonSchema: UpsertProviderKeyRequestSchema,
|
|
20858
|
+
responseSchema: ProviderKeyResponseSchema
|
|
20859
|
+
},
|
|
20860
|
+
"DELETE /api/user/provider-keys/:provider": {
|
|
20861
|
+
method: "DELETE",
|
|
20862
|
+
path: "/api/user/provider-keys/:provider",
|
|
20863
|
+
paramsSchema: ProviderKeyParamsSchema,
|
|
20864
|
+
responseSchema: ProviderKeyResponseSchema
|
|
20865
|
+
},
|
|
19482
20866
|
"POST /api/spaces": {
|
|
19483
20867
|
method: "POST",
|
|
19484
20868
|
path: "/api/spaces",
|
|
@@ -19502,6 +20886,217 @@ var apiEndpoints = {
|
|
|
19502
20886
|
paramsSchema: SpaceIdParamsSchema,
|
|
19503
20887
|
responseSchema: ListSpaceAssetsResponseSchema
|
|
19504
20888
|
},
|
|
20889
|
+
"GET /api/spaces/:id/collections": {
|
|
20890
|
+
method: "GET",
|
|
20891
|
+
path: "/api/spaces/:id/collections",
|
|
20892
|
+
paramsSchema: SpaceIdParamsSchema,
|
|
20893
|
+
responseSchema: ListCollectionsResponseSchema
|
|
20894
|
+
},
|
|
20895
|
+
"POST /api/spaces/:id/collections": {
|
|
20896
|
+
method: "POST",
|
|
20897
|
+
path: "/api/spaces/:id/collections",
|
|
20898
|
+
paramsSchema: SpaceIdParamsSchema,
|
|
20899
|
+
jsonSchema: UpsertCollectionRequestSchema,
|
|
20900
|
+
responseSchema: CollectionResponseSchema
|
|
20901
|
+
},
|
|
20902
|
+
"PATCH /api/spaces/:id/collections/:collectionId": {
|
|
20903
|
+
method: "PATCH",
|
|
20904
|
+
path: "/api/spaces/:id/collections/:collectionId",
|
|
20905
|
+
paramsSchema: CollectionIdParamsSchema,
|
|
20906
|
+
jsonSchema: UpdateCollectionRequestSchema,
|
|
20907
|
+
responseSchema: CollectionResponseSchema
|
|
20908
|
+
},
|
|
20909
|
+
"DELETE /api/spaces/:id/collections/:collectionId": {
|
|
20910
|
+
method: "DELETE",
|
|
20911
|
+
path: "/api/spaces/:id/collections/:collectionId",
|
|
20912
|
+
paramsSchema: CollectionIdParamsSchema,
|
|
20913
|
+
responseSchema: SuccessResponseSchema
|
|
20914
|
+
},
|
|
20915
|
+
"GET /api/spaces/:id/collections/:collectionId/items": {
|
|
20916
|
+
method: "GET",
|
|
20917
|
+
path: "/api/spaces/:id/collections/:collectionId/items",
|
|
20918
|
+
paramsSchema: CollectionIdParamsSchema,
|
|
20919
|
+
responseSchema: ListCollectionItemsResponseSchema
|
|
20920
|
+
},
|
|
20921
|
+
"POST /api/spaces/:id/collections/:collectionId/items": {
|
|
20922
|
+
method: "POST",
|
|
20923
|
+
path: "/api/spaces/:id/collections/:collectionId/items",
|
|
20924
|
+
paramsSchema: CollectionIdParamsSchema,
|
|
20925
|
+
jsonSchema: UpsertCollectionItemRequestSchema,
|
|
20926
|
+
responseSchema: CollectionItemResponseSchema
|
|
20927
|
+
},
|
|
20928
|
+
"PATCH /api/spaces/:id/collections/:collectionId/items/:itemId": {
|
|
20929
|
+
method: "PATCH",
|
|
20930
|
+
path: "/api/spaces/:id/collections/:collectionId/items/:itemId",
|
|
20931
|
+
paramsSchema: CollectionItemParamsSchema,
|
|
20932
|
+
jsonSchema: UpdateCollectionItemRequestSchema,
|
|
20933
|
+
responseSchema: CollectionItemResponseSchema
|
|
20934
|
+
},
|
|
20935
|
+
"POST /api/spaces/:id/collections/:collectionId/items/reorder": {
|
|
20936
|
+
method: "POST",
|
|
20937
|
+
path: "/api/spaces/:id/collections/:collectionId/items/reorder",
|
|
20938
|
+
paramsSchema: CollectionIdParamsSchema,
|
|
20939
|
+
jsonSchema: ReorderItemsRequestSchema,
|
|
20940
|
+
responseSchema: ListCollectionItemsResponseSchema
|
|
20941
|
+
},
|
|
20942
|
+
"DELETE /api/spaces/:id/collections/:collectionId/items/:itemId": {
|
|
20943
|
+
method: "DELETE",
|
|
20944
|
+
path: "/api/spaces/:id/collections/:collectionId/items/:itemId",
|
|
20945
|
+
paramsSchema: CollectionItemParamsSchema,
|
|
20946
|
+
responseSchema: SuccessResponseSchema
|
|
20947
|
+
},
|
|
20948
|
+
"GET /api/spaces/:id/style-reference-collections": {
|
|
20949
|
+
method: "GET",
|
|
20950
|
+
path: "/api/spaces/:id/style-reference-collections",
|
|
20951
|
+
paramsSchema: SpaceIdParamsSchema,
|
|
20952
|
+
responseSchema: ListStyleReferenceCollectionsResponseSchema
|
|
20953
|
+
},
|
|
20954
|
+
"GET /api/spaces/:id/style-presets": {
|
|
20955
|
+
method: "GET",
|
|
20956
|
+
path: "/api/spaces/:id/style-presets",
|
|
20957
|
+
paramsSchema: SpaceIdParamsSchema,
|
|
20958
|
+
responseSchema: ListStylePresetsResponseSchema
|
|
20959
|
+
},
|
|
20960
|
+
"POST /api/spaces/:id/style-presets": {
|
|
20961
|
+
method: "POST",
|
|
20962
|
+
path: "/api/spaces/:id/style-presets",
|
|
20963
|
+
paramsSchema: SpaceIdParamsSchema,
|
|
20964
|
+
jsonSchema: UpsertStylePresetRequestSchema,
|
|
20965
|
+
responseSchema: StylePresetResponseSchema
|
|
20966
|
+
},
|
|
20967
|
+
"PATCH /api/spaces/:id/style-presets/:presetId": {
|
|
20968
|
+
method: "PATCH",
|
|
20969
|
+
path: "/api/spaces/:id/style-presets/:presetId",
|
|
20970
|
+
paramsSchema: StylePresetParamsSchema,
|
|
20971
|
+
jsonSchema: UpdateStylePresetRequestSchema,
|
|
20972
|
+
responseSchema: StylePresetResponseSchema
|
|
20973
|
+
},
|
|
20974
|
+
"DELETE /api/spaces/:id/style-presets/:presetId": {
|
|
20975
|
+
method: "DELETE",
|
|
20976
|
+
path: "/api/spaces/:id/style-presets/:presetId",
|
|
20977
|
+
paramsSchema: StylePresetParamsSchema,
|
|
20978
|
+
responseSchema: SuccessResponseSchema
|
|
20979
|
+
},
|
|
20980
|
+
"GET /api/spaces/:id/relations": {
|
|
20981
|
+
method: "GET",
|
|
20982
|
+
path: "/api/spaces/:id/relations",
|
|
20983
|
+
paramsSchema: SpaceIdParamsSchema,
|
|
20984
|
+
responseSchema: ListRelationsResponseSchema
|
|
20985
|
+
},
|
|
20986
|
+
"POST /api/spaces/:id/relations": {
|
|
20987
|
+
method: "POST",
|
|
20988
|
+
path: "/api/spaces/:id/relations",
|
|
20989
|
+
paramsSchema: SpaceIdParamsSchema,
|
|
20990
|
+
jsonSchema: UpsertRelationRequestSchema,
|
|
20991
|
+
responseSchema: RelationResponseSchema
|
|
20992
|
+
},
|
|
20993
|
+
"PATCH /api/spaces/:id/relations/:relationId": {
|
|
20994
|
+
method: "PATCH",
|
|
20995
|
+
path: "/api/spaces/:id/relations/:relationId",
|
|
20996
|
+
paramsSchema: RelationParamsSchema,
|
|
20997
|
+
jsonSchema: UpdateRelationRequestSchema,
|
|
20998
|
+
responseSchema: RelationResponseSchema
|
|
20999
|
+
},
|
|
21000
|
+
"DELETE /api/spaces/:id/relations/:relationId": {
|
|
21001
|
+
method: "DELETE",
|
|
21002
|
+
path: "/api/spaces/:id/relations/:relationId",
|
|
21003
|
+
paramsSchema: RelationParamsSchema,
|
|
21004
|
+
responseSchema: SuccessResponseSchema
|
|
21005
|
+
},
|
|
21006
|
+
"GET /api/spaces/:id/compositions": {
|
|
21007
|
+
method: "GET",
|
|
21008
|
+
path: "/api/spaces/:id/compositions",
|
|
21009
|
+
paramsSchema: SpaceIdParamsSchema,
|
|
21010
|
+
responseSchema: ListCompositionsResponseSchema
|
|
21011
|
+
},
|
|
21012
|
+
"POST /api/spaces/:id/compositions": {
|
|
21013
|
+
method: "POST",
|
|
21014
|
+
path: "/api/spaces/:id/compositions",
|
|
21015
|
+
paramsSchema: SpaceIdParamsSchema,
|
|
21016
|
+
jsonSchema: UpsertCompositionRequestSchema,
|
|
21017
|
+
responseSchema: CompositionResponseSchema
|
|
21018
|
+
},
|
|
21019
|
+
"PATCH /api/spaces/:id/compositions/:compositionId": {
|
|
21020
|
+
method: "PATCH",
|
|
21021
|
+
path: "/api/spaces/:id/compositions/:compositionId",
|
|
21022
|
+
paramsSchema: CompositionIdParamsSchema,
|
|
21023
|
+
jsonSchema: UpdateCompositionRequestSchema,
|
|
21024
|
+
responseSchema: CompositionResponseSchema
|
|
21025
|
+
},
|
|
21026
|
+
"DELETE /api/spaces/:id/compositions/:compositionId": {
|
|
21027
|
+
method: "DELETE",
|
|
21028
|
+
path: "/api/spaces/:id/compositions/:compositionId",
|
|
21029
|
+
paramsSchema: CompositionIdParamsSchema,
|
|
21030
|
+
responseSchema: SuccessResponseSchema
|
|
21031
|
+
},
|
|
21032
|
+
"GET /api/spaces/:id/compositions/:compositionId/items": {
|
|
21033
|
+
method: "GET",
|
|
21034
|
+
path: "/api/spaces/:id/compositions/:compositionId/items",
|
|
21035
|
+
paramsSchema: CompositionIdParamsSchema,
|
|
21036
|
+
responseSchema: ListCompositionItemsResponseSchema
|
|
21037
|
+
},
|
|
21038
|
+
"POST /api/spaces/:id/compositions/:compositionId/items": {
|
|
21039
|
+
method: "POST",
|
|
21040
|
+
path: "/api/spaces/:id/compositions/:compositionId/items",
|
|
21041
|
+
paramsSchema: CompositionIdParamsSchema,
|
|
21042
|
+
jsonSchema: UpsertCompositionItemRequestSchema,
|
|
21043
|
+
responseSchema: CompositionItemResponseSchema
|
|
21044
|
+
},
|
|
21045
|
+
"PATCH /api/spaces/:id/compositions/:compositionId/items/:itemId": {
|
|
21046
|
+
method: "PATCH",
|
|
21047
|
+
path: "/api/spaces/:id/compositions/:compositionId/items/:itemId",
|
|
21048
|
+
paramsSchema: CompositionItemParamsSchema,
|
|
21049
|
+
jsonSchema: UpdateCompositionItemRequestSchema,
|
|
21050
|
+
responseSchema: CompositionItemResponseSchema
|
|
21051
|
+
},
|
|
21052
|
+
"POST /api/spaces/:id/compositions/:compositionId/items/reorder": {
|
|
21053
|
+
method: "POST",
|
|
21054
|
+
path: "/api/spaces/:id/compositions/:compositionId/items/reorder",
|
|
21055
|
+
paramsSchema: CompositionIdParamsSchema,
|
|
21056
|
+
jsonSchema: ReorderItemsRequestSchema,
|
|
21057
|
+
responseSchema: ListCompositionItemsResponseSchema
|
|
21058
|
+
},
|
|
21059
|
+
"DELETE /api/spaces/:id/compositions/:compositionId/items/:itemId": {
|
|
21060
|
+
method: "DELETE",
|
|
21061
|
+
path: "/api/spaces/:id/compositions/:compositionId/items/:itemId",
|
|
21062
|
+
paramsSchema: CompositionItemParamsSchema,
|
|
21063
|
+
responseSchema: SuccessResponseSchema
|
|
21064
|
+
},
|
|
21065
|
+
"GET /api/spaces/:id/usage/summary": {
|
|
21066
|
+
method: "GET",
|
|
21067
|
+
path: "/api/spaces/:id/usage/summary",
|
|
21068
|
+
paramsSchema: SpaceIdParamsSchema,
|
|
21069
|
+
querySchema: UsageSummaryQuerySchema,
|
|
21070
|
+
responseSchema: PlatformUsageSummaryResponseSchema
|
|
21071
|
+
},
|
|
21072
|
+
"GET /api/billing/status": {
|
|
21073
|
+
method: "GET",
|
|
21074
|
+
path: "/api/billing/status",
|
|
21075
|
+
responseSchema: BillingStatusResponseSchema
|
|
21076
|
+
},
|
|
21077
|
+
"GET /api/billing/usage": {
|
|
21078
|
+
method: "GET",
|
|
21079
|
+
path: "/api/billing/usage",
|
|
21080
|
+
responseSchema: BillingUsageResponseSchema
|
|
21081
|
+
},
|
|
21082
|
+
"GET /api/billing/checkout": {
|
|
21083
|
+
method: "GET",
|
|
21084
|
+
path: "/api/billing/checkout",
|
|
21085
|
+
querySchema: BillingUrlQuerySchema,
|
|
21086
|
+
responseSchema: BillingUrlResponseSchema
|
|
21087
|
+
},
|
|
21088
|
+
"GET /api/billing/portal": {
|
|
21089
|
+
method: "GET",
|
|
21090
|
+
path: "/api/billing/portal",
|
|
21091
|
+
querySchema: BillingUrlQuerySchema,
|
|
21092
|
+
responseSchema: BillingUrlResponseSchema
|
|
21093
|
+
},
|
|
21094
|
+
"GET /api/billing/spend/summary": {
|
|
21095
|
+
method: "GET",
|
|
21096
|
+
path: "/api/billing/spend/summary",
|
|
21097
|
+
querySchema: ProviderSpendSummaryQuerySchema,
|
|
21098
|
+
responseSchema: ProviderSpendSummaryResponseSchema
|
|
21099
|
+
},
|
|
19505
21100
|
"GET /api/spaces/:id/productions": {
|
|
19506
21101
|
method: "GET",
|
|
19507
21102
|
path: "/api/spaces/:id/productions",
|
|
@@ -19598,13 +21193,6 @@ var apiEndpoints = {
|
|
|
19598
21193
|
formSchema: UploadMediaRequestSchema,
|
|
19599
21194
|
responseSchema: UploadMediaResponseSchema
|
|
19600
21195
|
},
|
|
19601
|
-
"POST /api/spaces/:id/style-images": {
|
|
19602
|
-
method: "POST",
|
|
19603
|
-
path: "/api/spaces/:id/style-images",
|
|
19604
|
-
paramsSchema: SpaceIdParamsSchema,
|
|
19605
|
-
formSchema: UploadStyleImageRequestSchema,
|
|
19606
|
-
responseSchema: UploadStyleImageResponseSchema
|
|
19607
|
-
},
|
|
19608
21196
|
"GET /api/spaces/:spaceId/variants/:variantId/media": {
|
|
19609
21197
|
method: "GET",
|
|
19610
21198
|
path: "/api/spaces/:spaceId/variants/:variantId/media",
|
|
@@ -19648,6 +21236,17 @@ function resolveUrl(path, baseUrl) {
|
|
|
19648
21236
|
if (baseUrl) return new URL(path, baseUrl).toString();
|
|
19649
21237
|
return path;
|
|
19650
21238
|
}
|
|
21239
|
+
function appendQuery(path, query) {
|
|
21240
|
+
if (!query) return path;
|
|
21241
|
+
const params = new URLSearchParams();
|
|
21242
|
+
for (const [key, value] of Object.entries(query)) {
|
|
21243
|
+
if (value === void 0 || value === null) continue;
|
|
21244
|
+
params.set(key, String(value));
|
|
21245
|
+
}
|
|
21246
|
+
const search = params.toString();
|
|
21247
|
+
if (!search) return path;
|
|
21248
|
+
return `${path}${path.includes("?") ? "&" : "?"}${search}`;
|
|
21249
|
+
}
|
|
19651
21250
|
function buildFormData(form) {
|
|
19652
21251
|
const formData = new FormData();
|
|
19653
21252
|
for (const [key, value] of Object.entries(form)) {
|
|
@@ -19679,8 +21278,9 @@ async function apiFetch(key, ...args) {
|
|
|
19679
21278
|
const fetchImpl = options.fetch ?? fetch;
|
|
19680
21279
|
const params = "paramsSchema" in endpoint ? endpoint.paramsSchema.parse(options.params) : void 0;
|
|
19681
21280
|
const json = "jsonSchema" in endpoint ? endpoint.jsonSchema.parse(options.json) : void 0;
|
|
21281
|
+
const query = "querySchema" in endpoint ? endpoint.querySchema.parse(options.query ?? {}) : void 0;
|
|
19682
21282
|
const form = "formSchema" in endpoint ? endpoint.formSchema.parse(options.form) : void 0;
|
|
19683
|
-
const path = buildPath(endpoint.path, params);
|
|
21283
|
+
const path = appendQuery(buildPath(endpoint.path, params), query);
|
|
19684
21284
|
const headers = new Headers(options.headers);
|
|
19685
21285
|
const init = {
|
|
19686
21286
|
...options,
|
|
@@ -19691,6 +21291,7 @@ async function apiFetch(key, ...args) {
|
|
|
19691
21291
|
delete init.baseUrl;
|
|
19692
21292
|
delete init.fetch;
|
|
19693
21293
|
delete init.params;
|
|
21294
|
+
delete init.query;
|
|
19694
21295
|
delete init.json;
|
|
19695
21296
|
delete init.form;
|
|
19696
21297
|
if (json !== void 0) {
|
|
@@ -19710,7 +21311,7 @@ async function apiFetch(key, ...args) {
|
|
|
19710
21311
|
}
|
|
19711
21312
|
//#endregion
|
|
19712
21313
|
//#region src/cli/commands/productions.ts
|
|
19713
|
-
var defaultDeps$
|
|
21314
|
+
var defaultDeps$10 = {
|
|
19714
21315
|
loadConfig: loadStoredConfig,
|
|
19715
21316
|
loadProjectConfig,
|
|
19716
21317
|
resolveBaseUrl,
|
|
@@ -19724,12 +21325,12 @@ async function handleProductions(parsed) {
|
|
|
19724
21325
|
await executeProductions(parsed);
|
|
19725
21326
|
} catch (error) {
|
|
19726
21327
|
console.error("Error:", error instanceof Error ? error.message : error);
|
|
19727
|
-
printUsage$
|
|
21328
|
+
printUsage$10();
|
|
19728
21329
|
process$1.exitCode = 1;
|
|
19729
21330
|
}
|
|
19730
21331
|
}
|
|
19731
|
-
async function executeProductions(parsed, deps = defaultDeps$
|
|
19732
|
-
const ctx = await buildContext$
|
|
21332
|
+
async function executeProductions(parsed, deps = defaultDeps$10) {
|
|
21333
|
+
const ctx = await buildContext$7(parsed, deps);
|
|
19733
21334
|
const subcommand = parsed.positionals[0] || "list";
|
|
19734
21335
|
if (subcommand === "list") {
|
|
19735
21336
|
const records = await listProductionRecords(ctx, deps, readProductionId(parsed, 1));
|
|
@@ -19802,7 +21403,7 @@ async function placeProductionRecordForCli(input) {
|
|
|
19802
21403
|
}
|
|
19803
21404
|
})).record;
|
|
19804
21405
|
}
|
|
19805
|
-
async function buildContext$
|
|
21406
|
+
async function buildContext$7(parsed, deps) {
|
|
19806
21407
|
const projectConfig = await deps.loadProjectConfig();
|
|
19807
21408
|
const env = resolveCommandEnvironment(parsed, projectConfig);
|
|
19808
21409
|
const spaceId = resolveCommandSpace(parsed, projectConfig);
|
|
@@ -19861,10 +21462,10 @@ function readProductionId(parsed, positionalIndex) {
|
|
|
19861
21462
|
return productionId;
|
|
19862
21463
|
}
|
|
19863
21464
|
function parsePlaceRequest(parsed) {
|
|
19864
|
-
const productionId = readRequiredOption(parsed, "production-id", "productionId");
|
|
19865
|
-
const variantId = readRequiredOption(parsed, "variant", "variantId");
|
|
19866
|
-
const sceneLabel = readRequiredOption(parsed, "scene-label", "sceneLabel");
|
|
19867
|
-
const timelineStartMs = parseNonNegativeInteger$1(readRequiredOption(parsed, "timeline-start-ms", "timelineStartMs"), "--timeline-start-ms");
|
|
21465
|
+
const productionId = readRequiredOption$1(parsed, "production-id", "productionId");
|
|
21466
|
+
const variantId = readRequiredOption$1(parsed, "variant", "variantId");
|
|
21467
|
+
const sceneLabel = readRequiredOption$1(parsed, "scene-label", "sceneLabel");
|
|
21468
|
+
const timelineStartMs = parseNonNegativeInteger$1(readRequiredOption$1(parsed, "timeline-start-ms", "timelineStartMs"), "--timeline-start-ms");
|
|
19868
21469
|
const durationValue = readOptionalOption$1(parsed, "duration-ms", "durationMs");
|
|
19869
21470
|
return {
|
|
19870
21471
|
id: readOptionalOption$1(parsed, "id", "id"),
|
|
@@ -19880,7 +21481,7 @@ function parsePlaceRequest(parsed) {
|
|
|
19880
21481
|
metadata: parseMetadataJson(readOptionalOption$1(parsed, "metadata-json", "metadataJson"))
|
|
19881
21482
|
};
|
|
19882
21483
|
}
|
|
19883
|
-
function readRequiredOption(parsed, kebabName, camelName) {
|
|
21484
|
+
function readRequiredOption$1(parsed, kebabName, camelName) {
|
|
19884
21485
|
const value = readOptionalOption$1(parsed, kebabName, camelName);
|
|
19885
21486
|
if (value === void 0) throw new Error(`--${kebabName} is required`);
|
|
19886
21487
|
return value;
|
|
@@ -20025,7 +21626,7 @@ function parseJsonObject$1(value) {
|
|
|
20025
21626
|
function shellQuote$1(value) {
|
|
20026
21627
|
return `'${value.replace(/'/g, "'\\''")}'`;
|
|
20027
21628
|
}
|
|
20028
|
-
function printUsage$
|
|
21629
|
+
function printUsage$10() {
|
|
20029
21630
|
console.log(`
|
|
20030
21631
|
Usage:
|
|
20031
21632
|
makefx productions list --production-id <id>
|
|
@@ -20230,6 +21831,7 @@ var WebSocketClient = class WebSocketClient {
|
|
|
20230
21831
|
chatHandlers = /* @__PURE__ */ new Map();
|
|
20231
21832
|
generateHandlers = /* @__PURE__ */ new Map();
|
|
20232
21833
|
batchHandlers = /* @__PURE__ */ new Map();
|
|
21834
|
+
estimateHandlers = /* @__PURE__ */ new Map();
|
|
20233
21835
|
batchVariantToRequestId = /* @__PURE__ */ new Map();
|
|
20234
21836
|
variantCompletionHandlers = /* @__PURE__ */ new Map();
|
|
20235
21837
|
describeHandlers = /* @__PURE__ */ new Map();
|
|
@@ -20430,6 +22032,16 @@ var WebSocketClient = class WebSocketClient {
|
|
|
20430
22032
|
}
|
|
20431
22033
|
break;
|
|
20432
22034
|
}
|
|
22035
|
+
case "generation:estimate": {
|
|
22036
|
+
const estimateMsg = message;
|
|
22037
|
+
const handler = this.estimateHandlers.get(estimateMsg.requestId);
|
|
22038
|
+
if (handler) {
|
|
22039
|
+
this.estimateHandlers.delete(estimateMsg.requestId);
|
|
22040
|
+
clearTimeout(handler.timeout);
|
|
22041
|
+
handler.resolve(estimateMsg);
|
|
22042
|
+
}
|
|
22043
|
+
break;
|
|
22044
|
+
}
|
|
20433
22045
|
case "variant:updated": {
|
|
20434
22046
|
const variant = message.variant;
|
|
20435
22047
|
const batchRequestId = this.batchVariantToRequestId.get(variant.id);
|
|
@@ -20519,7 +22131,8 @@ var WebSocketClient = class WebSocketClient {
|
|
|
20519
22131
|
const error = /* @__PURE__ */ new Error(`${errorMsg.code}: ${errorMsg.message}`);
|
|
20520
22132
|
const mutationConsumed = this.failMutationWaiters(error);
|
|
20521
22133
|
const pipelineConsumed = this.failPipelineHandlers(error);
|
|
20522
|
-
|
|
22134
|
+
const estimateConsumed = this.failEstimateHandlers(error);
|
|
22135
|
+
if (!(mutationConsumed || pipelineConsumed || estimateConsumed)) {
|
|
20523
22136
|
console.error(`[WebSocketClient] Server error: ${errorMsg.code} - ${errorMsg.message}`);
|
|
20524
22137
|
this.onError?.(new Error(errorMsg.message));
|
|
20525
22138
|
}
|
|
@@ -20616,6 +22229,15 @@ var WebSocketClient = class WebSocketClient {
|
|
|
20616
22229
|
this.tileSetToRequestId.clear();
|
|
20617
22230
|
return true;
|
|
20618
22231
|
}
|
|
22232
|
+
failEstimateHandlers(error) {
|
|
22233
|
+
if (this.estimateHandlers.size === 0) return false;
|
|
22234
|
+
for (const [requestId, handler] of this.estimateHandlers) {
|
|
22235
|
+
clearTimeout(handler.timeout);
|
|
22236
|
+
this.estimateHandlers.delete(requestId);
|
|
22237
|
+
handler.reject(error);
|
|
22238
|
+
}
|
|
22239
|
+
return true;
|
|
22240
|
+
}
|
|
20619
22241
|
handleRotationPipelineMessage(message) {
|
|
20620
22242
|
if (message.type === "rotation:started") {
|
|
20621
22243
|
const handler = this.rotationHandlers.get(message.requestId);
|
|
@@ -20874,6 +22496,8 @@ var WebSocketClient = class WebSocketClient {
|
|
|
20874
22496
|
subjectDescription: params.subjectDescription,
|
|
20875
22497
|
aspectRatio: params.aspectRatio,
|
|
20876
22498
|
disableStyle: params.disableStyle,
|
|
22499
|
+
stylePresetId: params.stylePresetId,
|
|
22500
|
+
styleVariantIds: params.styleVariantIds,
|
|
20877
22501
|
generationMode: params.generationMode
|
|
20878
22502
|
});
|
|
20879
22503
|
} catch (err) {
|
|
@@ -20921,6 +22545,8 @@ var WebSocketClient = class WebSocketClient {
|
|
|
20921
22545
|
seedVariantId: params.seedVariantId,
|
|
20922
22546
|
aspectRatio: params.aspectRatio,
|
|
20923
22547
|
disableStyle: params.disableStyle,
|
|
22548
|
+
stylePresetId: params.stylePresetId,
|
|
22549
|
+
styleVariantIds: params.styleVariantIds,
|
|
20924
22550
|
generationMode: params.generationMode
|
|
20925
22551
|
});
|
|
20926
22552
|
} catch (err) {
|
|
@@ -20975,6 +22601,46 @@ var WebSocketClient = class WebSocketClient {
|
|
|
20975
22601
|
}, 12e4);
|
|
20976
22602
|
});
|
|
20977
22603
|
}
|
|
22604
|
+
async sendGenerationEstimateRequest(params) {
|
|
22605
|
+
const requestId = crypto.randomUUID();
|
|
22606
|
+
return new Promise((resolve, reject) => {
|
|
22607
|
+
const timeout = setTimeout(() => {
|
|
22608
|
+
if (this.estimateHandlers.has(requestId)) {
|
|
22609
|
+
this.estimateHandlers.delete(requestId);
|
|
22610
|
+
reject(/* @__PURE__ */ new Error("Generation estimate request timed out"));
|
|
22611
|
+
}
|
|
22612
|
+
}, 3e4);
|
|
22613
|
+
this.estimateHandlers.set(requestId, {
|
|
22614
|
+
resolve,
|
|
22615
|
+
reject,
|
|
22616
|
+
timeout
|
|
22617
|
+
});
|
|
22618
|
+
const message = {
|
|
22619
|
+
type: "generation:estimate",
|
|
22620
|
+
requestId,
|
|
22621
|
+
operation: params.operation,
|
|
22622
|
+
assetId: params.assetId,
|
|
22623
|
+
assetType: params.assetType,
|
|
22624
|
+
mediaKind: params.mediaKind,
|
|
22625
|
+
prompt: params.prompt,
|
|
22626
|
+
count: params.count,
|
|
22627
|
+
model: params.model,
|
|
22628
|
+
imageSize: params.imageSize,
|
|
22629
|
+
musicProvider: params.musicProvider,
|
|
22630
|
+
generateAudio: params.generateAudio,
|
|
22631
|
+
videoResolution: params.videoResolution,
|
|
22632
|
+
videoDurationSeconds: params.videoDurationSeconds,
|
|
22633
|
+
videoTier: params.videoTier
|
|
22634
|
+
};
|
|
22635
|
+
try {
|
|
22636
|
+
this.send(message);
|
|
22637
|
+
} catch (err) {
|
|
22638
|
+
this.estimateHandlers.delete(requestId);
|
|
22639
|
+
clearTimeout(timeout);
|
|
22640
|
+
reject(err);
|
|
22641
|
+
}
|
|
22642
|
+
});
|
|
22643
|
+
}
|
|
20978
22644
|
/**
|
|
20979
22645
|
* Send a generate request and wait for result
|
|
20980
22646
|
*/
|
|
@@ -21011,8 +22677,9 @@ var WebSocketClient = class WebSocketClient {
|
|
|
21011
22677
|
model: params.model,
|
|
21012
22678
|
aspectRatio: params.aspectRatio,
|
|
21013
22679
|
imageSize: params.imageSize,
|
|
21014
|
-
parentAssetId: params.parentAssetId,
|
|
21015
22680
|
disableStyle: params.disableStyle,
|
|
22681
|
+
stylePresetId: params.stylePresetId,
|
|
22682
|
+
styleVariantIds: params.styleVariantIds,
|
|
21016
22683
|
mediaKind: params.mediaKind,
|
|
21017
22684
|
voiceId: params.voiceId,
|
|
21018
22685
|
dialogueVoiceIds: params.dialogueVoiceIds,
|
|
@@ -21096,6 +22763,8 @@ var WebSocketClient = class WebSocketClient {
|
|
|
21096
22763
|
aspectRatio: params.aspectRatio,
|
|
21097
22764
|
imageSize: params.imageSize,
|
|
21098
22765
|
disableStyle: params.disableStyle,
|
|
22766
|
+
stylePresetId: params.stylePresetId,
|
|
22767
|
+
styleVariantIds: params.styleVariantIds,
|
|
21099
22768
|
mediaKind: params.mediaKind,
|
|
21100
22769
|
voiceId: params.voiceId,
|
|
21101
22770
|
dialogueVoiceIds: params.dialogueVoiceIds,
|
|
@@ -21148,8 +22817,9 @@ var WebSocketClient = class WebSocketClient {
|
|
|
21148
22817
|
model: params.model,
|
|
21149
22818
|
aspectRatio: params.aspectRatio,
|
|
21150
22819
|
imageSize: params.imageSize,
|
|
21151
|
-
parentAssetId: params.parentAssetId,
|
|
21152
22820
|
disableStyle: params.disableStyle,
|
|
22821
|
+
stylePresetId: params.stylePresetId,
|
|
22822
|
+
styleVariantIds: params.styleVariantIds,
|
|
21153
22823
|
mediaKind: params.mediaKind,
|
|
21154
22824
|
voiceId: params.voiceId,
|
|
21155
22825
|
dialogueVoiceIds: params.dialogueVoiceIds,
|
|
@@ -21575,7 +23245,7 @@ function cliGenerationSupportsRefs(namespace) {
|
|
|
21575
23245
|
//#endregion
|
|
21576
23246
|
//#region src/cli/commands/forge.ts
|
|
21577
23247
|
var CLI_GENERATION_MEDIA_KIND = getCliGenerationMediaKind("top-level");
|
|
21578
|
-
var defaultDeps$
|
|
23248
|
+
var defaultDeps$9 = {
|
|
21579
23249
|
loadConfig: loadStoredConfig,
|
|
21580
23250
|
loadProjectConfig,
|
|
21581
23251
|
resolveBaseUrl,
|
|
@@ -21585,6 +23255,7 @@ var defaultDeps$6 = {
|
|
|
21585
23255
|
downloadFile,
|
|
21586
23256
|
saveRunManifest,
|
|
21587
23257
|
placeProductionRecord: placeProductionRecordForCli,
|
|
23258
|
+
fetch,
|
|
21588
23259
|
createRunId,
|
|
21589
23260
|
getWorkingDir: () => process$1.cwd(),
|
|
21590
23261
|
fileExists: async (filePath) => {
|
|
@@ -21596,6 +23267,43 @@ var defaultDeps$6 = {
|
|
|
21596
23267
|
}
|
|
21597
23268
|
}
|
|
21598
23269
|
};
|
|
23270
|
+
var ESTIMATE_METER_LABELS = {
|
|
23271
|
+
gemini_images: "Gemini image",
|
|
23272
|
+
gemini_videos: "Veo video unit",
|
|
23273
|
+
gemini_audio: "Lyria generation",
|
|
23274
|
+
elevenlabs_audio: "ElevenLabs unit"
|
|
23275
|
+
};
|
|
23276
|
+
function formatEstimatedUsd(microUsd) {
|
|
23277
|
+
if (!Number.isFinite(microUsd) || microUsd <= 0) return "$0.00";
|
|
23278
|
+
if (microUsd < 1e4) return "<$0.01";
|
|
23279
|
+
return `$${(microUsd / 1e6).toFixed(2)}`;
|
|
23280
|
+
}
|
|
23281
|
+
function formatEstimateQuantity(quantity, singular) {
|
|
23282
|
+
const normalized = Number.isFinite(quantity) ? quantity : 0;
|
|
23283
|
+
const suffix = normalized === 1 ? singular : `${singular}s`;
|
|
23284
|
+
return `${normalized.toLocaleString()} ${suffix}`;
|
|
23285
|
+
}
|
|
23286
|
+
async function printPreflightEstimate(client, params) {
|
|
23287
|
+
let result;
|
|
23288
|
+
try {
|
|
23289
|
+
result = await client.sendGenerationEstimateRequest(params);
|
|
23290
|
+
} catch (error) {
|
|
23291
|
+
console.warn(`Preflight estimate unavailable: ${error instanceof Error ? error.message : String(error)}`);
|
|
23292
|
+
return;
|
|
23293
|
+
}
|
|
23294
|
+
if (!result.success || !result.estimate) {
|
|
23295
|
+
console.warn(`Preflight estimate unavailable: ${result.error || "unknown error"}`);
|
|
23296
|
+
return;
|
|
23297
|
+
}
|
|
23298
|
+
const estimate = result.estimate;
|
|
23299
|
+
const meterLabel = ESTIMATE_METER_LABELS[estimate.meterEventName] ?? estimate.meterEventName;
|
|
23300
|
+
const quotaLine = estimate.quota?.limit === null || estimate.quota?.limit === void 0 ? void 0 : `${estimate.quota.used.toLocaleString()} used / ${estimate.quota.limit.toLocaleString()} limit`;
|
|
23301
|
+
console.log("Preflight estimate:");
|
|
23302
|
+
console.log(` Usage: ${formatEstimateQuantity(estimate.quotaQuantity, meterLabel)}, ${formatEstimateQuantity(estimate.platformWorkflowRuns, "workflow")}`);
|
|
23303
|
+
console.log(` Estimated provider cost: ${formatEstimatedUsd(estimate.providerCostMicroUsd)}${estimate.billingMode === "byok" ? " (BYOK)" : ""}`);
|
|
23304
|
+
if (quotaLine) console.log(` Quota: ${quotaLine}`);
|
|
23305
|
+
if (!estimate.allowed) throw new Error(estimate.denyMessage || "Preflight check denied this generation request");
|
|
23306
|
+
}
|
|
21599
23307
|
async function handleGenerate(parsed) {
|
|
21600
23308
|
await handleForgeCommand("generate", parsed);
|
|
21601
23309
|
}
|
|
@@ -21610,18 +23318,18 @@ async function handleBatch(parsed) {
|
|
|
21610
23318
|
}
|
|
21611
23319
|
async function handleForgeCommand(command, parsed) {
|
|
21612
23320
|
try {
|
|
21613
|
-
await executeForgeCommand(command, parsed, defaultDeps$
|
|
23321
|
+
await executeForgeCommand(command, parsed, defaultDeps$9);
|
|
21614
23322
|
} catch (error) {
|
|
21615
23323
|
console.error("Error:", error instanceof Error ? error.message : error);
|
|
21616
|
-
printUsage$
|
|
23324
|
+
printUsage$9(command);
|
|
21617
23325
|
process$1.exitCode = 1;
|
|
21618
23326
|
}
|
|
21619
23327
|
}
|
|
21620
|
-
async function executeForgeCommand(command, parsed, deps = defaultDeps$
|
|
23328
|
+
async function executeForgeCommand(command, parsed, deps = defaultDeps$9, options = {}) {
|
|
21621
23329
|
const mediaKind = options.mediaKind || CLI_GENERATION_MEDIA_KIND;
|
|
21622
23330
|
if (parsed.options.follow) {
|
|
21623
23331
|
if (command === "batch") throw new Error("--follow is only supported for single-output generation commands");
|
|
21624
|
-
const ctx = await buildContext$
|
|
23332
|
+
const ctx = await buildContext$6(parsed, deps);
|
|
21625
23333
|
const client = await deps.createClient(ctx.env, ctx.spaceId);
|
|
21626
23334
|
try {
|
|
21627
23335
|
await client.connect();
|
|
@@ -21635,7 +23343,7 @@ async function executeForgeCommand(command, parsed, deps = defaultDeps$6, option
|
|
|
21635
23343
|
validateVideoAudioOptions(parsed, mediaKind);
|
|
21636
23344
|
parseVideoGenerationOptions(parsed, mediaKind);
|
|
21637
23345
|
if (command !== "batch") validateProductionMetadataOptions(parsed);
|
|
21638
|
-
const ctx = await buildContext$
|
|
23346
|
+
const ctx = await buildContext$6(parsed, deps);
|
|
21639
23347
|
const client = await deps.createClient(ctx.env, ctx.spaceId);
|
|
21640
23348
|
try {
|
|
21641
23349
|
await client.connect();
|
|
@@ -21649,7 +23357,7 @@ async function executeForgeCommand(command, parsed, deps = defaultDeps$6, option
|
|
|
21649
23357
|
client.disconnect();
|
|
21650
23358
|
}
|
|
21651
23359
|
}
|
|
21652
|
-
async function executeAudioCommand(command, parsed, deps = defaultDeps$
|
|
23360
|
+
async function executeAudioCommand(command, parsed, deps = defaultDeps$9, options = {}) {
|
|
21653
23361
|
const audioProfile = getCliGenerationProfile("audio");
|
|
21654
23362
|
if (!audioProfile.commands.includes(command)) throw new Error(`Audio generation does not support ${command}`);
|
|
21655
23363
|
const modeEntry = options.mode ? getMediaOperationEntry(options.mode) : void 0;
|
|
@@ -21662,7 +23370,7 @@ async function executeAudioCommand(command, parsed, deps = defaultDeps$6, option
|
|
|
21662
23370
|
audioMode: options.mode
|
|
21663
23371
|
});
|
|
21664
23372
|
}
|
|
21665
|
-
async function executeVideoCommand(command, parsed, deps = defaultDeps$
|
|
23373
|
+
async function executeVideoCommand(command, parsed, deps = defaultDeps$9) {
|
|
21666
23374
|
const videoProfile = getCliGenerationProfile("video");
|
|
21667
23375
|
if (!videoProfile.commands.includes(command)) throw new Error(`Video generation does not support ${command}`);
|
|
21668
23376
|
return executeForgeCommand(command, parsed, deps, {
|
|
@@ -21708,6 +23416,20 @@ async function executeGenerate(parsed, ctx, client, deps, mediaKind, followOptio
|
|
|
21708
23416
|
const imageOptions = parseImageGenerationOptions(parsed, mediaKind);
|
|
21709
23417
|
const videoAudioOptions = parseVideoAudioOptions(parsed, mediaKind);
|
|
21710
23418
|
const videoOptions = parseVideoGenerationOptions(parsed, mediaKind);
|
|
23419
|
+
const styleSelection = await resolveStyleSelection(parsed, ctx, deps);
|
|
23420
|
+
await printPreflightEstimate(client, {
|
|
23421
|
+
operation: "generate",
|
|
23422
|
+
assetType,
|
|
23423
|
+
mediaKind,
|
|
23424
|
+
prompt,
|
|
23425
|
+
count: 1,
|
|
23426
|
+
model: imageOptions.model,
|
|
23427
|
+
imageSize: imageOptions.imageSize,
|
|
23428
|
+
...musicProvider ? { musicProvider } : {},
|
|
23429
|
+
...videoAudioOptions,
|
|
23430
|
+
...videoOptions
|
|
23431
|
+
});
|
|
23432
|
+
printStyleSelection(styleSelection);
|
|
21711
23433
|
console.log(`Generating "${name}" in space ${ctx.spaceId}...`);
|
|
21712
23434
|
const audioVoiceOptions = mediaKind === "audio" ? parseAudioVoiceOptions(parsed) : {};
|
|
21713
23435
|
const result = await client.sendGenerateRequest({
|
|
@@ -21716,8 +23438,8 @@ async function executeGenerate(parsed, ctx, client, deps, mediaKind, followOptio
|
|
|
21716
23438
|
prompt,
|
|
21717
23439
|
...imageOptions,
|
|
21718
23440
|
aspectRatio: imageOptions.aspectRatio ?? videoOptions.aspectRatio,
|
|
21719
|
-
parentAssetId: parsed.options.parent,
|
|
21720
23441
|
disableStyle: parsed.options["no-style"] === "true",
|
|
23442
|
+
...styleSelection.stylePresetId ? { stylePresetId: styleSelection.stylePresetId } : {},
|
|
21721
23443
|
mediaKind,
|
|
21722
23444
|
...audioVoiceOptions,
|
|
21723
23445
|
...musicProvider ? { musicProvider } : {},
|
|
@@ -21785,6 +23507,20 @@ async function executeRefine(parsed, ctx, client, deps, mediaKind) {
|
|
|
21785
23507
|
const imageOptions = parseImageGenerationOptions(parsed, mediaKind);
|
|
21786
23508
|
const videoAudioOptions = parseVideoAudioOptions(parsed, mediaKind);
|
|
21787
23509
|
const videoOptions = parseVideoGenerationOptions(parsed, mediaKind);
|
|
23510
|
+
const styleSelection = await resolveStyleSelection(parsed, ctx, deps);
|
|
23511
|
+
await printPreflightEstimate(client, {
|
|
23512
|
+
operation: "refine",
|
|
23513
|
+
assetId: sourceVariant.asset_id,
|
|
23514
|
+
assetType: sourceAsset?.type || void 0,
|
|
23515
|
+
mediaKind,
|
|
23516
|
+
prompt,
|
|
23517
|
+
count: 1,
|
|
23518
|
+
model: imageOptions.model,
|
|
23519
|
+
imageSize: imageOptions.imageSize,
|
|
23520
|
+
...videoAudioOptions,
|
|
23521
|
+
...videoOptions
|
|
23522
|
+
});
|
|
23523
|
+
printStyleSelection(styleSelection);
|
|
21788
23524
|
console.log(`Refining variant ${sourceVariantId}...`);
|
|
21789
23525
|
const result = await client.sendRefineRequest({
|
|
21790
23526
|
assetId: sourceVariant.asset_id,
|
|
@@ -21793,6 +23529,7 @@ async function executeRefine(parsed, ctx, client, deps, mediaKind) {
|
|
|
21793
23529
|
...imageOptions,
|
|
21794
23530
|
aspectRatio: imageOptions.aspectRatio ?? videoOptions.aspectRatio,
|
|
21795
23531
|
disableStyle: parsed.options["no-style"] === "true",
|
|
23532
|
+
...styleSelection.stylePresetId ? { stylePresetId: styleSelection.stylePresetId } : {},
|
|
21796
23533
|
mediaKind,
|
|
21797
23534
|
...videoAudioOptions,
|
|
21798
23535
|
...videoOptions,
|
|
@@ -21843,6 +23580,19 @@ async function executeDerive(parsed, ctx, client, deps, mediaKind, followOptions
|
|
|
21843
23580
|
});
|
|
21844
23581
|
const videoAudioOptions = parseVideoAudioOptions(parsed, mediaKind);
|
|
21845
23582
|
const videoOptions = parseVideoGenerationOptions(parsed, mediaKind);
|
|
23583
|
+
const styleSelection = await resolveStyleSelection(parsed, ctx, deps);
|
|
23584
|
+
await printPreflightEstimate(client, {
|
|
23585
|
+
operation: "derive",
|
|
23586
|
+
assetType,
|
|
23587
|
+
mediaKind,
|
|
23588
|
+
prompt,
|
|
23589
|
+
count: 1,
|
|
23590
|
+
model: imageOptions.model,
|
|
23591
|
+
imageSize: imageOptions.imageSize,
|
|
23592
|
+
...videoAudioOptions,
|
|
23593
|
+
...videoOptions
|
|
23594
|
+
});
|
|
23595
|
+
printStyleSelection(styleSelection);
|
|
21846
23596
|
console.log(`Deriving "${name}" from ${referenceVariantIds.length} reference(s)...`);
|
|
21847
23597
|
const result = await client.sendGenerateRequest({
|
|
21848
23598
|
name,
|
|
@@ -21851,8 +23601,8 @@ async function executeDerive(parsed, ctx, client, deps, mediaKind, followOptions
|
|
|
21851
23601
|
referenceVariantIds,
|
|
21852
23602
|
...imageOptions,
|
|
21853
23603
|
aspectRatio: imageOptions.aspectRatio ?? videoOptions.aspectRatio,
|
|
21854
|
-
parentAssetId: parsed.options.parent,
|
|
21855
23604
|
disableStyle: parsed.options["no-style"] === "true",
|
|
23605
|
+
...styleSelection.stylePresetId ? { stylePresetId: styleSelection.stylePresetId } : {},
|
|
21856
23606
|
mediaKind,
|
|
21857
23607
|
...videoAudioOptions,
|
|
21858
23608
|
...videoOptions,
|
|
@@ -22047,7 +23797,20 @@ async function executeBatch(parsed, ctx, client, deps, mediaKind, saveBatchManif
|
|
|
22047
23797
|
const referenceVariantIds = refs.length > 0 ? await resolveReferenceVariantIds(refs, ctx, deps, state.variants, mediaKind) : void 0;
|
|
22048
23798
|
const startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
22049
23799
|
const runId = deps.createRunId();
|
|
22050
|
-
|
|
23800
|
+
const styleSelection = await resolveStyleSelection(parsed, ctx, deps);
|
|
23801
|
+
await printPreflightEstimate(client, {
|
|
23802
|
+
operation: "batch",
|
|
23803
|
+
assetType,
|
|
23804
|
+
mediaKind,
|
|
23805
|
+
prompt,
|
|
23806
|
+
count,
|
|
23807
|
+
model: imageOptions.model,
|
|
23808
|
+
imageSize: imageOptions.imageSize,
|
|
23809
|
+
...musicProvider ? { musicProvider } : {}
|
|
23810
|
+
});
|
|
23811
|
+
const mediaLabel = mediaKind === "image" ? "image" : mediaKind === "video" ? "video" : "audio file";
|
|
23812
|
+
printStyleSelection(styleSelection);
|
|
23813
|
+
console.log(`Batch generating ${count} ${mediaLabel}(s) for "${name}"...`);
|
|
22051
23814
|
const audioVoiceOptions = mediaKind === "audio" ? parseAudioVoiceOptions(parsed) : {};
|
|
22052
23815
|
const result = await client.sendBatchRequest({
|
|
22053
23816
|
name,
|
|
@@ -22058,8 +23821,8 @@ async function executeBatch(parsed, ctx, client, deps, mediaKind, saveBatchManif
|
|
|
22058
23821
|
referenceVariantIds,
|
|
22059
23822
|
...imageOptions,
|
|
22060
23823
|
aspectRatio: imageOptions.aspectRatio,
|
|
22061
|
-
parentAssetId: parsed.options.parent,
|
|
22062
23824
|
disableStyle: parsed.options["no-style"] === "true",
|
|
23825
|
+
...styleSelection.stylePresetId ? { stylePresetId: styleSelection.stylePresetId } : {},
|
|
22063
23826
|
mediaKind,
|
|
22064
23827
|
...audioVoiceOptions,
|
|
22065
23828
|
...musicProvider ? { musicProvider } : {}
|
|
@@ -22177,7 +23940,7 @@ async function placeProductionRecordFromScene(input) {
|
|
|
22177
23940
|
record
|
|
22178
23941
|
});
|
|
22179
23942
|
}
|
|
22180
|
-
async function buildContext$
|
|
23943
|
+
async function buildContext$6(parsed, deps) {
|
|
22181
23944
|
const projectConfig = await deps.loadProjectConfig();
|
|
22182
23945
|
const env = resolveCommandEnvironment(parsed, projectConfig);
|
|
22183
23946
|
const spaceId = resolveCommandSpace(parsed, projectConfig);
|
|
@@ -22243,6 +24006,51 @@ function requestSpaceState(client) {
|
|
|
22243
24006
|
client.requestSync();
|
|
22244
24007
|
});
|
|
22245
24008
|
}
|
|
24009
|
+
async function resolveStyleSelection(parsed, ctx, deps) {
|
|
24010
|
+
const stylePresetRef = readStylePresetOption(parsed);
|
|
24011
|
+
if (parsed.options["no-style"] === "true") {
|
|
24012
|
+
if (stylePresetRef) throw new Error("--style-preset cannot be used with --no-style");
|
|
24013
|
+
return {};
|
|
24014
|
+
}
|
|
24015
|
+
if (!stylePresetRef) return {};
|
|
24016
|
+
const presets = (await apiFetch("GET /api/spaces/:id/style-presets", {
|
|
24017
|
+
baseUrl: ctx.baseUrl,
|
|
24018
|
+
fetch: deps.fetch ?? fetch,
|
|
24019
|
+
params: { id: ctx.spaceId },
|
|
24020
|
+
headers: {
|
|
24021
|
+
"Authorization": `Bearer ${ctx.accessToken}`,
|
|
24022
|
+
"Accept": "application/json"
|
|
24023
|
+
}
|
|
24024
|
+
})).presets;
|
|
24025
|
+
const byId = presets.find((preset) => preset.id === stylePresetRef);
|
|
24026
|
+
const byName = presets.filter((preset) => preset.name === stylePresetRef);
|
|
24027
|
+
const preset = byId ?? (byName.length === 1 ? byName[0] : void 0);
|
|
24028
|
+
if (!preset) {
|
|
24029
|
+
if (byName.length > 1) throw new Error(`Style preset name is ambiguous: ${stylePresetRef}. Use a preset ID.`);
|
|
24030
|
+
throw new Error(`Style preset not found: ${stylePresetRef}`);
|
|
24031
|
+
}
|
|
24032
|
+
if (!isTruthyFlag(preset.enabled)) throw new Error(`Style preset is disabled: ${preset.name} (${preset.id})`);
|
|
24033
|
+
return {
|
|
24034
|
+
stylePresetId: preset.id,
|
|
24035
|
+
preset
|
|
24036
|
+
};
|
|
24037
|
+
}
|
|
24038
|
+
function readStylePresetOption(parsed) {
|
|
24039
|
+
return readOptionalOption(parsed, "style-preset", "stylePreset") ?? readOptionalOption(parsed, "preset", "preset");
|
|
24040
|
+
}
|
|
24041
|
+
function printStyleSelection(selection) {
|
|
24042
|
+
if (selection.preset) {
|
|
24043
|
+
const preset = selection.preset;
|
|
24044
|
+
const defaultLabel = isTruthyFlag(preset.is_default) ? ", default" : "";
|
|
24045
|
+
console.log(`Style preset: ${preset.name} (${preset.id}${defaultLabel})`);
|
|
24046
|
+
console.log(` References: ${preset.reference_count}`);
|
|
24047
|
+
console.log(` Collection: ${preset.collection_name || "-"}`);
|
|
24048
|
+
return;
|
|
24049
|
+
}
|
|
24050
|
+
}
|
|
24051
|
+
function isTruthyFlag(value) {
|
|
24052
|
+
return value === true || value === 1;
|
|
24053
|
+
}
|
|
22246
24054
|
async function downloadResult(result, outputPath, ctx, deps) {
|
|
22247
24055
|
const variant = result.variant;
|
|
22248
24056
|
if (!result.success || !variant) throw new Error(result.error || "Generation failed without a completed variant");
|
|
@@ -22528,7 +24336,7 @@ function cliImageSizeValues() {
|
|
|
22528
24336
|
function cliImageAspectValues() {
|
|
22529
24337
|
return cliOptionValues(getImageModelCapabilities().supportedAspectRatios);
|
|
22530
24338
|
}
|
|
22531
|
-
function printUsage$
|
|
24339
|
+
function printUsage$9(command) {
|
|
22532
24340
|
if (command === "generate") {
|
|
22533
24341
|
console.log(`
|
|
22534
24342
|
Usage:
|
|
@@ -22581,7 +24389,7 @@ function printBatchResult(result, outputDir, manifestPath, ctx, mediaKind) {
|
|
|
22581
24389
|
}
|
|
22582
24390
|
//#endregion
|
|
22583
24391
|
//#region src/cli/commands/audio.ts
|
|
22584
|
-
var defaultDeps$
|
|
24392
|
+
var defaultDeps$8 = {
|
|
22585
24393
|
loadConfig: loadStoredConfig,
|
|
22586
24394
|
loadProjectConfig,
|
|
22587
24395
|
resolveBaseUrl,
|
|
@@ -22594,11 +24402,11 @@ async function handleAudio(parsed) {
|
|
|
22594
24402
|
await executeAudio(parsed);
|
|
22595
24403
|
} catch (error) {
|
|
22596
24404
|
console.error("Error:", error instanceof Error ? error.message : error);
|
|
22597
|
-
printUsage$
|
|
24405
|
+
printUsage$8();
|
|
22598
24406
|
process$1.exitCode = 1;
|
|
22599
24407
|
}
|
|
22600
24408
|
}
|
|
22601
|
-
async function executeAudio(parsed, deps = defaultDeps$
|
|
24409
|
+
async function executeAudio(parsed, deps = defaultDeps$8) {
|
|
22602
24410
|
const invocation = parseAudioInvocation(parsed.positionals);
|
|
22603
24411
|
if (invocation.command === "voices") return executeAudioVoices({
|
|
22604
24412
|
...parsed,
|
|
@@ -22671,7 +24479,7 @@ function printVoices(response, print) {
|
|
|
22671
24479
|
function formatLabels(labels) {
|
|
22672
24480
|
return Object.entries(labels).map(([key, value]) => `${key}:${value}`).join(", ");
|
|
22673
24481
|
}
|
|
22674
|
-
function printUsage$
|
|
24482
|
+
function printUsage$8() {
|
|
22675
24483
|
const modes = AUDIO_FORGE_MEDIA_MODES.join("|");
|
|
22676
24484
|
console.log(`
|
|
22677
24485
|
Usage:
|
|
@@ -22700,7 +24508,7 @@ async function handleVideo(parsed) {
|
|
|
22700
24508
|
});
|
|
22701
24509
|
} catch (error) {
|
|
22702
24510
|
console.error("Error:", error instanceof Error ? error.message : error);
|
|
22703
|
-
printUsage$
|
|
24511
|
+
printUsage$7();
|
|
22704
24512
|
process$1.exitCode = 1;
|
|
22705
24513
|
}
|
|
22706
24514
|
}
|
|
@@ -22709,7 +24517,7 @@ function parseVideoCommand(value) {
|
|
|
22709
24517
|
if (value && commands.includes(value)) return value;
|
|
22710
24518
|
throw new Error("Video command is required: generate, refine, or derive");
|
|
22711
24519
|
}
|
|
22712
|
-
function printUsage$
|
|
24520
|
+
function printUsage$7() {
|
|
22713
24521
|
const aspectValues = VIDEO_GENERATION_ASPECT_RATIOS.join("|");
|
|
22714
24522
|
const resolutionValues = Array.from(new Set(VIDEO_GENERATION_TIERS.flatMap((tier) => getVideoGenerationResolutionsForTier(tier)))).join("|");
|
|
22715
24523
|
const durationValues = VIDEO_GENERATION_DURATION_SECONDS.join("|");
|
|
@@ -22741,17 +24549,17 @@ Production metadata:
|
|
|
22741
24549
|
}
|
|
22742
24550
|
//#endregion
|
|
22743
24551
|
//#region src/cli/commands/init.ts
|
|
22744
|
-
var defaultDeps$
|
|
24552
|
+
var defaultDeps$7 = { saveProjectConfig };
|
|
22745
24553
|
async function handleInit(parsed) {
|
|
22746
24554
|
try {
|
|
22747
24555
|
await executeInit(parsed);
|
|
22748
24556
|
} catch (error) {
|
|
22749
24557
|
console.error("Error:", error instanceof Error ? error.message : error);
|
|
22750
|
-
printUsage$
|
|
24558
|
+
printUsage$6();
|
|
22751
24559
|
process$1.exitCode = 1;
|
|
22752
24560
|
}
|
|
22753
24561
|
}
|
|
22754
|
-
async function executeInit(parsed, deps = defaultDeps$
|
|
24562
|
+
async function executeInit(parsed, deps = defaultDeps$7) {
|
|
22755
24563
|
const environment = resolveCommandEnvironment(parsed);
|
|
22756
24564
|
const spaceId = resolveCommandSpace(parsed);
|
|
22757
24565
|
if (!spaceId) throw new Error("--space is required");
|
|
@@ -22777,7 +24585,7 @@ async function executeInit(parsed, deps = defaultDeps$4) {
|
|
|
22777
24585
|
spaceId
|
|
22778
24586
|
};
|
|
22779
24587
|
}
|
|
22780
|
-
function printUsage$
|
|
24588
|
+
function printUsage$6() {
|
|
22781
24589
|
console.log(`
|
|
22782
24590
|
Usage:
|
|
22783
24591
|
makefx init --space <id> [--env production|stage|local]
|
|
@@ -22786,7 +24594,7 @@ Usage:
|
|
|
22786
24594
|
}
|
|
22787
24595
|
//#endregion
|
|
22788
24596
|
//#region src/cli/commands/runs.ts
|
|
22789
|
-
var defaultDeps$
|
|
24597
|
+
var defaultDeps$6 = {
|
|
22790
24598
|
loadProjectConfig,
|
|
22791
24599
|
listRunManifests,
|
|
22792
24600
|
readRunManifest,
|
|
@@ -22799,11 +24607,11 @@ async function handleRuns(parsed) {
|
|
|
22799
24607
|
await executeRuns(parsed);
|
|
22800
24608
|
} catch (error) {
|
|
22801
24609
|
console.error("Error:", error instanceof Error ? error.message : error);
|
|
22802
|
-
printUsage$
|
|
24610
|
+
printUsage$5();
|
|
22803
24611
|
process$1.exitCode = 1;
|
|
22804
24612
|
}
|
|
22805
24613
|
}
|
|
22806
|
-
async function executeRuns(parsed, deps = defaultDeps$
|
|
24614
|
+
async function executeRuns(parsed, deps = defaultDeps$6) {
|
|
22807
24615
|
const projectConfig = await deps.loadProjectConfig();
|
|
22808
24616
|
if (!projectConfig?.projectRoot) throw new Error("Make Effects project config not found. Run: makefx init --space <id>");
|
|
22809
24617
|
requireDebugAcknowledgement(parsed);
|
|
@@ -22921,7 +24729,7 @@ function formatCreated(value) {
|
|
|
22921
24729
|
if (Number.isNaN(date.getTime())) return value;
|
|
22922
24730
|
return value.replace("T", " ").replace(/\.\d{3}Z$/, "Z").slice(0, 20);
|
|
22923
24731
|
}
|
|
22924
|
-
function printUsage$
|
|
24732
|
+
function printUsage$5() {
|
|
22925
24733
|
console.log(`
|
|
22926
24734
|
Usage:
|
|
22927
24735
|
makefx runs --debug
|
|
@@ -22939,7 +24747,7 @@ For timed scene assembly, use:
|
|
|
22939
24747
|
}
|
|
22940
24748
|
//#endregion
|
|
22941
24749
|
//#region src/cli/commands/assets.ts
|
|
22942
|
-
var defaultDeps$
|
|
24750
|
+
var defaultDeps$5 = {
|
|
22943
24751
|
loadConfig: loadStoredConfig,
|
|
22944
24752
|
loadProjectConfig,
|
|
22945
24753
|
resolveBaseUrl,
|
|
@@ -22962,15 +24770,15 @@ async function handleAssets(parsed) {
|
|
|
22962
24770
|
await executeAssets(parsed);
|
|
22963
24771
|
} catch (error) {
|
|
22964
24772
|
console.error("Error:", error instanceof Error ? error.message : error);
|
|
22965
|
-
printUsage$
|
|
24773
|
+
printUsage$4();
|
|
22966
24774
|
process$1.exitCode = 1;
|
|
22967
24775
|
}
|
|
22968
24776
|
}
|
|
22969
|
-
async function executeAssets(parsed, deps = defaultDeps$
|
|
22970
|
-
const ctx = await buildContext$
|
|
24777
|
+
async function executeAssets(parsed, deps = defaultDeps$5) {
|
|
24778
|
+
const ctx = await buildContext$5(parsed, deps);
|
|
22971
24779
|
const subcommand = parsed.positionals[0] || "list";
|
|
22972
24780
|
if (subcommand === "list") {
|
|
22973
|
-
const assets = await listAssets(ctx, deps);
|
|
24781
|
+
const assets = await listAssets$1(ctx, deps);
|
|
22974
24782
|
if (parsed.options.json === "true") deps.print(JSON.stringify(assets.map(toAssetJson), null, 2));
|
|
22975
24783
|
else printAssetList(assets, deps.print);
|
|
22976
24784
|
return {
|
|
@@ -23046,7 +24854,7 @@ async function executeAssets(parsed, deps = defaultDeps$2) {
|
|
|
23046
24854
|
function normalizeOption(value) {
|
|
23047
24855
|
return !value || value === "true" ? void 0 : value;
|
|
23048
24856
|
}
|
|
23049
|
-
async function buildContext$
|
|
24857
|
+
async function buildContext$5(parsed, deps) {
|
|
23050
24858
|
const projectConfig = await deps.loadProjectConfig();
|
|
23051
24859
|
const env = resolveCommandEnvironment(parsed, projectConfig);
|
|
23052
24860
|
const spaceId = resolveCommandSpace(parsed, projectConfig);
|
|
@@ -23063,7 +24871,7 @@ async function buildContext$2(parsed, deps) {
|
|
|
23063
24871
|
force: parsed.options.force === "true"
|
|
23064
24872
|
};
|
|
23065
24873
|
}
|
|
23066
|
-
async function listAssets(ctx, deps) {
|
|
24874
|
+
async function listAssets$1(ctx, deps) {
|
|
23067
24875
|
return (await fetchJson(ctx, deps, `/api/spaces/${ctx.spaceId}/assets`)).assets || [];
|
|
23068
24876
|
}
|
|
23069
24877
|
async function getAssetDetails(ctx, deps, assetId) {
|
|
@@ -23088,7 +24896,7 @@ async function resolveDownloadRef(ref, ctx, deps) {
|
|
|
23088
24896
|
requestPath: `/api/images/${ref}`
|
|
23089
24897
|
};
|
|
23090
24898
|
}
|
|
23091
|
-
const assets = await listAssets(ctx, deps);
|
|
24899
|
+
const assets = await listAssets$1(ctx, deps);
|
|
23092
24900
|
for (const asset of assets) {
|
|
23093
24901
|
const variant = (await getAssetDetails(ctx, deps, asset.id)).variants.find((candidate) => candidate.id === ref);
|
|
23094
24902
|
if (!variant) continue;
|
|
@@ -23146,7 +24954,6 @@ function printAssetDetails(details, ctx, print) {
|
|
|
23146
24954
|
print(` Type: ${asset.type || "unknown"}`);
|
|
23147
24955
|
print(` Media: ${asset.media_kind || "-"}`);
|
|
23148
24956
|
print(` Active: ${asset.active_variant_id || "-"}`);
|
|
23149
|
-
print(` Parent: ${asset.parent_asset_id || "-"}`);
|
|
23150
24957
|
print(` Created: ${formatTimestamp(asset.created_at)}`);
|
|
23151
24958
|
print(` Updated: ${formatTimestamp(asset.updated_at)}`);
|
|
23152
24959
|
print(` Web: ${ctx.baseUrl}/spaces/${ctx.spaceId}/assets/${asset.id}`);
|
|
@@ -23195,7 +25002,6 @@ function toAssetJson(asset) {
|
|
|
23195
25002
|
type: asset.type,
|
|
23196
25003
|
media_kind: asset.media_kind || null,
|
|
23197
25004
|
activeVariantId: asset.active_variant_id,
|
|
23198
|
-
parentAssetId: asset.parent_asset_id || null,
|
|
23199
25005
|
createdAt: asset.created_at || null,
|
|
23200
25006
|
updatedAt: asset.updated_at || null
|
|
23201
25007
|
};
|
|
@@ -23227,7 +25033,7 @@ function formatTimestamp(value) {
|
|
|
23227
25033
|
if (Number.isNaN(date.getTime())) return String(value);
|
|
23228
25034
|
return date.toISOString().replace("T", " ").replace(/\.\d{3}Z$/, "Z").slice(0, 20);
|
|
23229
25035
|
}
|
|
23230
|
-
function printUsage$
|
|
25036
|
+
function printUsage$4() {
|
|
23231
25037
|
console.log(`
|
|
23232
25038
|
Usage:
|
|
23233
25039
|
makefx assets
|
|
@@ -23242,7 +25048,7 @@ Usage:
|
|
|
23242
25048
|
}
|
|
23243
25049
|
//#endregion
|
|
23244
25050
|
//#region src/cli/commands/variants.ts
|
|
23245
|
-
var defaultDeps$
|
|
25051
|
+
var defaultDeps$4 = {
|
|
23246
25052
|
loadConfig: loadStoredConfig,
|
|
23247
25053
|
loadProjectConfig,
|
|
23248
25054
|
resolveBaseUrl,
|
|
@@ -23254,12 +25060,12 @@ async function handleVariants(parsed) {
|
|
|
23254
25060
|
await executeVariants(parsed);
|
|
23255
25061
|
} catch (error) {
|
|
23256
25062
|
console.error("Error:", error instanceof Error ? error.message : error);
|
|
23257
|
-
printUsage$
|
|
25063
|
+
printUsage$3();
|
|
23258
25064
|
process$1.exitCode = 1;
|
|
23259
25065
|
}
|
|
23260
25066
|
}
|
|
23261
|
-
async function executeVariants(parsed, deps = defaultDeps$
|
|
23262
|
-
const ctx = await buildContext$
|
|
25067
|
+
async function executeVariants(parsed, deps = defaultDeps$4) {
|
|
25068
|
+
const ctx = await buildContext$4(parsed, deps);
|
|
23263
25069
|
const subcommand = parsed.positionals[0];
|
|
23264
25070
|
if (subcommand === "delete") {
|
|
23265
25071
|
const variantId = requireVariantId(parsed, "delete");
|
|
@@ -23307,7 +25113,7 @@ function requireVariantId(parsed, verb) {
|
|
|
23307
25113
|
if (!variantId) throw new Error(`Variant ID is required: makefx variants ${verb} <variant-id>`);
|
|
23308
25114
|
return variantId;
|
|
23309
25115
|
}
|
|
23310
|
-
async function buildContext$
|
|
25116
|
+
async function buildContext$4(parsed, deps) {
|
|
23311
25117
|
const projectConfig = await deps.loadProjectConfig();
|
|
23312
25118
|
const env = resolveCommandEnvironment(parsed, projectConfig);
|
|
23313
25119
|
const spaceId = resolveCommandSpace(parsed, projectConfig);
|
|
@@ -23330,7 +25136,7 @@ async function withVariantClient(ctx, deps, run) {
|
|
|
23330
25136
|
client.disconnect();
|
|
23331
25137
|
}
|
|
23332
25138
|
}
|
|
23333
|
-
function printUsage$
|
|
25139
|
+
function printUsage$3() {
|
|
23334
25140
|
console.log(`
|
|
23335
25141
|
Usage:
|
|
23336
25142
|
makefx variants delete <variant-id>
|
|
@@ -23346,6 +25152,809 @@ Options:
|
|
|
23346
25152
|
`);
|
|
23347
25153
|
}
|
|
23348
25154
|
//#endregion
|
|
25155
|
+
//#region src/cli/commands/styles.ts
|
|
25156
|
+
var defaultDeps$3 = {
|
|
25157
|
+
loadConfig: loadStoredConfig,
|
|
25158
|
+
loadProjectConfig,
|
|
25159
|
+
resolveBaseUrl,
|
|
25160
|
+
fetch,
|
|
25161
|
+
print: console.log
|
|
25162
|
+
};
|
|
25163
|
+
async function handleStyles(parsed) {
|
|
25164
|
+
try {
|
|
25165
|
+
await executeStyles(parsed);
|
|
25166
|
+
} catch (error) {
|
|
25167
|
+
console.error("Error:", error instanceof Error ? error.message : error);
|
|
25168
|
+
printUsage$2();
|
|
25169
|
+
process$1.exitCode = 1;
|
|
25170
|
+
}
|
|
25171
|
+
}
|
|
25172
|
+
async function executeStyles(parsed, deps = defaultDeps$3) {
|
|
25173
|
+
const namespace = parsed.positionals[0] || "presets";
|
|
25174
|
+
if (namespace === "references" || namespace === "refs") return executeReferences(parsed, deps);
|
|
25175
|
+
if (namespace === "collections" || namespace === "collection") return executeCollections(parsed, deps);
|
|
25176
|
+
if (namespace === "presets" || namespace === "preset") return executePresets(parsed, deps);
|
|
25177
|
+
throw new Error(`Unknown styles command: ${namespace}`);
|
|
25178
|
+
}
|
|
25179
|
+
async function executeReferences(parsed, deps) {
|
|
25180
|
+
const ctx = await buildContext$3(parsed, deps);
|
|
25181
|
+
const collectionFilter = readOption(parsed, "collection", "collectionId") || parsed.positionals[1];
|
|
25182
|
+
const collections = await listStyleReferenceCollections(ctx, deps);
|
|
25183
|
+
const selected = collectionFilter ? collections.filter((collection) => collection.id === collectionFilter || collection.name === collectionFilter) : collections;
|
|
25184
|
+
if (collectionFilter && selected.length === 0) throw new Error(`Style reference collection not found: ${collectionFilter}`);
|
|
25185
|
+
const references = [];
|
|
25186
|
+
for (const collection of selected) {
|
|
25187
|
+
const items = await listCollectionItems(ctx, deps, collection.id);
|
|
25188
|
+
for (const item of items.filter((candidate) => candidate.role === "style_ref")) references.push({
|
|
25189
|
+
collectionId: collection.id,
|
|
25190
|
+
collectionName: collection.name,
|
|
25191
|
+
item
|
|
25192
|
+
});
|
|
25193
|
+
}
|
|
25194
|
+
if (parsed.options.json === "true") deps.print(JSON.stringify(references, null, 2));
|
|
25195
|
+
else printReferences(references, deps.print);
|
|
25196
|
+
return {
|
|
25197
|
+
type: "references",
|
|
25198
|
+
references
|
|
25199
|
+
};
|
|
25200
|
+
}
|
|
25201
|
+
async function executeCollections(parsed, deps) {
|
|
25202
|
+
const ctx = await buildContext$3(parsed, deps);
|
|
25203
|
+
const action = parsed.positionals[1] || "list";
|
|
25204
|
+
if (action === "list") {
|
|
25205
|
+
const collections = await listStyleReferenceCollections(ctx, deps);
|
|
25206
|
+
if (parsed.options.json === "true") deps.print(JSON.stringify(collections, null, 2));
|
|
25207
|
+
else printCollections(collections, deps.print);
|
|
25208
|
+
return {
|
|
25209
|
+
type: "collections",
|
|
25210
|
+
collections
|
|
25211
|
+
};
|
|
25212
|
+
}
|
|
25213
|
+
if (action === "create") {
|
|
25214
|
+
const name = parsed.positionals[2] || readRequiredOption(parsed, "name", "name");
|
|
25215
|
+
const collection = await createCollection(ctx, deps, {
|
|
25216
|
+
id: readOption(parsed, "id", "id"),
|
|
25217
|
+
name,
|
|
25218
|
+
description: nullableOption(parsed, "description", "description")
|
|
25219
|
+
});
|
|
25220
|
+
const items = await upsertStyleReferenceItems(ctx, deps, collection.id, parsed, false);
|
|
25221
|
+
printCollectionMutation("Created", collection, items, deps.print, parsed.options.json === "true");
|
|
25222
|
+
return {
|
|
25223
|
+
type: "collection",
|
|
25224
|
+
collection,
|
|
25225
|
+
items
|
|
25226
|
+
};
|
|
25227
|
+
}
|
|
25228
|
+
if (action === "update") {
|
|
25229
|
+
const collectionId = parsed.positionals[2] || readRequiredOption(parsed, "id", "id");
|
|
25230
|
+
const changes = {};
|
|
25231
|
+
const name = readOption(parsed, "name", "name");
|
|
25232
|
+
const description = nullableOption(parsed, "description", "description");
|
|
25233
|
+
if (name !== void 0) changes.name = name;
|
|
25234
|
+
if (description !== void 0) changes.description = description;
|
|
25235
|
+
let collection;
|
|
25236
|
+
if (Object.keys(changes).length > 0) collection = await updateCollection(ctx, deps, collectionId, changes);
|
|
25237
|
+
const items = hasReferenceOptions(parsed) ? await upsertStyleReferenceItems(ctx, deps, collectionId, parsed, parsed.options.append !== "true") : void 0;
|
|
25238
|
+
if (!collection) collection = (await listCollections(ctx, deps)).find((candidate) => candidate.id === collectionId);
|
|
25239
|
+
if (!collection) throw new Error(`Collection not found: ${collectionId}`);
|
|
25240
|
+
printCollectionMutation("Updated", collection, items, deps.print, parsed.options.json === "true");
|
|
25241
|
+
return {
|
|
25242
|
+
type: "collection",
|
|
25243
|
+
collection,
|
|
25244
|
+
items
|
|
25245
|
+
};
|
|
25246
|
+
}
|
|
25247
|
+
throw new Error(`Unknown styles collections command: ${action}`);
|
|
25248
|
+
}
|
|
25249
|
+
async function executePresets(parsed, deps) {
|
|
25250
|
+
const ctx = await buildContext$3(parsed, deps);
|
|
25251
|
+
const action = parsed.positionals[1] || "list";
|
|
25252
|
+
if (action === "list") {
|
|
25253
|
+
const presets = await listStylePresets(ctx, deps);
|
|
25254
|
+
if (parsed.options.json === "true") deps.print(JSON.stringify(presets, null, 2));
|
|
25255
|
+
else printPresets(presets, deps.print);
|
|
25256
|
+
return {
|
|
25257
|
+
type: "presets",
|
|
25258
|
+
presets
|
|
25259
|
+
};
|
|
25260
|
+
}
|
|
25261
|
+
if (action === "create") {
|
|
25262
|
+
const name = parsed.positionals[2] || readRequiredOption(parsed, "name", "name");
|
|
25263
|
+
const response = await createStylePreset(ctx, deps, {
|
|
25264
|
+
id: readOption(parsed, "id", "id"),
|
|
25265
|
+
name,
|
|
25266
|
+
description: nullableOption(parsed, "description", "description"),
|
|
25267
|
+
stylePrompt: readOption(parsed, "prompt", "stylePrompt") ?? "",
|
|
25268
|
+
collectionId: nullableOption(parsed, "collection", "collectionId"),
|
|
25269
|
+
enabled: parsed.options.disable === "true" ? false : true,
|
|
25270
|
+
isDefault: parsed.options.default === "true"
|
|
25271
|
+
});
|
|
25272
|
+
printPresetMutation("Created", response.preset, deps.print, parsed.options.json === "true");
|
|
25273
|
+
return {
|
|
25274
|
+
type: "preset",
|
|
25275
|
+
preset: response.preset
|
|
25276
|
+
};
|
|
25277
|
+
}
|
|
25278
|
+
if (action === "update") {
|
|
25279
|
+
const response = await updateStylePreset(ctx, deps, parsed.positionals[2] || readRequiredOption(parsed, "id", "id"), buildPresetUpdate(parsed));
|
|
25280
|
+
printPresetMutation("Updated", response.preset, deps.print, parsed.options.json === "true");
|
|
25281
|
+
return {
|
|
25282
|
+
type: "preset",
|
|
25283
|
+
preset: response.preset
|
|
25284
|
+
};
|
|
25285
|
+
}
|
|
25286
|
+
if (action === "enable" || action === "disable") {
|
|
25287
|
+
const response = await updateStylePreset(ctx, deps, parsed.positionals[2] || readRequiredOption(parsed, "id", "id"), { enabled: action === "enable" });
|
|
25288
|
+
printPresetMutation(action === "enable" ? "Enabled" : "Disabled", response.preset, deps.print, parsed.options.json === "true");
|
|
25289
|
+
return {
|
|
25290
|
+
type: "preset",
|
|
25291
|
+
preset: response.preset
|
|
25292
|
+
};
|
|
25293
|
+
}
|
|
25294
|
+
if (action === "delete" || action === "remove") {
|
|
25295
|
+
const presetId = parsed.positionals[2] || readRequiredOption(parsed, "id", "id");
|
|
25296
|
+
await deleteStylePreset(ctx, deps, presetId);
|
|
25297
|
+
if (parsed.options.json === "true") deps.print(JSON.stringify({
|
|
25298
|
+
success: true,
|
|
25299
|
+
presetId
|
|
25300
|
+
}, null, 2));
|
|
25301
|
+
else deps.print(`Deleted style preset ${presetId}`);
|
|
25302
|
+
return {
|
|
25303
|
+
type: "delete-preset",
|
|
25304
|
+
presetId
|
|
25305
|
+
};
|
|
25306
|
+
}
|
|
25307
|
+
throw new Error(`Unknown styles presets command: ${action}`);
|
|
25308
|
+
}
|
|
25309
|
+
async function buildContext$3(parsed, deps) {
|
|
25310
|
+
const projectConfig = await deps.loadProjectConfig();
|
|
25311
|
+
const env = resolveCommandEnvironment(parsed, projectConfig);
|
|
25312
|
+
const spaceId = resolveCommandSpace(parsed, projectConfig);
|
|
25313
|
+
if (!spaceId) throw new Error("--space is required, or run: makefx init --space <id>");
|
|
25314
|
+
const config = await deps.loadConfig(env);
|
|
25315
|
+
if (!config) throw new Error(`Not logged in to ${env} environment. Run: ${loginCommandForEnvironment(env)}`);
|
|
25316
|
+
if (config.token.expiresAt < Date.now()) throw new Error(`Token expired for ${env} environment. Run: ${loginCommandForEnvironment(env)}`);
|
|
25317
|
+
if (env === "local") process$1.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
|
|
25318
|
+
return {
|
|
25319
|
+
env,
|
|
25320
|
+
spaceId,
|
|
25321
|
+
baseUrl: deps.resolveBaseUrl(env),
|
|
25322
|
+
accessToken: config.token.accessToken
|
|
25323
|
+
};
|
|
25324
|
+
}
|
|
25325
|
+
async function listAssets(ctx, deps) {
|
|
25326
|
+
return (await apiFetch("GET /api/spaces/:id/assets", {
|
|
25327
|
+
baseUrl: ctx.baseUrl,
|
|
25328
|
+
fetch: deps.fetch,
|
|
25329
|
+
params: { id: ctx.spaceId },
|
|
25330
|
+
headers: authHeaders(ctx)
|
|
25331
|
+
})).assets;
|
|
25332
|
+
}
|
|
25333
|
+
async function listCollections(ctx, deps) {
|
|
25334
|
+
return (await apiFetch("GET /api/spaces/:id/collections", {
|
|
25335
|
+
baseUrl: ctx.baseUrl,
|
|
25336
|
+
fetch: deps.fetch,
|
|
25337
|
+
params: { id: ctx.spaceId },
|
|
25338
|
+
headers: authHeaders(ctx)
|
|
25339
|
+
})).collections;
|
|
25340
|
+
}
|
|
25341
|
+
async function listStyleReferenceCollections(ctx, deps) {
|
|
25342
|
+
return (await apiFetch("GET /api/spaces/:id/style-reference-collections", {
|
|
25343
|
+
baseUrl: ctx.baseUrl,
|
|
25344
|
+
fetch: deps.fetch,
|
|
25345
|
+
params: { id: ctx.spaceId },
|
|
25346
|
+
headers: authHeaders(ctx)
|
|
25347
|
+
})).collections;
|
|
25348
|
+
}
|
|
25349
|
+
async function listCollectionItems(ctx, deps, collectionId) {
|
|
25350
|
+
return (await apiFetch("GET /api/spaces/:id/collections/:collectionId/items", {
|
|
25351
|
+
baseUrl: ctx.baseUrl,
|
|
25352
|
+
fetch: deps.fetch,
|
|
25353
|
+
params: {
|
|
25354
|
+
id: ctx.spaceId,
|
|
25355
|
+
collectionId
|
|
25356
|
+
},
|
|
25357
|
+
headers: authHeaders(ctx)
|
|
25358
|
+
})).items;
|
|
25359
|
+
}
|
|
25360
|
+
async function createCollection(ctx, deps, json) {
|
|
25361
|
+
return (await apiFetch("POST /api/spaces/:id/collections", {
|
|
25362
|
+
baseUrl: ctx.baseUrl,
|
|
25363
|
+
fetch: deps.fetch,
|
|
25364
|
+
params: { id: ctx.spaceId },
|
|
25365
|
+
json,
|
|
25366
|
+
headers: authHeaders(ctx)
|
|
25367
|
+
})).collection;
|
|
25368
|
+
}
|
|
25369
|
+
async function updateCollection(ctx, deps, collectionId, json) {
|
|
25370
|
+
return (await apiFetch("PATCH /api/spaces/:id/collections/:collectionId", {
|
|
25371
|
+
baseUrl: ctx.baseUrl,
|
|
25372
|
+
fetch: deps.fetch,
|
|
25373
|
+
params: {
|
|
25374
|
+
id: ctx.spaceId,
|
|
25375
|
+
collectionId
|
|
25376
|
+
},
|
|
25377
|
+
json,
|
|
25378
|
+
headers: authHeaders(ctx)
|
|
25379
|
+
})).collection;
|
|
25380
|
+
}
|
|
25381
|
+
async function createCollectionItem(ctx, deps, collectionId, json) {
|
|
25382
|
+
return (await apiFetch("POST /api/spaces/:id/collections/:collectionId/items", {
|
|
25383
|
+
baseUrl: ctx.baseUrl,
|
|
25384
|
+
fetch: deps.fetch,
|
|
25385
|
+
params: {
|
|
25386
|
+
id: ctx.spaceId,
|
|
25387
|
+
collectionId
|
|
25388
|
+
},
|
|
25389
|
+
json,
|
|
25390
|
+
headers: authHeaders(ctx)
|
|
25391
|
+
})).item;
|
|
25392
|
+
}
|
|
25393
|
+
async function deleteCollectionItem(ctx, deps, collectionId, itemId) {
|
|
25394
|
+
await apiFetch("DELETE /api/spaces/:id/collections/:collectionId/items/:itemId", {
|
|
25395
|
+
baseUrl: ctx.baseUrl,
|
|
25396
|
+
fetch: deps.fetch,
|
|
25397
|
+
params: {
|
|
25398
|
+
id: ctx.spaceId,
|
|
25399
|
+
collectionId,
|
|
25400
|
+
itemId
|
|
25401
|
+
},
|
|
25402
|
+
headers: authHeaders(ctx)
|
|
25403
|
+
});
|
|
25404
|
+
}
|
|
25405
|
+
async function listStylePresets(ctx, deps) {
|
|
25406
|
+
return (await apiFetch("GET /api/spaces/:id/style-presets", {
|
|
25407
|
+
baseUrl: ctx.baseUrl,
|
|
25408
|
+
fetch: deps.fetch,
|
|
25409
|
+
params: { id: ctx.spaceId },
|
|
25410
|
+
headers: authHeaders(ctx)
|
|
25411
|
+
})).presets;
|
|
25412
|
+
}
|
|
25413
|
+
async function createStylePreset(ctx, deps, json) {
|
|
25414
|
+
return apiFetch("POST /api/spaces/:id/style-presets", {
|
|
25415
|
+
baseUrl: ctx.baseUrl,
|
|
25416
|
+
fetch: deps.fetch,
|
|
25417
|
+
params: { id: ctx.spaceId },
|
|
25418
|
+
json,
|
|
25419
|
+
headers: authHeaders(ctx)
|
|
25420
|
+
});
|
|
25421
|
+
}
|
|
25422
|
+
async function updateStylePreset(ctx, deps, presetId, json) {
|
|
25423
|
+
return apiFetch("PATCH /api/spaces/:id/style-presets/:presetId", {
|
|
25424
|
+
baseUrl: ctx.baseUrl,
|
|
25425
|
+
fetch: deps.fetch,
|
|
25426
|
+
params: {
|
|
25427
|
+
id: ctx.spaceId,
|
|
25428
|
+
presetId
|
|
25429
|
+
},
|
|
25430
|
+
json,
|
|
25431
|
+
headers: authHeaders(ctx)
|
|
25432
|
+
});
|
|
25433
|
+
}
|
|
25434
|
+
async function deleteStylePreset(ctx, deps, presetId) {
|
|
25435
|
+
await apiFetch("DELETE /api/spaces/:id/style-presets/:presetId", {
|
|
25436
|
+
baseUrl: ctx.baseUrl,
|
|
25437
|
+
fetch: deps.fetch,
|
|
25438
|
+
params: {
|
|
25439
|
+
id: ctx.spaceId,
|
|
25440
|
+
presetId
|
|
25441
|
+
},
|
|
25442
|
+
headers: authHeaders(ctx)
|
|
25443
|
+
});
|
|
25444
|
+
}
|
|
25445
|
+
async function upsertStyleReferenceItems(ctx, deps, collectionId, parsed, replaceExisting) {
|
|
25446
|
+
const refs = await buildStyleReferenceItemRequests(ctx, deps, parsed);
|
|
25447
|
+
if (refs.length === 0) return [];
|
|
25448
|
+
if (replaceExisting) {
|
|
25449
|
+
const existing = await listCollectionItems(ctx, deps, collectionId);
|
|
25450
|
+
await Promise.all(existing.filter((item) => item.role === "style_ref").map((item) => deleteCollectionItem(ctx, deps, collectionId, item.id)));
|
|
25451
|
+
}
|
|
25452
|
+
const created = [];
|
|
25453
|
+
for (let index = 0; index < refs.length; index += 1) created.push(await createCollectionItem(ctx, deps, collectionId, {
|
|
25454
|
+
...refs[index],
|
|
25455
|
+
role: "style_ref",
|
|
25456
|
+
sortIndex: index
|
|
25457
|
+
}));
|
|
25458
|
+
return created;
|
|
25459
|
+
}
|
|
25460
|
+
async function buildStyleReferenceItemRequests(ctx, deps, parsed) {
|
|
25461
|
+
const assets = parseCsvOptions(parsed, ["assets", "asset"]);
|
|
25462
|
+
const variants = parseCsvOptions(parsed, ["variants", "variant"]);
|
|
25463
|
+
const refs = parseCsvOptions(parsed, ["refs", "ref"]);
|
|
25464
|
+
if (assets.length === 0 && variants.length === 0 && refs.length === 0) return [];
|
|
25465
|
+
const allAssets = await listAssets(ctx, deps);
|
|
25466
|
+
const assetById = new Map(allAssets.map((asset) => [asset.id, asset]));
|
|
25467
|
+
const requests = [];
|
|
25468
|
+
for (const assetId of [...assets, ...refs.filter((ref) => assetById.has(ref))]) {
|
|
25469
|
+
const asset = assetById.get(assetId);
|
|
25470
|
+
if (!asset) throw new Error(`Asset not found in space ${ctx.spaceId}: ${assetId}`);
|
|
25471
|
+
if (!asset.active_variant_id) throw new Error(`Asset ${assetId} has no active variant to pin as a style reference`);
|
|
25472
|
+
requests.push({
|
|
25473
|
+
subjectType: "asset",
|
|
25474
|
+
assetId,
|
|
25475
|
+
pinnedVariantId: asset.active_variant_id
|
|
25476
|
+
});
|
|
25477
|
+
}
|
|
25478
|
+
for (const variantId of [...variants, ...refs.filter((ref) => !assetById.has(ref))]) requests.push({
|
|
25479
|
+
subjectType: "variant",
|
|
25480
|
+
variantId
|
|
25481
|
+
});
|
|
25482
|
+
return dedupeItemRequests(requests);
|
|
25483
|
+
}
|
|
25484
|
+
function dedupeItemRequests(requests) {
|
|
25485
|
+
const seen = /* @__PURE__ */ new Set();
|
|
25486
|
+
return requests.filter((request) => {
|
|
25487
|
+
const key = request.subjectType === "asset" ? `asset:${request.assetId}:${request.pinnedVariantId ?? ""}` : `variant:${request.variantId}`;
|
|
25488
|
+
if (seen.has(key)) return false;
|
|
25489
|
+
seen.add(key);
|
|
25490
|
+
return true;
|
|
25491
|
+
});
|
|
25492
|
+
}
|
|
25493
|
+
function buildPresetUpdate(parsed) {
|
|
25494
|
+
const update = {};
|
|
25495
|
+
const name = readOption(parsed, "name", "name");
|
|
25496
|
+
const description = nullableOption(parsed, "description", "description");
|
|
25497
|
+
const stylePrompt = readOption(parsed, "prompt", "stylePrompt");
|
|
25498
|
+
const collectionId = nullableOption(parsed, "collection", "collectionId");
|
|
25499
|
+
if (name !== void 0) update.name = name;
|
|
25500
|
+
if (description !== void 0) update.description = description;
|
|
25501
|
+
if (stylePrompt !== void 0) update.stylePrompt = stylePrompt;
|
|
25502
|
+
if (collectionId !== void 0) update.collectionId = collectionId;
|
|
25503
|
+
if (parsed.options.enable === "true") update.enabled = true;
|
|
25504
|
+
if (parsed.options.disable === "true") update.enabled = false;
|
|
25505
|
+
if (parsed.options.default === "true") update.isDefault = true;
|
|
25506
|
+
if (parsed.options["no-default"] === "true") update.isDefault = false;
|
|
25507
|
+
if (Object.keys(update).length === 0) throw new Error("No preset updates provided");
|
|
25508
|
+
return update;
|
|
25509
|
+
}
|
|
25510
|
+
function authHeaders(ctx) {
|
|
25511
|
+
return {
|
|
25512
|
+
"Authorization": `Bearer ${ctx.accessToken}`,
|
|
25513
|
+
"Accept": "application/json"
|
|
25514
|
+
};
|
|
25515
|
+
}
|
|
25516
|
+
function hasReferenceOptions(parsed) {
|
|
25517
|
+
return [
|
|
25518
|
+
"refs",
|
|
25519
|
+
"ref",
|
|
25520
|
+
"assets",
|
|
25521
|
+
"asset",
|
|
25522
|
+
"variants",
|
|
25523
|
+
"variant"
|
|
25524
|
+
].some((key) => Boolean(readRawOption(parsed, key)));
|
|
25525
|
+
}
|
|
25526
|
+
function parseCsvOptions(parsed, keys) {
|
|
25527
|
+
return keys.flatMap((key) => parseCsv(readRawOption(parsed, key)));
|
|
25528
|
+
}
|
|
25529
|
+
function parseCsv(value) {
|
|
25530
|
+
if (!value || value === "true") return [];
|
|
25531
|
+
return value.split(",").map((item) => item.trim()).filter(Boolean);
|
|
25532
|
+
}
|
|
25533
|
+
function readRequiredOption(parsed, kebabName, camelName) {
|
|
25534
|
+
const value = readOption(parsed, kebabName, camelName);
|
|
25535
|
+
if (value === void 0) throw new Error(`--${kebabName} is required`);
|
|
25536
|
+
return value;
|
|
25537
|
+
}
|
|
25538
|
+
function readOption(parsed, kebabName, camelName) {
|
|
25539
|
+
const value = readRawOption(parsed, kebabName) ?? readRawOption(parsed, camelName);
|
|
25540
|
+
return !value || value === "true" ? void 0 : value;
|
|
25541
|
+
}
|
|
25542
|
+
function readRawOption(parsed, key) {
|
|
25543
|
+
return parsed.options[key];
|
|
25544
|
+
}
|
|
25545
|
+
function nullableOption(parsed, kebabName, camelName) {
|
|
25546
|
+
if (parsed.options["no-collection"] === "true" && (kebabName === "collection" || camelName === "collectionId")) return null;
|
|
25547
|
+
const value = readOption(parsed, kebabName, camelName);
|
|
25548
|
+
if (value === void 0) return void 0;
|
|
25549
|
+
return value === "null" || value === "-" ? null : value;
|
|
25550
|
+
}
|
|
25551
|
+
function isEnabled(value) {
|
|
25552
|
+
return value === true || value === 1;
|
|
25553
|
+
}
|
|
25554
|
+
function printReferences(references, print) {
|
|
25555
|
+
if (references.length === 0) {
|
|
25556
|
+
print("No style reference assets found.");
|
|
25557
|
+
return;
|
|
25558
|
+
}
|
|
25559
|
+
print(`Found ${references.length} style reference asset(s):\n`);
|
|
25560
|
+
print("Collection".padEnd(28) + "Subject".padEnd(10) + "Asset".padEnd(28) + "Variant".padEnd(28) + "Item");
|
|
25561
|
+
print("-".repeat(108));
|
|
25562
|
+
for (const reference of references) {
|
|
25563
|
+
const item = reference.item;
|
|
25564
|
+
print(truncate(reference.collectionName, 26).padEnd(28) + item.subject_type.padEnd(10) + truncate(item.asset_id || "-", 26).padEnd(28) + truncate(item.pinned_variant_id || item.variant_id || "-", 26).padEnd(28) + truncate(item.id, 26));
|
|
25565
|
+
}
|
|
25566
|
+
}
|
|
25567
|
+
function printCollections(collections, print) {
|
|
25568
|
+
if (collections.length === 0) {
|
|
25569
|
+
print("No style reference collections found.");
|
|
25570
|
+
return;
|
|
25571
|
+
}
|
|
25572
|
+
print(`Found ${collections.length} style reference collection(s):\n`);
|
|
25573
|
+
print("References".padEnd(12) + "Presets".padEnd(10) + "Collection".padEnd(34) + "Name");
|
|
25574
|
+
print("-".repeat(88));
|
|
25575
|
+
for (const collection of collections) print(String(collection.reference_count).padEnd(12) + String(collection.preset_count).padEnd(10) + truncate(collection.id, 32).padEnd(34) + truncate(collection.name, 40));
|
|
25576
|
+
}
|
|
25577
|
+
function printPresets(presets, print) {
|
|
25578
|
+
if (presets.length === 0) {
|
|
25579
|
+
print("No style presets found.");
|
|
25580
|
+
return;
|
|
25581
|
+
}
|
|
25582
|
+
print(`Found ${presets.length} style preset(s):\n`);
|
|
25583
|
+
print("State".padEnd(14) + "References".padEnd(12) + "Preset".padEnd(30) + "Collection".padEnd(28) + "Name");
|
|
25584
|
+
print("-".repeat(104));
|
|
25585
|
+
for (const preset of presets) print(truncate(`${isEnabled(preset.enabled) ? "enabled" : "disabled"}${isEnabled(preset.is_default) ? ",default" : ""}`, 12).padEnd(14) + String(preset.reference_count).padEnd(12) + truncate(preset.id, 28).padEnd(30) + truncate(preset.collection_name || preset.collection_id || "-", 26).padEnd(28) + truncate(preset.name, 34));
|
|
25586
|
+
}
|
|
25587
|
+
function printCollectionMutation(verb, collection, items, print, asJson) {
|
|
25588
|
+
if (asJson) {
|
|
25589
|
+
print(JSON.stringify({
|
|
25590
|
+
collection,
|
|
25591
|
+
items
|
|
25592
|
+
}, null, 2));
|
|
25593
|
+
return;
|
|
25594
|
+
}
|
|
25595
|
+
print(`${verb} style reference collection ${collection.id}`);
|
|
25596
|
+
print(` Name: ${collection.name}`);
|
|
25597
|
+
if (items) print(` References: ${items.filter((item) => item.role === "style_ref").length}`);
|
|
25598
|
+
}
|
|
25599
|
+
function printPresetMutation(verb, preset, print, asJson) {
|
|
25600
|
+
if (asJson) {
|
|
25601
|
+
print(JSON.stringify(preset, null, 2));
|
|
25602
|
+
return;
|
|
25603
|
+
}
|
|
25604
|
+
print(`${verb} style preset ${preset.id}`);
|
|
25605
|
+
print(` Name: ${preset.name}`);
|
|
25606
|
+
print(` Enabled: ${isEnabled(preset.enabled) ? "yes" : "no"}`);
|
|
25607
|
+
print(` Default: ${isEnabled(preset.is_default) ? "yes" : "no"}`);
|
|
25608
|
+
print(` Collection: ${preset.collection_name || preset.collection_id || "-"}`);
|
|
25609
|
+
print(` References: ${preset.reference_count}`);
|
|
25610
|
+
}
|
|
25611
|
+
function printUsage$2() {
|
|
25612
|
+
console.log(`
|
|
25613
|
+
Usage:
|
|
25614
|
+
makefx styles references [--collection <id-or-name>] [--json]
|
|
25615
|
+
makefx styles collections list [--json]
|
|
25616
|
+
makefx styles collections create <name> --refs <asset_or_variant,...>
|
|
25617
|
+
makefx styles collections update <collection-id> [--name <name>] [--refs <asset_or_variant,...>] [--append]
|
|
25618
|
+
makefx styles presets list [--json]
|
|
25619
|
+
makefx styles presets create <name> --collection <collection-id> --prompt "style prompt" [--default]
|
|
25620
|
+
makefx styles presets update <preset-id> [--name <name>] [--collection <collection-id>] [--prompt "style prompt"]
|
|
25621
|
+
makefx styles presets enable <preset-id>
|
|
25622
|
+
makefx styles presets disable <preset-id>
|
|
25623
|
+
makefx styles presets delete <preset-id>
|
|
25624
|
+
|
|
25625
|
+
Options:
|
|
25626
|
+
--space <id> Target space ID; defaults from the initialized project
|
|
25627
|
+
--refs <ids> Comma-separated asset IDs or variant IDs to use as style references
|
|
25628
|
+
--assets <ids> Comma-separated asset IDs; active variants are pinned
|
|
25629
|
+
--variants <ids> Comma-separated variant IDs
|
|
25630
|
+
--json Print machine-readable output
|
|
25631
|
+
--env <env> Environment (production|stage|local)
|
|
25632
|
+
--local Shortcut for --env local
|
|
25633
|
+
`);
|
|
25634
|
+
}
|
|
25635
|
+
//#endregion
|
|
25636
|
+
//#region src/cli/commands/usage.ts
|
|
25637
|
+
var defaultDeps$2 = {
|
|
25638
|
+
loadConfig: loadStoredConfig,
|
|
25639
|
+
loadProjectConfig,
|
|
25640
|
+
resolveBaseUrl,
|
|
25641
|
+
fetch,
|
|
25642
|
+
print: console.log
|
|
25643
|
+
};
|
|
25644
|
+
async function handleUsage(parsed) {
|
|
25645
|
+
try {
|
|
25646
|
+
await executeUsage(parsed);
|
|
25647
|
+
} catch (error) {
|
|
25648
|
+
console.error("Error:", error instanceof Error ? error.message : error);
|
|
25649
|
+
printUsage$1();
|
|
25650
|
+
process$1.exitCode = 1;
|
|
25651
|
+
}
|
|
25652
|
+
}
|
|
25653
|
+
async function executeUsage(parsed, deps = defaultDeps$2) {
|
|
25654
|
+
const subcommand = parsed.positionals[0] || "summary";
|
|
25655
|
+
if (subcommand !== "summary") throw new Error(`Unknown usage command: ${subcommand}`);
|
|
25656
|
+
const summary = await fetchUsageSummary(await buildContext$2(parsed, deps), deps, {
|
|
25657
|
+
from: optionValue$2(parsed.options.from),
|
|
25658
|
+
to: optionValue$2(parsed.options.to)
|
|
25659
|
+
});
|
|
25660
|
+
if (parsed.options.json === "true") deps.print(JSON.stringify(summary, null, 2));
|
|
25661
|
+
else printUsageSummary(summary, deps.print);
|
|
25662
|
+
return {
|
|
25663
|
+
type: "summary",
|
|
25664
|
+
summary
|
|
25665
|
+
};
|
|
25666
|
+
}
|
|
25667
|
+
async function buildContext$2(parsed, deps) {
|
|
25668
|
+
const projectConfig = await deps.loadProjectConfig();
|
|
25669
|
+
const env = resolveCommandEnvironment(parsed, projectConfig);
|
|
25670
|
+
const spaceId = resolveCommandSpace(parsed, projectConfig);
|
|
25671
|
+
if (!spaceId) throw new Error("--space is required, or run: makefx init --space <id>");
|
|
25672
|
+
const config = await deps.loadConfig(env);
|
|
25673
|
+
if (!config) throw new Error(`Not logged in to ${env} environment. Run: ${loginCommandForEnvironment(env)}`);
|
|
25674
|
+
if (config.token.expiresAt < Date.now()) throw new Error(`Token expired for ${env} environment. Run: ${loginCommandForEnvironment(env)}`);
|
|
25675
|
+
if (env === "local") process$1.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
|
|
25676
|
+
return {
|
|
25677
|
+
env,
|
|
25678
|
+
spaceId,
|
|
25679
|
+
baseUrl: deps.resolveBaseUrl(env),
|
|
25680
|
+
accessToken: config.token.accessToken
|
|
25681
|
+
};
|
|
25682
|
+
}
|
|
25683
|
+
async function fetchUsageSummary(ctx, deps, options) {
|
|
25684
|
+
const params = new URLSearchParams();
|
|
25685
|
+
if (options.from) params.set("from", options.from);
|
|
25686
|
+
if (options.to) params.set("to", options.to);
|
|
25687
|
+
const query = params.toString();
|
|
25688
|
+
const response = await deps.fetch(`${ctx.baseUrl}/api/spaces/${encodeURIComponent(ctx.spaceId)}/usage/summary${query ? `?${query}` : ""}`, { headers: {
|
|
25689
|
+
"Authorization": `Bearer ${ctx.accessToken}`,
|
|
25690
|
+
"Accept": "application/json"
|
|
25691
|
+
} });
|
|
25692
|
+
if (!response.ok) {
|
|
25693
|
+
const text = await response.text();
|
|
25694
|
+
throw new Error(`Request failed (${response.status}): ${text || response.statusText}`);
|
|
25695
|
+
}
|
|
25696
|
+
return response.json();
|
|
25697
|
+
}
|
|
25698
|
+
function optionValue$2(value) {
|
|
25699
|
+
return !value || value === "true" ? void 0 : value;
|
|
25700
|
+
}
|
|
25701
|
+
function printUsageSummary(summary, print) {
|
|
25702
|
+
print(`\nUsage summary for ${summary.spaceId}\n`);
|
|
25703
|
+
print(` Period: ${formatPeriod$1(summary.period)}`);
|
|
25704
|
+
print(` Storage: ${formatBytes(summary.totals.storageBytes)}`);
|
|
25705
|
+
print(` Workflow runs: ${summary.totals.workflowRuns}`);
|
|
25706
|
+
print(` Delivery: ${formatBytes(summary.totals.deliveryBytes)}`);
|
|
25707
|
+
if (summary.byMediaKind.length > 0) {
|
|
25708
|
+
print("\nBy media kind:");
|
|
25709
|
+
print("Media".padEnd(10) + "Storage".padEnd(14) + "Workflows".padEnd(12) + "Delivery".padEnd(14) + "Events");
|
|
25710
|
+
print("-".repeat(58));
|
|
25711
|
+
for (const row of summary.byMediaKind) print((row.mediaKind || "-").padEnd(10) + formatBytes(row.storageBytes).padEnd(14) + String(row.workflowRuns).padEnd(12) + formatBytes(row.deliveryBytes).padEnd(14) + String(row.events));
|
|
25712
|
+
}
|
|
25713
|
+
}
|
|
25714
|
+
function formatPeriod$1(period) {
|
|
25715
|
+
if (!period.from && !period.to) return "all time";
|
|
25716
|
+
if (period.from && period.to) return `${period.from} to ${period.to}`;
|
|
25717
|
+
if (period.from) return `from ${period.from}`;
|
|
25718
|
+
return `through ${period.to}`;
|
|
25719
|
+
}
|
|
25720
|
+
function formatBytes(bytes) {
|
|
25721
|
+
const sign = bytes < 0 ? "-" : "";
|
|
25722
|
+
let value = Math.abs(bytes);
|
|
25723
|
+
const units = [
|
|
25724
|
+
"B",
|
|
25725
|
+
"KiB",
|
|
25726
|
+
"MiB",
|
|
25727
|
+
"GiB",
|
|
25728
|
+
"TiB"
|
|
25729
|
+
];
|
|
25730
|
+
let unitIndex = 0;
|
|
25731
|
+
while (value >= 1024 && unitIndex < units.length - 1) {
|
|
25732
|
+
value /= 1024;
|
|
25733
|
+
unitIndex += 1;
|
|
25734
|
+
}
|
|
25735
|
+
return `${sign}${unitIndex === 0 ? String(value) : value.toFixed(value >= 10 ? 1 : 2)} ${units[unitIndex]}`;
|
|
25736
|
+
}
|
|
25737
|
+
function printUsage$1() {
|
|
25738
|
+
console.log(`
|
|
25739
|
+
Usage:
|
|
25740
|
+
makefx usage [summary] [--space <id>] [--from <date>] [--to <date>]
|
|
25741
|
+
makefx usage --json
|
|
25742
|
+
|
|
25743
|
+
Options:
|
|
25744
|
+
--space <id> Target space ID; defaults from the initialized project
|
|
25745
|
+
--from <date> Include usage at or after this date or ISO timestamp
|
|
25746
|
+
--to <date> Include usage at or before this date or ISO timestamp
|
|
25747
|
+
--json Print machine-readable output
|
|
25748
|
+
--env <env> Environment (production|stage|local)
|
|
25749
|
+
--local Shortcut for --env local
|
|
25750
|
+
`);
|
|
25751
|
+
}
|
|
25752
|
+
//#endregion
|
|
25753
|
+
//#region src/cli/commands/spend.ts
|
|
25754
|
+
var defaultDeps$1 = {
|
|
25755
|
+
loadConfig: loadStoredConfig,
|
|
25756
|
+
loadProjectConfig,
|
|
25757
|
+
resolveBaseUrl,
|
|
25758
|
+
fetch,
|
|
25759
|
+
print: console.log
|
|
25760
|
+
};
|
|
25761
|
+
async function handleSpend(parsed) {
|
|
25762
|
+
try {
|
|
25763
|
+
await executeSpend(parsed);
|
|
25764
|
+
} catch (error) {
|
|
25765
|
+
console.error("Error:", error instanceof Error ? error.message : error);
|
|
25766
|
+
printSpend();
|
|
25767
|
+
process$1.exitCode = 1;
|
|
25768
|
+
}
|
|
25769
|
+
}
|
|
25770
|
+
async function executeSpend(parsed, deps = defaultDeps$1) {
|
|
25771
|
+
const subcommand = parsed.positionals[0] || "summary";
|
|
25772
|
+
if (subcommand !== "summary") throw new Error(`Unknown spend command: ${subcommand}`);
|
|
25773
|
+
const summary = await fetchSpendSummary(await buildContext$1(parsed, deps), deps, {
|
|
25774
|
+
from: optionValue$1(parsed.options.from),
|
|
25775
|
+
to: optionValue$1(parsed.options.to),
|
|
25776
|
+
userId: optionValue$1(parsed.options["user-id"] ?? parsed.options.userId),
|
|
25777
|
+
spaceId: optionValue$1(parsed.options["space-id"] ?? parsed.options.spaceId ?? parsed.options.space),
|
|
25778
|
+
provider: optionValue$1(parsed.options.provider),
|
|
25779
|
+
mediaKind: optionValue$1(parsed.options["media-kind"] ?? parsed.options.mediaKind)
|
|
25780
|
+
});
|
|
25781
|
+
if (parsed.options.json === "true") deps.print(JSON.stringify(summary, null, 2));
|
|
25782
|
+
else printSpendSummary(summary, deps.print);
|
|
25783
|
+
return {
|
|
25784
|
+
type: "summary",
|
|
25785
|
+
summary
|
|
25786
|
+
};
|
|
25787
|
+
}
|
|
25788
|
+
async function buildContext$1(parsed, deps) {
|
|
25789
|
+
const env = resolveCommandEnvironment(parsed, await deps.loadProjectConfig());
|
|
25790
|
+
const config = await deps.loadConfig(env);
|
|
25791
|
+
if (!config) throw new Error(`Not logged in to ${env} environment. Run: ${loginCommandForEnvironment(env)}`);
|
|
25792
|
+
if (config.token.expiresAt < Date.now()) throw new Error(`Token expired for ${env} environment. Run: ${loginCommandForEnvironment(env)}`);
|
|
25793
|
+
if (env === "local") process$1.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
|
|
25794
|
+
return {
|
|
25795
|
+
env,
|
|
25796
|
+
baseUrl: deps.resolveBaseUrl(env),
|
|
25797
|
+
accessToken: config.token.accessToken
|
|
25798
|
+
};
|
|
25799
|
+
}
|
|
25800
|
+
async function fetchSpendSummary(ctx, deps, options) {
|
|
25801
|
+
const params = new URLSearchParams();
|
|
25802
|
+
if (options.from) params.set("from", options.from);
|
|
25803
|
+
if (options.to) params.set("to", options.to);
|
|
25804
|
+
if (options.userId) params.set("user_id", options.userId);
|
|
25805
|
+
if (options.spaceId) params.set("space_id", options.spaceId);
|
|
25806
|
+
if (options.provider) params.set("provider", options.provider);
|
|
25807
|
+
if (options.mediaKind) params.set("media_kind", options.mediaKind);
|
|
25808
|
+
const query = params.toString();
|
|
25809
|
+
const response = await deps.fetch(`${ctx.baseUrl}/api/billing/spend/summary${query ? `?${query}` : ""}`, { headers: {
|
|
25810
|
+
"Authorization": `Bearer ${ctx.accessToken}`,
|
|
25811
|
+
"Accept": "application/json"
|
|
25812
|
+
} });
|
|
25813
|
+
if (!response.ok) {
|
|
25814
|
+
const text = await response.text();
|
|
25815
|
+
throw new Error(`Request failed (${response.status}): ${text || response.statusText}`);
|
|
25816
|
+
}
|
|
25817
|
+
return response.json();
|
|
25818
|
+
}
|
|
25819
|
+
function optionValue$1(value) {
|
|
25820
|
+
return !value || value === "true" ? void 0 : value;
|
|
25821
|
+
}
|
|
25822
|
+
function printSpendSummary(summary, print) {
|
|
25823
|
+
print("\nProvider cost summary\n");
|
|
25824
|
+
print(` Period: ${formatPeriod(summary.period)}`);
|
|
25825
|
+
print(` Filters: ${formatFilters(summary.filters)}`);
|
|
25826
|
+
print(` Provider cost: ${formatUsd(summary.totals.amountMicroUsd)}`);
|
|
25827
|
+
print(` Entries: ${summary.totals.entries}`);
|
|
25828
|
+
print(` Unpriced: ${summary.totals.unpricedEntries}`);
|
|
25829
|
+
print(` Quantity: ${formatNumber(summary.totals.quantity)}`);
|
|
25830
|
+
if (summary.byProvider.length > 0) printSpendTable("\nBy provider:", [
|
|
25831
|
+
"Provider",
|
|
25832
|
+
"Cost",
|
|
25833
|
+
"Entries",
|
|
25834
|
+
"Unpriced",
|
|
25835
|
+
"Quantity"
|
|
25836
|
+
], summary.byProvider.map((row) => [
|
|
25837
|
+
row.provider,
|
|
25838
|
+
formatUsd(row.amountMicroUsd),
|
|
25839
|
+
String(row.entries),
|
|
25840
|
+
String(row.unpricedEntries),
|
|
25841
|
+
formatNumber(row.quantity)
|
|
25842
|
+
]), print);
|
|
25843
|
+
if (summary.byModel.length > 0) printSpendTable("\nBy model:", [
|
|
25844
|
+
"Provider",
|
|
25845
|
+
"Model",
|
|
25846
|
+
"Cost",
|
|
25847
|
+
"Entries",
|
|
25848
|
+
"Unpriced"
|
|
25849
|
+
], summary.byModel.map((row) => [
|
|
25850
|
+
row.provider,
|
|
25851
|
+
row.providerModel,
|
|
25852
|
+
formatUsd(row.amountMicroUsd),
|
|
25853
|
+
String(row.entries),
|
|
25854
|
+
String(row.unpricedEntries)
|
|
25855
|
+
]), print);
|
|
25856
|
+
if (summary.byMediaKind.length > 0) printSpendTable("\nBy media kind:", [
|
|
25857
|
+
"Media",
|
|
25858
|
+
"Cost",
|
|
25859
|
+
"Entries",
|
|
25860
|
+
"Unpriced",
|
|
25861
|
+
"Quantity"
|
|
25862
|
+
], summary.byMediaKind.map((row) => [
|
|
25863
|
+
row.mediaKind || "-",
|
|
25864
|
+
formatUsd(row.amountMicroUsd),
|
|
25865
|
+
String(row.entries),
|
|
25866
|
+
String(row.unpricedEntries),
|
|
25867
|
+
formatNumber(row.quantity)
|
|
25868
|
+
]), print);
|
|
25869
|
+
if (summary.byMeterEventName.length > 0) printSpendTable("\nBy meter:", [
|
|
25870
|
+
"Meter",
|
|
25871
|
+
"Cost",
|
|
25872
|
+
"Entries",
|
|
25873
|
+
"Unpriced",
|
|
25874
|
+
"Quantity"
|
|
25875
|
+
], summary.byMeterEventName.map((row) => [
|
|
25876
|
+
row.meterEventName || "-",
|
|
25877
|
+
formatUsd(row.amountMicroUsd),
|
|
25878
|
+
String(row.entries),
|
|
25879
|
+
String(row.unpricedEntries),
|
|
25880
|
+
formatNumber(row.quantity)
|
|
25881
|
+
]), print);
|
|
25882
|
+
}
|
|
25883
|
+
function printSpendTable(title, headers, rows, print) {
|
|
25884
|
+
print(title);
|
|
25885
|
+
const widths = headers.map((header, index) => Math.max(header.length, ...rows.map((row) => row[index]?.length ?? 0)));
|
|
25886
|
+
print(headers.map((header, index) => header.padEnd(widths[index] + 2)).join("").trimEnd());
|
|
25887
|
+
print(widths.map((width) => "-".repeat(width)).join(" "));
|
|
25888
|
+
for (const row of rows) print(row.map((value, index) => value.padEnd(widths[index] + 2)).join("").trimEnd());
|
|
25889
|
+
}
|
|
25890
|
+
function formatPeriod(period) {
|
|
25891
|
+
if (!period.from && !period.to) return "all time";
|
|
25892
|
+
if (period.from && period.to) return `${period.from} to ${period.to}`;
|
|
25893
|
+
if (period.from) return `from ${period.from}`;
|
|
25894
|
+
return `through ${period.to}`;
|
|
25895
|
+
}
|
|
25896
|
+
function formatFilters(filters) {
|
|
25897
|
+
const parts = [
|
|
25898
|
+
filters.userId !== null ? `user=${filters.userId}` : null,
|
|
25899
|
+
filters.spaceId ? `space=${filters.spaceId}` : null,
|
|
25900
|
+
filters.provider ? `provider=${filters.provider}` : null,
|
|
25901
|
+
filters.mediaKind ? `media=${filters.mediaKind}` : null
|
|
25902
|
+
].filter((part) => part !== null);
|
|
25903
|
+
return parts.length > 0 ? parts.join(", ") : "none";
|
|
25904
|
+
}
|
|
25905
|
+
function formatUsd(amountMicroUsd) {
|
|
25906
|
+
let trimmed = (amountMicroUsd / 1e6).toFixed(6).replace(/0+$/, "").replace(/\.$/, "");
|
|
25907
|
+
if (!trimmed.includes(".")) trimmed = `${trimmed}.00`;
|
|
25908
|
+
else if (trimmed.split(".")[1].length === 1) trimmed = `${trimmed}0`;
|
|
25909
|
+
return `$${trimmed}`;
|
|
25910
|
+
}
|
|
25911
|
+
function formatNumber(value) {
|
|
25912
|
+
return Number.isInteger(value) ? String(value) : value.toFixed(3).replace(/0+$/, "").replace(/\.$/, "");
|
|
25913
|
+
}
|
|
25914
|
+
function printSpend() {
|
|
25915
|
+
console.log(`
|
|
25916
|
+
Usage:
|
|
25917
|
+
makefx spend [summary] [--from <date>] [--to <date>]
|
|
25918
|
+
makefx spend --user-id <id> --provider <name> --media-kind <image|audio|video>
|
|
25919
|
+
makefx spend --json
|
|
25920
|
+
|
|
25921
|
+
Options:
|
|
25922
|
+
--from <date> Include provider cost at or after this date or ISO timestamp
|
|
25923
|
+
--to <date> Include provider cost at or before this date or ISO timestamp
|
|
25924
|
+
--user-id <id> Filter to one user ID
|
|
25925
|
+
--space-id <id> Filter to one space ID
|
|
25926
|
+
--space <id> Alias for --space-id
|
|
25927
|
+
--provider <name> Filter to one provider
|
|
25928
|
+
--media-kind <kind> Filter to image, audio, or video provider cost
|
|
25929
|
+
--json Print machine-readable output
|
|
25930
|
+
--env <env> Environment (production|stage|local)
|
|
25931
|
+
--local Shortcut for --env local
|
|
25932
|
+
`);
|
|
25933
|
+
}
|
|
25934
|
+
//#endregion
|
|
25935
|
+
//#region src/shared/featureFlags.ts
|
|
25936
|
+
var TRUE_VALUES = new Set([
|
|
25937
|
+
"1",
|
|
25938
|
+
"true",
|
|
25939
|
+
"yes",
|
|
25940
|
+
"on"
|
|
25941
|
+
]);
|
|
25942
|
+
var ROTATION_FEATURE_FLAG = "MAKEFX_ROTATION_ENABLED";
|
|
25943
|
+
function isFeatureFlagEnabled(value) {
|
|
25944
|
+
if (typeof value === "boolean") return value;
|
|
25945
|
+
if (typeof value === "number") return value === 1;
|
|
25946
|
+
if (typeof value !== "string") return false;
|
|
25947
|
+
return TRUE_VALUES.has(value.trim().toLowerCase());
|
|
25948
|
+
}
|
|
25949
|
+
//#endregion
|
|
25950
|
+
//#region src/cli/lib/feature-flags.ts
|
|
25951
|
+
function isCliRotationEnabled(env = process.env) {
|
|
25952
|
+
return isFeatureFlagEnabled(env[ROTATION_FEATURE_FLAG]);
|
|
25953
|
+
}
|
|
25954
|
+
function rotationDisabledMessage() {
|
|
25955
|
+
return `Rotation features are disabled. Set ${ROTATION_FEATURE_FLAG}=true to enable this experimental surface.`;
|
|
25956
|
+
}
|
|
25957
|
+
//#endregion
|
|
23349
25958
|
//#region src/cli/commands/pipelines.ts
|
|
23350
25959
|
var ROTATION_CONFIGS = [
|
|
23351
25960
|
"4-directional",
|
|
@@ -23364,6 +25973,7 @@ var defaultDeps = {
|
|
|
23364
25973
|
loadProjectConfig,
|
|
23365
25974
|
resolveBaseUrl,
|
|
23366
25975
|
createClient: (env, spaceId) => WebSocketClient.create(env, spaceId),
|
|
25976
|
+
isRotationEnabled: isCliRotationEnabled,
|
|
23367
25977
|
print: console.log
|
|
23368
25978
|
};
|
|
23369
25979
|
async function handleRotation(parsed) {
|
|
@@ -23377,12 +25987,15 @@ async function handlePipelineCommand(command, parsed) {
|
|
|
23377
25987
|
const result = await executePipelineCommand(command, parsed, defaultDeps);
|
|
23378
25988
|
if ("status" in result && (result.status === "failed" || result.status === "cancelled")) process$1.exitCode = 1;
|
|
23379
25989
|
} catch (error) {
|
|
23380
|
-
|
|
23381
|
-
|
|
25990
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
25991
|
+
console.error("Error:", message);
|
|
25992
|
+
if (message !== rotationDisabledMessage()) printUsage(command);
|
|
23382
25993
|
process$1.exitCode = 1;
|
|
23383
25994
|
}
|
|
23384
25995
|
}
|
|
23385
25996
|
async function executePipelineCommand(command, parsed, deps = defaultDeps) {
|
|
25997
|
+
const rotationEnabled = deps.isRotationEnabled ?? isCliRotationEnabled;
|
|
25998
|
+
if (command === "rotation" && !rotationEnabled()) throw new Error(rotationDisabledMessage());
|
|
23386
25999
|
const ctx = await buildContext(parsed, deps);
|
|
23387
26000
|
const client = await deps.createClient(ctx.env, ctx.spaceId);
|
|
23388
26001
|
try {
|
|
@@ -23584,6 +26197,10 @@ function printJsonOrText(json, result, text, deps) {
|
|
|
23584
26197
|
}
|
|
23585
26198
|
function printUsage(command) {
|
|
23586
26199
|
if (command === "rotation") {
|
|
26200
|
+
if (!isCliRotationEnabled()) {
|
|
26201
|
+
console.log(rotationDisabledMessage());
|
|
26202
|
+
return;
|
|
26203
|
+
}
|
|
23587
26204
|
console.log(`
|
|
23588
26205
|
Usage:
|
|
23589
26206
|
makefx rotation --variant <variant-id> [--config 4-directional|8-directional|turnaround]
|
|
@@ -23596,7 +26213,7 @@ Options:
|
|
|
23596
26213
|
--subject <text> Optional subject description for consistency prompts
|
|
23597
26214
|
--aspect <ratio> Optional generation aspect ratio
|
|
23598
26215
|
--mode <mode> sequential or single-shot (default: sequential)
|
|
23599
|
-
--no-style Disable
|
|
26216
|
+
--no-style Disable style preset injection for this pipeline
|
|
23600
26217
|
--detach Return after the pipeline starts instead of waiting for completion
|
|
23601
26218
|
--timeout <sec> Override the pipeline wait timeout
|
|
23602
26219
|
--json Print machine-readable output
|
|
@@ -23618,7 +26235,7 @@ Options:
|
|
|
23618
26235
|
--seed-variant <id> Optional completed image variant to place at the center (sequential mode only)
|
|
23619
26236
|
--aspect <ratio> Optional generation aspect ratio
|
|
23620
26237
|
--mode <mode> sequential or single-shot (default: sequential)
|
|
23621
|
-
--no-style Disable
|
|
26238
|
+
--no-style Disable style preset injection for this pipeline
|
|
23622
26239
|
--detach Return after the pipeline starts instead of waiting for completion
|
|
23623
26240
|
--timeout <sec> Override the pipeline wait timeout
|
|
23624
26241
|
--json Print machine-readable output
|
|
@@ -23626,7 +26243,7 @@ Options:
|
|
|
23626
26243
|
}
|
|
23627
26244
|
//#endregion
|
|
23628
26245
|
//#region src/cli/index.ts
|
|
23629
|
-
var CLI_VERSION = "0.
|
|
26246
|
+
var CLI_VERSION = "0.2.0+a98a786097bf";
|
|
23630
26247
|
async function main() {
|
|
23631
26248
|
const argv = process$1.argv.slice(2);
|
|
23632
26249
|
if (argv[0] === "--") argv.shift();
|
|
@@ -23735,6 +26352,9 @@ function printCommandHelp(command, positionals) {
|
|
|
23735
26352
|
case "upload":
|
|
23736
26353
|
printUploadHelp();
|
|
23737
26354
|
return;
|
|
26355
|
+
case "import":
|
|
26356
|
+
printImportHelp();
|
|
26357
|
+
return;
|
|
23738
26358
|
case "generate":
|
|
23739
26359
|
case "refine":
|
|
23740
26360
|
case "derive":
|
|
@@ -23753,10 +26373,20 @@ function printCommandHelp(command, positionals) {
|
|
|
23753
26373
|
case "assets":
|
|
23754
26374
|
printAssetsHelp();
|
|
23755
26375
|
return;
|
|
26376
|
+
case "usage":
|
|
26377
|
+
printUsageHelp();
|
|
26378
|
+
return;
|
|
26379
|
+
case "spend":
|
|
26380
|
+
printSpendHelp();
|
|
26381
|
+
return;
|
|
23756
26382
|
case "variants":
|
|
23757
26383
|
case "variant":
|
|
23758
26384
|
printVariantsHelp();
|
|
23759
26385
|
return;
|
|
26386
|
+
case "styles":
|
|
26387
|
+
case "style":
|
|
26388
|
+
printStylesHelp();
|
|
26389
|
+
return;
|
|
23760
26390
|
case "rotation":
|
|
23761
26391
|
printRotationHelp();
|
|
23762
26392
|
return;
|
|
@@ -23775,6 +26405,11 @@ function printCommandHelp(command, positionals) {
|
|
|
23775
26405
|
}
|
|
23776
26406
|
}
|
|
23777
26407
|
function printHelp() {
|
|
26408
|
+
const rotationHelp = isCliRotationEnabled() ? ` rotation --variant <variant-id>
|
|
26409
|
+
Generate rotation views from a completed image variant
|
|
26410
|
+
rotation cancel <rotation-set-id>
|
|
26411
|
+
Cancel an active rotation pipeline` : "";
|
|
26412
|
+
const rotationExample = isCliRotationEnabled() ? " makefx rotation --variant variant_456 --config 8-directional\n" : "";
|
|
23778
26413
|
console.log(`
|
|
23779
26414
|
Make Effects CLI
|
|
23780
26415
|
|
|
@@ -23802,10 +26437,10 @@ Project:
|
|
|
23802
26437
|
variants star <variant-id> Star a variant (unstar to clear)
|
|
23803
26438
|
variants rate <variant-id> approved|rejected
|
|
23804
26439
|
Rate a variant for quality curation
|
|
23805
|
-
|
|
23806
|
-
|
|
23807
|
-
|
|
23808
|
-
|
|
26440
|
+
styles presets List style presets
|
|
26441
|
+
styles collections List style reference collections
|
|
26442
|
+
styles references List style reference assets
|
|
26443
|
+
${rotationHelp}
|
|
23809
26444
|
tileset "prompt" --type terrain --grid 3x3
|
|
23810
26445
|
Generate a consistent tile set
|
|
23811
26446
|
tileset cancel <tile-set-id> Cancel an active tile-set pipeline
|
|
@@ -23813,12 +26448,14 @@ Project:
|
|
|
23813
26448
|
List Space-backed production placements
|
|
23814
26449
|
productions export --production-id <id>
|
|
23815
26450
|
Export production scene args from Space records
|
|
26451
|
+
usage [summary] [--space <id>] Show platform storage and workflow consumption
|
|
26452
|
+
spend [summary] Show admin provider cost summary
|
|
23816
26453
|
|
|
23817
26454
|
Billing (Polar.sh):
|
|
23818
26455
|
billing status Show sync status (pending, failed, synced events)
|
|
23819
26456
|
billing check Run operational checks for workers, meters, and sync health
|
|
23820
26457
|
billing reconcile --user-id <id>
|
|
23821
|
-
|
|
26458
|
+
Reconcile Polar, charge, provider, and platform usage
|
|
23822
26459
|
billing retry-failed Retry all failed events
|
|
23823
26460
|
|
|
23824
26461
|
Spaces:
|
|
@@ -23835,6 +26472,7 @@ Listen:
|
|
|
23835
26472
|
Upload:
|
|
23836
26473
|
upload <file> --asset <id> [--space <id>] Upload image, audio, or video to existing asset
|
|
23837
26474
|
upload <file> --name <name> [--space <id>] Upload media and create new asset
|
|
26475
|
+
import <manifest.json> [--space <id>] Import media with provenance, lineage, and organization metadata
|
|
23838
26476
|
|
|
23839
26477
|
Forge:
|
|
23840
26478
|
generate "prompt" --name <name> --type <type> -o <file>
|
|
@@ -23876,14 +26514,20 @@ Examples:
|
|
|
23876
26514
|
makefx audio sfx generate "A short brass victory sting" --name "Victory Sting" -o victory.wav
|
|
23877
26515
|
makefx video generate "A looping idle animation" --name "Idle Animation" --type animation --duration 6 --resolution 1080p --tier fast -o idle.mp4
|
|
23878
26516
|
makefx productions export --production-id s01e01-a2
|
|
26517
|
+
makefx import import-manifest.json --dry-run --json
|
|
26518
|
+
makefx import external-renders.json --space space_123
|
|
23879
26519
|
makefx assets
|
|
26520
|
+
makefx usage --from 2026-06-01
|
|
26521
|
+
makefx spend --from 2026-06-01 --provider gemini
|
|
23880
26522
|
makefx assets download variant_123 -o variant.mp4
|
|
23881
26523
|
makefx assets rename asset_123 "Hero (moving)"
|
|
23882
26524
|
makefx assets set-active asset_123 variant_456
|
|
23883
26525
|
makefx variants retry variant_456
|
|
23884
26526
|
makefx variants delete variant_456
|
|
23885
|
-
makefx
|
|
23886
|
-
makefx
|
|
26527
|
+
makefx styles collections create "Painterly refs" --refs asset_123,variant_456
|
|
26528
|
+
makefx styles presets create "Painterly" --collection collection_123 --prompt "Painterly adventure game" --default
|
|
26529
|
+
makefx generate "A market background" --style-preset Painterly --name "Market" --type scene -o market.png
|
|
26530
|
+
${rotationExample} makefx tileset "grass and stone path tiles" --type terrain --grid 3x3
|
|
23887
26531
|
`);
|
|
23888
26532
|
}
|
|
23889
26533
|
function printInitHelp() {
|
|
@@ -23918,7 +26562,7 @@ Usage:
|
|
|
23918
26562
|
Subcommands:
|
|
23919
26563
|
status Show sync status (pending, failed, synced events)
|
|
23920
26564
|
check Run operational checks for workers, Polar meters, and sync health
|
|
23921
|
-
reconcile
|
|
26565
|
+
reconcile Reconcile Polar, charge, provider, and platform usage for one user
|
|
23922
26566
|
retry-failed Reset failed events for retry (next cron will sync them)
|
|
23923
26567
|
|
|
23924
26568
|
Options:
|
|
@@ -23956,11 +26600,35 @@ Options:
|
|
|
23956
26600
|
--name <name> New asset name (creates asset + variant)
|
|
23957
26601
|
--type <type> Asset type for new assets (default: character)
|
|
23958
26602
|
--media-kind <k> Optional explicit kind: image, audio, or video
|
|
23959
|
-
--parent <id> Parent asset ID for new assets
|
|
23960
26603
|
--env <env> Environment (production|stage|local)
|
|
23961
26604
|
--local Shortcut for --env local
|
|
23962
26605
|
`);
|
|
23963
26606
|
}
|
|
26607
|
+
function printImportHelp() {
|
|
26608
|
+
console.log(`
|
|
26609
|
+
Usage:
|
|
26610
|
+
makefx import <manifest.json> [--space <id>]
|
|
26611
|
+
makefx import <manifest.json> --dry-run [--json]
|
|
26612
|
+
|
|
26613
|
+
Options:
|
|
26614
|
+
--space <id> Target space ID; defaults from initialized project
|
|
26615
|
+
--dry-run Validate manifest, files, targets, membership, lineage, and organization references
|
|
26616
|
+
--json Print machine-readable import or dry-run output
|
|
26617
|
+
--env <env> Environment (production|stage|local)
|
|
26618
|
+
--local Shortcut for --env local
|
|
26619
|
+
|
|
26620
|
+
Manifest:
|
|
26621
|
+
Records import files with prompt, model, provider, providerMetadata, and
|
|
26622
|
+
generationProvenance. Lineage entries record immutable source provenance using
|
|
26623
|
+
sourceFile or sourceVariantId; use collections, relations, and compositions
|
|
26624
|
+
for editable organization metadata. Style references are normal assets grouped
|
|
26625
|
+
into collections and selected through style presets.
|
|
26626
|
+
|
|
26627
|
+
Examples:
|
|
26628
|
+
makefx import external-renders.json --dry-run --json
|
|
26629
|
+
makefx import external-renders.json --space space_123
|
|
26630
|
+
`);
|
|
26631
|
+
}
|
|
23964
26632
|
function printForgeHelp(command) {
|
|
23965
26633
|
if (command === "generate") {
|
|
23966
26634
|
console.log(`
|
|
@@ -23970,6 +26638,10 @@ Usage:
|
|
|
23970
26638
|
|
|
23971
26639
|
${imageCapabilityHelp()}
|
|
23972
26640
|
|
|
26641
|
+
Style:
|
|
26642
|
+
--style-preset <id-or-name> Use an enabled style preset for this generation
|
|
26643
|
+
--no-style Disable style preset injection for this generation
|
|
26644
|
+
|
|
23973
26645
|
Production metadata:
|
|
23974
26646
|
--scene-label <label> --timeline-start-ms <ms> --duration-ms <ms>
|
|
23975
26647
|
--shot-id <id> --production-id <id>
|
|
@@ -23984,6 +26656,10 @@ Usage:
|
|
|
23984
26656
|
|
|
23985
26657
|
${imageCapabilityHelp()}
|
|
23986
26658
|
|
|
26659
|
+
Style:
|
|
26660
|
+
--style-preset <id-or-name> Use an enabled style preset for this refinement
|
|
26661
|
+
--no-style Disable style preset injection for this refinement
|
|
26662
|
+
|
|
23987
26663
|
Production metadata:
|
|
23988
26664
|
--scene-label <label> --timeline-start-ms <ms> --duration-ms <ms>
|
|
23989
26665
|
--shot-id <id> --production-id <id>
|
|
@@ -23996,6 +26672,10 @@ Usage:
|
|
|
23996
26672
|
makefx batch "prompt" --name <name> --type <type> --count <2-8> --output-dir <dir> [--model ${optionValues(IMAGE_MODEL_SELECTIONS)}] [--size ${imageSizeValues()}] [--aspect <ratio>]
|
|
23997
26673
|
|
|
23998
26674
|
${imageCapabilityHelp()}
|
|
26675
|
+
|
|
26676
|
+
Style:
|
|
26677
|
+
--style-preset <id-or-name> Use an enabled style preset for this batch
|
|
26678
|
+
--no-style Disable style preset injection for this batch
|
|
23999
26679
|
`);
|
|
24000
26680
|
return;
|
|
24001
26681
|
}
|
|
@@ -24006,6 +26686,10 @@ Usage:
|
|
|
24006
26686
|
|
|
24007
26687
|
${imageCapabilityHelp()}
|
|
24008
26688
|
|
|
26689
|
+
Style:
|
|
26690
|
+
--style-preset <id-or-name> Use an enabled style preset for this derivation
|
|
26691
|
+
--no-style Disable style preset injection for this derivation
|
|
26692
|
+
|
|
24009
26693
|
Production metadata:
|
|
24010
26694
|
--scene-label <label> --timeline-start-ms <ms> --duration-ms <ms>
|
|
24011
26695
|
--shot-id <id> --production-id <id>
|
|
@@ -24203,7 +26887,43 @@ Options:
|
|
|
24203
26887
|
--local Shortcut for --env local
|
|
24204
26888
|
`);
|
|
24205
26889
|
}
|
|
26890
|
+
function printStylesHelp() {
|
|
26891
|
+
console.log(`
|
|
26892
|
+
Usage:
|
|
26893
|
+
makefx styles references [--collection <id-or-name>] [--json]
|
|
26894
|
+
makefx styles collections list [--json]
|
|
26895
|
+
makefx styles collections create <name> --refs <asset_or_variant,...>
|
|
26896
|
+
makefx styles collections update <collection-id> [--name <name>] [--refs <asset_or_variant,...>] [--append]
|
|
26897
|
+
makefx styles presets list [--json]
|
|
26898
|
+
makefx styles presets create <name> --collection <collection-id> --prompt "style prompt" [--default]
|
|
26899
|
+
makefx styles presets update <preset-id> [--name <name>] [--collection <collection-id>] [--prompt "style prompt"]
|
|
26900
|
+
makefx styles presets enable <preset-id>
|
|
26901
|
+
makefx styles presets disable <preset-id>
|
|
26902
|
+
makefx styles presets delete <preset-id>
|
|
26903
|
+
|
|
26904
|
+
Generation:
|
|
26905
|
+
makefx generate "prompt" --style-preset <id-or-name> --name <name> --type <type> -o <file>
|
|
26906
|
+
makefx generate "prompt" --no-style --name <name> --type <type> -o <file>
|
|
26907
|
+
|
|
26908
|
+
Model:
|
|
26909
|
+
Style references are normal Space assets or exact variants grouped into style
|
|
26910
|
+
collections. Style presets point to those collections plus a style prompt.
|
|
26911
|
+
|
|
26912
|
+
Options:
|
|
26913
|
+
--space <id> Target space ID; defaults from the initialized project
|
|
26914
|
+
--refs <ids> Comma-separated asset IDs or variant IDs to use as style references
|
|
26915
|
+
--assets <ids> Comma-separated asset IDs; active variants are pinned
|
|
26916
|
+
--variants <ids> Comma-separated variant IDs
|
|
26917
|
+
--json Print machine-readable output
|
|
26918
|
+
--env <env> Environment (production|stage|local)
|
|
26919
|
+
--local Shortcut for --env local
|
|
26920
|
+
`);
|
|
26921
|
+
}
|
|
24206
26922
|
function printRotationHelp() {
|
|
26923
|
+
if (!isCliRotationEnabled()) {
|
|
26924
|
+
console.log(rotationDisabledMessage());
|
|
26925
|
+
return;
|
|
26926
|
+
}
|
|
24207
26927
|
console.log(`
|
|
24208
26928
|
Usage:
|
|
24209
26929
|
makefx rotation --variant <variant-id> [--config 4-directional|8-directional|turnaround]
|
|
@@ -24216,7 +26936,7 @@ Options:
|
|
|
24216
26936
|
--subject <text> Optional subject description for consistency prompts
|
|
24217
26937
|
--aspect <ratio> Optional generation aspect ratio
|
|
24218
26938
|
--mode <mode> sequential or single-shot (default: sequential)
|
|
24219
|
-
--no-style Disable
|
|
26939
|
+
--no-style Disable style preset injection for this pipeline
|
|
24220
26940
|
--detach Return after the pipeline starts instead of waiting for completion
|
|
24221
26941
|
--timeout <sec> Override the pipeline wait timeout
|
|
24222
26942
|
--json Print machine-readable output
|
|
@@ -24238,7 +26958,7 @@ Options:
|
|
|
24238
26958
|
--seed-variant <id> Optional completed image variant to place at the center (sequential mode only)
|
|
24239
26959
|
--aspect <ratio> Optional generation aspect ratio
|
|
24240
26960
|
--mode <mode> sequential or single-shot (default: sequential)
|
|
24241
|
-
--no-style Disable
|
|
26961
|
+
--no-style Disable style preset injection for this pipeline
|
|
24242
26962
|
--detach Return after the pipeline starts instead of waiting for completion
|
|
24243
26963
|
--timeout <sec> Override the pipeline wait timeout
|
|
24244
26964
|
--json Print machine-readable output
|
|
@@ -24266,6 +26986,41 @@ Usage:
|
|
|
24266
26986
|
makefx assets download <variant-id|legacy-image-key> -o output-file
|
|
24267
26987
|
`);
|
|
24268
26988
|
}
|
|
26989
|
+
function printUsageHelp() {
|
|
26990
|
+
console.log(`
|
|
26991
|
+
Usage:
|
|
26992
|
+
makefx usage [summary] [--space <id>] [--from <date>] [--to <date>]
|
|
26993
|
+
makefx usage --json
|
|
26994
|
+
|
|
26995
|
+
Options:
|
|
26996
|
+
--space <id> Target space ID; defaults from the initialized project
|
|
26997
|
+
--from <date> Include usage at or after this date or ISO timestamp
|
|
26998
|
+
--to <date> Include usage at or before this date or ISO timestamp
|
|
26999
|
+
--json Print machine-readable output
|
|
27000
|
+
--env <env> Environment (production|stage|local)
|
|
27001
|
+
--local Shortcut for --env local
|
|
27002
|
+
`);
|
|
27003
|
+
}
|
|
27004
|
+
function printSpendHelp() {
|
|
27005
|
+
console.log(`
|
|
27006
|
+
Usage:
|
|
27007
|
+
makefx spend [summary] [--from <date>] [--to <date>]
|
|
27008
|
+
makefx spend --user-id <id> --provider <name> --media-kind <image|audio|video>
|
|
27009
|
+
makefx spend --json
|
|
27010
|
+
|
|
27011
|
+
Options:
|
|
27012
|
+
--from <date> Include provider cost at or after this date or ISO timestamp
|
|
27013
|
+
--to <date> Include provider cost at or before this date or ISO timestamp
|
|
27014
|
+
--user-id <id> Filter to one user ID
|
|
27015
|
+
--space-id <id> Filter to one space ID
|
|
27016
|
+
--space <id> Alias for --space-id
|
|
27017
|
+
--provider <name> Filter to one provider
|
|
27018
|
+
--media-kind <kind> Filter to image, audio, or video provider cost
|
|
27019
|
+
--json Print machine-readable output
|
|
27020
|
+
--env <env> Environment (production|stage|local)
|
|
27021
|
+
--local Shortcut for --env local
|
|
27022
|
+
`);
|
|
27023
|
+
}
|
|
24269
27024
|
async function dispatchCommand(command, parsed) {
|
|
24270
27025
|
switch (command) {
|
|
24271
27026
|
case "init":
|
|
@@ -24289,6 +27044,9 @@ async function dispatchCommand(command, parsed) {
|
|
|
24289
27044
|
case "upload":
|
|
24290
27045
|
await handleUpload(parsed);
|
|
24291
27046
|
break;
|
|
27047
|
+
case "import":
|
|
27048
|
+
await handleImport(parsed);
|
|
27049
|
+
break;
|
|
24292
27050
|
case "generate":
|
|
24293
27051
|
await handleGenerate(parsed);
|
|
24294
27052
|
break;
|
|
@@ -24313,10 +27071,20 @@ async function dispatchCommand(command, parsed) {
|
|
|
24313
27071
|
case "assets":
|
|
24314
27072
|
await handleAssets(parsed);
|
|
24315
27073
|
break;
|
|
27074
|
+
case "usage":
|
|
27075
|
+
await handleUsage(parsed);
|
|
27076
|
+
break;
|
|
27077
|
+
case "spend":
|
|
27078
|
+
await handleSpend(parsed);
|
|
27079
|
+
break;
|
|
24316
27080
|
case "variants":
|
|
24317
27081
|
case "variant":
|
|
24318
27082
|
await handleVariants(parsed);
|
|
24319
27083
|
break;
|
|
27084
|
+
case "styles":
|
|
27085
|
+
case "style":
|
|
27086
|
+
await handleStyles(parsed);
|
|
27087
|
+
break;
|
|
24320
27088
|
case "rotation":
|
|
24321
27089
|
await handleRotation(parsed);
|
|
24322
27090
|
break;
|