@uniformdev/cli 20.74.6-alpha.2 → 20.74.6-alpha.3

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.
@@ -388,6 +388,16 @@ function readFileToObject(filename) {
388
388
  const file = readFileSync(filename, "utf8");
389
389
  return load(file, { filename, json: true });
390
390
  }
391
+ var ENTITY_ID_CHUNK_SIZE = 100;
392
+ function* chunkEntityIds(ids, chunkSize = ENTITY_ID_CHUNK_SIZE) {
393
+ if (!ids) {
394
+ yield void 0;
395
+ return;
396
+ }
397
+ for (let index = 0; index < ids.length; index += chunkSize) {
398
+ yield ids.slice(index, index + chunkSize);
399
+ }
400
+ }
391
401
  async function* paginateAsync(fetchPage, options) {
392
402
  const pageSize = options.pageSize ?? 100;
393
403
  if (pageSize < 1) {
@@ -440,6 +450,21 @@ function getEntityBatchSize(entityType, config) {
440
450
  }
441
451
  return entityBatchSizeDefaults[entityType];
442
452
  }
453
+ function getPublishScope(entityType, config) {
454
+ const publish = config.entitiesConfig?.[entityType]?.publish;
455
+ if (!publish) {
456
+ return void 0;
457
+ }
458
+ if (publish === true || publish === "all") {
459
+ return "all";
460
+ }
461
+ if (publish === "pushed") {
462
+ return "pushed";
463
+ }
464
+ throw new Error(
465
+ `Invalid publish option '${publish}' for ${entityType}. Expected true, false, 'all', or 'pushed'.`
466
+ );
467
+ }
443
468
  function resolveEntityBatchSize({
444
469
  entityType,
445
470
  cliBatchSize,
@@ -549,9 +574,11 @@ export {
549
574
  isPathAPackageFile,
550
575
  emitWithFormat,
551
576
  readFileToObject,
577
+ chunkEntityIds,
552
578
  paginateAsync,
553
579
  isPaginatedSyncEntity,
554
580
  getEntityBatchSize,
581
+ getPublishScope,
555
582
  withBatchSizeOptions,
556
583
  applyDefaultSyncConfiguration,
557
584
  getEntityOption,
@@ -1,4 +1,4 @@
1
- import { C as CLIConfiguration, E as EntityTypes } from './index-DeoTNXj-.mjs';
1
+ import { C as CLIConfiguration, E as EntityTypes } from './index-CxaxRfj3.mjs';
2
2
 
3
3
  type UniformConfigAllOptions = {
4
4
  /**
@@ -1,4 +1,4 @@
1
- import "./chunk-TPAFG3LW.mjs";
1
+ import "./chunk-IBJEWQVU.mjs";
2
2
 
3
3
  // src/sync/allSerializableEntitiesConfig.ts
4
4
  var allSerializableEntitiesConfig = {
@@ -11,11 +11,11 @@ var allSerializableEntitiesConfig = {
11
11
  projectMapDefinition: {},
12
12
  projectMapNode: {},
13
13
  contentType: {},
14
- composition: { publish: true },
15
- entry: { publish: true },
16
- entryPattern: { publish: true },
17
- componentPattern: { publish: true },
18
- compositionPattern: { publish: true },
14
+ composition: { publish: "all" },
15
+ entry: { publish: "all" },
16
+ entryPattern: { publish: "all" },
17
+ componentPattern: { publish: "all" },
18
+ compositionPattern: { publish: "all" },
19
19
  asset: {},
20
20
  workflow: {},
21
21
  webhook: {},
@@ -13,8 +13,17 @@ type EntityConfiguration = {
13
13
  disabled?: true;
14
14
  };
15
15
  type EntityWithStateConfiguration = EntityConfiguration & Partial<StateArgs>;
16
+ /**
17
+ * What a push should publish once it has written its entities to preview.
18
+ *
19
+ * - `all`: publish every entity of this type in the project that has unpublished changes, whether or
20
+ * not it came from the push source. This is what `publish: true` has always done.
21
+ * - `pushed`: publish only the entities present in the push source (directory or package file).
22
+ */
23
+ type PublishScope = 'all' | 'pushed';
16
24
  type PublishableEntitiesConfiguration = EntityWithStateConfiguration & {
17
- publish?: boolean;
25
+ /** `true` is an alias for `'all'`, kept for backwards compatibility. */
26
+ publish?: boolean | PublishScope;
18
27
  batchSize?: number;
19
28
  };
20
29
  type SerializationEntitiesConfiguration = Record<EntityTypes, {
package/dist/index.d.mts CHANGED
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- export { C as CLIConfiguration } from './index-DeoTNXj-.mjs';
2
+ export { C as CLIConfiguration } from './index-CxaxRfj3.mjs';
package/dist/index.mjs CHANGED
@@ -3,10 +3,12 @@ import {
3
3
  CLI_USER_AGENT,
4
4
  __require,
5
5
  applyDefaultSyncConfiguration,
6
+ chunkEntityIds,
6
7
  emitWithFormat,
7
8
  getDirectoryOrFilename,
8
9
  getEntityBatchSize,
9
10
  getEntityOption,
11
+ getPublishScope,
10
12
  isPaginatedSyncEntity,
11
13
  isPathAPackageFile,
12
14
  nodeFetchProxy,
@@ -21,7 +23,7 @@ import {
21
23
  withFormatOptions,
22
24
  withProjectOptions,
23
25
  withTeamOptions
24
- } from "./chunk-TPAFG3LW.mjs";
26
+ } from "./chunk-IBJEWQVU.mjs";
25
27
 
26
28
  // src/index.ts
27
29
  import * as dotenv from "dotenv";
@@ -875,6 +877,7 @@ async function syncEngine({
875
877
  throw new SyncEngineError(e, sourceObject2);
876
878
  }
877
879
  } finally {
880
+ syncEngineEvents.emit("objectWritten", { id: ids[0], action: "update" });
878
881
  log2({
879
882
  action: "update",
880
883
  id: ids[0],
@@ -910,6 +913,7 @@ async function syncEngine({
910
913
  throw new SyncEngineError(e, sourceObject2);
911
914
  }
912
915
  } finally {
916
+ syncEngineEvents.emit("objectWritten", { id, action: "create" });
913
917
  log2({
914
918
  action: "create",
915
919
  id,
@@ -4208,16 +4212,28 @@ var selectIdentifier3 = (response) => {
4208
4212
  }
4209
4213
  return baseId;
4210
4214
  };
4211
- function parseCompositionSerializedId(providerId) {
4212
- const [compositionId, editionId] = providerId.split(" (");
4213
- return { compositionId, editionId: editionId?.slice(0, -1) };
4214
- }
4215
4215
  var selectDisplayName3 = (component) => {
4216
4216
  const name = component.composition._name ?? component.composition._slug ?? component.composition._id;
4217
4217
  const edition = component.editionId ? component.editionName ?? component.editionId : void 0;
4218
4218
  return `${name} (pid: ${component.composition._id}${edition ? `, edition: ${edition}` : ""})`;
4219
4219
  };
4220
4220
 
4221
+ // src/commands/canvas/util/serializedIds.ts
4222
+ function parseSerializedId(serializedId) {
4223
+ const [id, editionId] = serializedId.split(" (");
4224
+ return { id, editionId: editionId?.slice(0, -1) };
4225
+ }
4226
+ function splitSerializedIds(ids) {
4227
+ return ids.split(",").map((id) => id.trim()).filter(Boolean);
4228
+ }
4229
+ function toRawEntityIds(serializedIds) {
4230
+ const rawIds = serializedIds.map((serializedId) => {
4231
+ const { id, editionId } = parseSerializedId(serializedId);
4232
+ return editionId ?? id;
4233
+ });
4234
+ return Array.from(new Set(rawIds));
4235
+ }
4236
+
4221
4237
  // src/commands/canvas/componentInstanceEngineDataSource.ts
4222
4238
  function createComponentInstanceEngineDataSource({
4223
4239
  client,
@@ -4227,39 +4243,44 @@ function createComponentInstanceEngineDataSource({
4227
4243
  patternType,
4228
4244
  verbose,
4229
4245
  batchSize,
4246
+ editions = "all",
4230
4247
  ...clientOptions
4231
4248
  }) {
4232
4249
  const stateId = convertStateOption(state);
4233
4250
  async function* getObjects() {
4234
- const componentInstances = paginateAsync(
4235
- async (offset, limit2) => {
4236
- const parameters = {
4237
- ...clientOptions,
4238
- limit: limit2,
4239
- offset,
4240
- pattern: onlyCompositions ? false : onlyPatterns ? true : void 0,
4241
- state: stateId,
4242
- skipPatternResolution: true,
4243
- skipOverridesResolution: true,
4244
- withComponentIDs: true,
4245
- patternType,
4246
- editions: "all"
4251
+ const pageSize = batchSize ?? 100;
4252
+ for (const compositionIDsChunk of chunkEntityIds(clientOptions.compositionIDs)) {
4253
+ const componentInstances = paginateAsync(
4254
+ async (offset, limit2) => {
4255
+ const parameters = {
4256
+ ...clientOptions,
4257
+ compositionIDs: compositionIDsChunk,
4258
+ limit: limit2,
4259
+ offset,
4260
+ pattern: onlyCompositions ? false : onlyPatterns ? true : void 0,
4261
+ state: stateId,
4262
+ skipPatternResolution: true,
4263
+ skipOverridesResolution: true,
4264
+ withComponentIDs: true,
4265
+ patternType,
4266
+ editions
4267
+ };
4268
+ if (verbose) {
4269
+ console.log(`\u{1F41B} pull compositions: `, parameters);
4270
+ }
4271
+ return (await client.getCompositionList(parameters)).compositions;
4272
+ },
4273
+ { pageSize, verbose, entityName: "compositions" }
4274
+ );
4275
+ for await (const compositionListItem of componentInstances) {
4276
+ const result = {
4277
+ id: selectIdentifier3(compositionListItem),
4278
+ displayName: selectDisplayName3(compositionListItem),
4279
+ providerId: selectIdentifier3(compositionListItem),
4280
+ object: prepCompositionForDisk(compositionListItem)
4247
4281
  };
4248
- if (verbose) {
4249
- console.log(`\u{1F41B} pull compositions: `, parameters);
4250
- }
4251
- return (await client.getCompositionList(parameters)).compositions;
4252
- },
4253
- { pageSize: batchSize ?? 100, verbose, entityName: "compositions" }
4254
- );
4255
- for await (const compositionListItem of componentInstances) {
4256
- const result = {
4257
- id: selectIdentifier3(compositionListItem),
4258
- displayName: selectDisplayName3(compositionListItem),
4259
- providerId: selectIdentifier3(compositionListItem),
4260
- object: prepCompositionForDisk(compositionListItem)
4261
- };
4262
- yield result;
4282
+ yield result;
4283
+ }
4263
4284
  }
4264
4285
  }
4265
4286
  return {
@@ -4267,9 +4288,10 @@ function createComponentInstanceEngineDataSource({
4267
4288
  objects: getObjects(),
4268
4289
  deleteObject: async (providerId) => {
4269
4290
  if (verbose) {
4270
- console.log(`\u{1F41B} delete composition: (id: ${parseCompositionSerializedId(providerId)})`);
4291
+ console.log(`\u{1F41B} delete composition: (id: ${providerId})`);
4271
4292
  }
4272
- await client.removeComposition(parseCompositionSerializedId(providerId));
4293
+ const { id: compositionId, editionId } = parseSerializedId(providerId);
4294
+ await client.removeComposition({ compositionId, editionId });
4273
4295
  },
4274
4296
  writeObject: async (object4) => {
4275
4297
  if (verbose) {
@@ -4334,29 +4356,23 @@ var CompositionPublishModule = {
4334
4356
  console.error(`Specify --all or composition ID(s) to publish.`);
4335
4357
  process.exit(1);
4336
4358
  }
4337
- const compositionIDsArray = ids ? ids.split(",").map((id) => id.trim()) : void 0;
4359
+ const compositionIDs = ids ? toRawEntityIds(splitSerializedIds(ids)) : void 0;
4338
4360
  const fetch2 = nodeFetchProxy(proxy, verbose);
4339
4361
  const client = getCanvasClient({ apiKey, apiHost, fetch: fetch2, projectId });
4340
- const source = createComponentInstanceEngineDataSource({
4362
+ const createDataSource = (state) => createComponentInstanceEngineDataSource({
4341
4363
  client,
4342
- state: "preview",
4343
- compositionIDs: compositionIDsArray,
4344
- onlyCompositions,
4345
- onlyPatterns,
4346
- patternType,
4347
- verbose,
4348
- batchSize: resolvedBatchSize
4349
- });
4350
- const target = createComponentInstanceEngineDataSource({
4351
- client,
4352
- state: "published",
4353
- compositionIDs: compositionIDsArray,
4364
+ state,
4365
+ compositionIDs,
4366
+ // ids name exact entities or editions; resolving editions would publish siblings nobody asked for
4367
+ editions: compositionIDs ? "raw" : "all",
4354
4368
  onlyCompositions,
4355
4369
  onlyPatterns,
4356
4370
  patternType,
4357
4371
  verbose,
4358
4372
  batchSize: resolvedBatchSize
4359
4373
  });
4374
+ const source = createDataSource("preview");
4375
+ const target = createDataSource("published");
4360
4376
  const fileClient = getFileClient({ apiKey, apiHost, fetch: fetch2, projectId });
4361
4377
  await syncEngine({
4362
4378
  source,
@@ -4960,8 +4976,9 @@ var CompositionUnpublishModule = {
4960
4976
  console.log(`Composition ${id} did not have a draft (removing published)`);
4961
4977
  }
4962
4978
  if (!whatIf) {
4979
+ const { id: compositionId, editionId } = parseSerializedId(id);
4963
4980
  actions.push(
4964
- client.removeComposition({ ...parseCompositionSerializedId(id), state: CANVAS_PUBLISHED_STATE2 }).catch((err) => {
4981
+ client.removeComposition({ compositionId, editionId, state: CANVAS_PUBLISHED_STATE2 }).catch((err) => {
4965
4982
  const isNotFound = err instanceof ApiClientError && err.statusCode === 404;
4966
4983
  if (isNotFound) {
4967
4984
  console.warn(
@@ -6262,10 +6279,6 @@ var selectEntryIdentifier = (e) => {
6262
6279
  }
6263
6280
  return baseId;
6264
6281
  };
6265
- function parseEntrySerializedId(providerId) {
6266
- const [entryId, editionId] = providerId.split(" (");
6267
- return { entryId, editionId: editionId?.slice(0, -1) };
6268
- }
6269
6282
  var selectEntryDisplayName = (e) => {
6270
6283
  const name = e.entry._name ?? "Untitled";
6271
6284
  const edition = e.editionId ? e.editionName ?? e.editionId : void 0;
@@ -6280,49 +6293,54 @@ function createEntryEngineDataSource({
6280
6293
  onlyPatterns,
6281
6294
  entryIDs,
6282
6295
  batchSize,
6283
- verbose
6296
+ verbose,
6297
+ editions = "all"
6284
6298
  }) {
6285
6299
  const stateId = convertStateOption(state);
6286
6300
  async function* getObjects() {
6287
- const entries = paginateAsync(
6288
- async (offset, limit2) => {
6289
- try {
6290
- return (await client.getEntries({
6291
- offset,
6292
- limit: limit2,
6293
- entryIDs,
6294
- pattern: onlyEntries ? false : onlyPatterns ? true : void 0,
6295
- skipDataResolution: true,
6296
- skipOverridesResolution: true,
6297
- skipPatternResolution: true,
6298
- state: stateId,
6299
- withComponentIDs: true,
6300
- editions: "all"
6301
- })).entries;
6302
- } catch (error) {
6303
- if (error instanceof ApiClientError2 && error.errorMessage === "Entry not found or not published") {
6304
- return [];
6301
+ const pageSize = batchSize ?? 100;
6302
+ for (const entryIDsChunk of chunkEntityIds(entryIDs)) {
6303
+ const entries = paginateAsync(
6304
+ async (offset, limit2) => {
6305
+ try {
6306
+ return (await client.getEntries({
6307
+ offset,
6308
+ limit: limit2,
6309
+ entryIDs: entryIDsChunk,
6310
+ pattern: onlyEntries ? false : onlyPatterns ? true : void 0,
6311
+ skipDataResolution: true,
6312
+ skipOverridesResolution: true,
6313
+ skipPatternResolution: true,
6314
+ state: stateId,
6315
+ withComponentIDs: true,
6316
+ editions
6317
+ })).entries;
6318
+ } catch (error) {
6319
+ if (error instanceof ApiClientError2 && error.errorMessage === "Entry not found or not published") {
6320
+ return [];
6321
+ }
6322
+ throw error;
6305
6323
  }
6306
- throw error;
6307
- }
6308
- },
6309
- { pageSize: batchSize ?? 100, verbose, entityName: "entries" }
6310
- );
6311
- for await (const e of entries) {
6312
- const result = {
6313
- id: selectEntryIdentifier(e),
6314
- displayName: selectEntryDisplayName(e),
6315
- providerId: selectEntryIdentifier(e),
6316
- object: prepCompositionForDisk(e)
6317
- };
6318
- yield result;
6324
+ },
6325
+ { pageSize, verbose, entityName: "entries" }
6326
+ );
6327
+ for await (const e of entries) {
6328
+ const result = {
6329
+ id: selectEntryIdentifier(e),
6330
+ displayName: selectEntryDisplayName(e),
6331
+ providerId: selectEntryIdentifier(e),
6332
+ object: prepCompositionForDisk(e)
6333
+ };
6334
+ yield result;
6335
+ }
6319
6336
  }
6320
6337
  }
6321
6338
  return {
6322
6339
  name: "Uniform API",
6323
6340
  objects: getObjects(),
6324
6341
  deleteObject: async (providerId) => {
6325
- await client.deleteEntry(parseEntrySerializedId(providerId));
6342
+ const { id: entryId, editionId } = parseSerializedId(providerId);
6343
+ await client.deleteEntry({ entryId, editionId });
6326
6344
  },
6327
6345
  writeObject: async ({ object: object4 }) => {
6328
6346
  await client.upsertEntry({ ...convertEntryToPutEntry(object4), state: stateId });
@@ -6373,23 +6391,21 @@ var EntryPublishModule = {
6373
6391
  console.error(`Specify --all or entry ID(s) to publish.`);
6374
6392
  process.exit(1);
6375
6393
  }
6376
- const entryIDsArray = ids ? ids.split(",").map((id) => id.trim()) : void 0;
6394
+ const entryIDs = ids ? toRawEntityIds(splitSerializedIds(ids)) : void 0;
6377
6395
  const fetch2 = nodeFetchProxy(proxy, verbose);
6378
6396
  const client = getContentClient({ apiKey, apiHost, edgeApiHost, fetch: fetch2, projectId });
6379
- const source = createEntryEngineDataSource({
6380
- client,
6381
- state: "preview",
6382
- entryIDs: entryIDsArray,
6383
- onlyEntries: true,
6384
- batchSize: resolvedBatchSize
6385
- });
6386
- const target = createEntryEngineDataSource({
6397
+ const createDataSource = (state) => createEntryEngineDataSource({
6387
6398
  client,
6388
- state: "published",
6389
- entryIDs: entryIDsArray,
6399
+ state,
6400
+ entryIDs,
6401
+ // ids name exact entities or editions; resolving editions would publish siblings nobody asked for
6402
+ editions: entryIDs ? "raw" : "all",
6390
6403
  onlyEntries: true,
6404
+ verbose,
6391
6405
  batchSize: resolvedBatchSize
6392
6406
  });
6407
+ const source = createDataSource("preview");
6408
+ const target = createDataSource("published");
6393
6409
  const fileClient = getFileClient({ apiKey, apiHost, fetch: fetch2, projectId });
6394
6410
  await syncEngine({
6395
6411
  source,
@@ -6773,8 +6789,9 @@ var EntryUnpublishModule = {
6773
6789
  console.log(`Entry ${id} did not have a draft (removing published)`);
6774
6790
  }
6775
6791
  if (!whatIf) {
6792
+ const { id: entryId, editionId } = parseSerializedId(id);
6776
6793
  actions.push(
6777
- client.deleteEntry({ ...parseEntrySerializedId(id), state: CANVAS_PUBLISHED_STATE3 }).catch((err) => {
6794
+ client.deleteEntry({ entryId, editionId, state: CANVAS_PUBLISHED_STATE3 }).catch((err) => {
6778
6795
  const isNotFound = err instanceof ApiClientError3 && err.statusCode === 404;
6779
6796
  if (isNotFound) {
6780
6797
  console.warn(
@@ -7003,23 +7020,21 @@ var EntryPatternPublishModule = {
7003
7020
  console.error(`Specify --all or entry pattern ID(s) to publish.`);
7004
7021
  process.exit(1);
7005
7022
  }
7006
- const entryIDsArray = ids ? ids.split(",").map((id) => id.trim()) : void 0;
7023
+ const entryIDs = ids ? toRawEntityIds(splitSerializedIds(ids)) : void 0;
7007
7024
  const fetch2 = nodeFetchProxy(proxy, verbose);
7008
7025
  const client = getContentClient({ apiKey, apiHost, edgeApiHost, fetch: fetch2, projectId });
7009
- const source = createEntryEngineDataSource({
7026
+ const createDataSource = (state) => createEntryEngineDataSource({
7010
7027
  client,
7011
- state: "preview",
7012
- entryIDs: entryIDsArray,
7013
- onlyPatterns: true,
7014
- batchSize: resolvedBatchSize
7015
- });
7016
- const target = createEntryEngineDataSource({
7017
- client,
7018
- state: "published",
7019
- entryIDs: entryIDsArray,
7028
+ state,
7029
+ entryIDs,
7030
+ // ids name exact entities or editions; resolving editions would publish siblings nobody asked for
7031
+ editions: entryIDs ? "raw" : "all",
7020
7032
  onlyPatterns: true,
7033
+ verbose,
7021
7034
  batchSize: resolvedBatchSize
7022
7035
  });
7036
+ const source = createDataSource("preview");
7037
+ const target = createDataSource("published");
7023
7038
  const fileClient = getFileClient({ apiKey, apiHost, fetch: fetch2, projectId });
7024
7039
  await syncEngine({
7025
7040
  source,
@@ -7377,8 +7392,9 @@ var EntryPatternUnpublishModule = {
7377
7392
  console.log(`Entry pattern ${id} did not have a draft (removing published)`);
7378
7393
  }
7379
7394
  if (!whatIf) {
7395
+ const { id: entryId, editionId } = parseSerializedId(id);
7380
7396
  actions.push(
7381
- client.deleteEntry({ ...parseEntrySerializedId(id), state: CANVAS_PUBLISHED_STATE4 }).catch((err) => {
7397
+ client.deleteEntry({ entryId, editionId, state: CANVAS_PUBLISHED_STATE4 }).catch((err) => {
7382
7398
  const isNotFound = err instanceof ApiClientError4 && err.statusCode === 404;
7383
7399
  if (isNotFound) {
7384
7400
  console.warn(
@@ -13181,7 +13197,7 @@ var WebhookPullModule = {
13181
13197
  // src/commands/sync/commands/util.ts
13182
13198
  import ora2 from "ora";
13183
13199
  async function spinPromise(action, options) {
13184
- const { successText, failText } = typeof options === "object" ? options : { successText: void 0, failText: void 0 };
13200
+ const { failText } = options;
13185
13201
  const spinner = ora2(options).start();
13186
13202
  const consoleReplay = [];
13187
13203
  const revertLog = patchConsole({
@@ -13219,6 +13235,7 @@ async function spinPromise(action, options) {
13219
13235
  process.on("SIGINT", executeReplayOnSigint);
13220
13236
  try {
13221
13237
  const result = await action;
13238
+ const successText = typeof options.successText === "function" ? options.successText(result) : options.successText;
13222
13239
  const finalStatusText = spinner.text.startsWith(options.text) && spinner.text.length > options.text.length ? spinner.text.slice(options.text.length).trim() : `\u2699\uFE0F compared: ${numPad(0)} changes: 0`;
13223
13240
  const padding = " ".repeat(Math.max(4, 40 - successText.length));
13224
13241
  spinner.succeed(successText + padding + finalStatusText);
@@ -13500,160 +13517,112 @@ var SyncPushModule = {
13500
13517
  "No entities were configured to be pushed. Please make sure you have configuration file and at least one entity type is enabled."
13501
13518
  );
13502
13519
  }
13503
- for (const [entityType, module] of enabledEntities) {
13520
+ const publishScopes = /* @__PURE__ */ new Map();
13521
+ for (const { entityType } of publishableEntities) {
13504
13522
  try {
13505
- await spinPromise(
13506
- module.handler({
13507
- ...otherParams,
13508
- state: 0,
13509
- format: getFormat2(entityType, config2),
13510
- onlyCompositions: entityType === "composition" ? true : void 0,
13511
- onlyPatterns: ["pattern", "componentPattern", "compositionPattern"].includes(entityType) ? true : void 0,
13512
- patternType: entityType === "compositionPattern" ? "composition" : entityType === "componentPattern" ? "component" : void 0,
13513
- mode: getPushMode(entityType, config2),
13514
- directory: getPushFilename(entityType, config2),
13515
- allowEmptySource: config2.allowEmptySource,
13516
- ...isPaginatedSyncEntity(entityType) ? { resolvedBatchSize: getEntityBatchSize(entityType, config2) } : {}
13517
- }),
13518
- {
13519
- text: `${entityType}...`,
13520
- successText: entityType,
13521
- failText(error) {
13522
- return `${entityType}
13523
-
13524
- ${error.stack ?? error.message}`;
13525
- }
13526
- }
13527
- );
13528
- } catch {
13523
+ publishScopes.set(entityType, getPublishScope(entityType, config2));
13524
+ } catch (error) {
13525
+ console.error(error instanceof Error ? error.message : String(error));
13529
13526
  process.exit(1);
13530
13527
  }
13531
13528
  }
13532
- if (config2.entitiesConfig?.componentPattern && config2.entitiesConfig?.componentPattern?.push?.disabled !== true && config2.entitiesConfig?.componentPattern?.publish) {
13533
- try {
13534
- await spinPromise(
13535
- ComponentPatternPublishModule.handler({
13536
- ...otherParams,
13537
- serialization: config2,
13538
- patternType: "component",
13539
- onlyPatterns: true,
13540
- all: true,
13541
- directory: getPushFilename("componentPattern", config2),
13542
- resolvedBatchSize: getEntityBatchSize("componentPattern", config2)
13543
- }),
13544
- {
13545
- text: "publishing component patterns...",
13546
- successText: "published component patterns",
13547
- failText(error) {
13548
- return `publishing component patterns
13549
-
13550
- ${error.stack ?? error.message}`;
13551
- }
13552
- }
13553
- );
13554
- } catch {
13555
- process.exit(1);
13556
- }
13529
+ const pushedIds = /* @__PURE__ */ new Map();
13530
+ for (const [entityType, module] of enabledEntities) {
13531
+ const written = [];
13532
+ const recordWrite = ({ id }) => written.push(id);
13533
+ syncEngineEvents.on("objectWritten", recordWrite);
13534
+ pushedIds.set(entityType, written);
13535
+ await runStep({
13536
+ text: `${entityType}...`,
13537
+ successText: entityType,
13538
+ failLabel: entityType,
13539
+ run: () => module.handler({
13540
+ ...otherParams,
13541
+ state: 0,
13542
+ format: getFormat2(entityType, config2),
13543
+ ...getEntityDiscriminators(entityType),
13544
+ mode: getPushMode(entityType, config2),
13545
+ directory: getPushFilename(entityType, config2),
13546
+ allowEmptySource: config2.allowEmptySource,
13547
+ ...isPaginatedSyncEntity(entityType) ? { resolvedBatchSize: getEntityBatchSize(entityType, config2) } : {}
13548
+ })
13549
+ });
13550
+ syncEngineEvents.off("objectWritten", recordWrite);
13557
13551
  }
13558
- if (config2.entitiesConfig?.compositionPattern && config2.entitiesConfig?.compositionPattern?.push?.disabled !== true && config2.entitiesConfig?.compositionPattern?.publish) {
13559
- try {
13560
- await spinPromise(
13561
- CompositionPatternPublishModule.handler({
13562
- ...otherParams,
13563
- serialization: config2,
13564
- all: true,
13565
- onlyPatterns: true,
13566
- patternType: "composition",
13567
- directory: getPushFilename("compositionPattern", config2),
13568
- resolvedBatchSize: getEntityBatchSize("compositionPattern", config2)
13569
- }),
13570
- {
13571
- text: "publishing composition patterns...",
13572
- successText: "published composition patterns",
13573
- failText(error) {
13574
- return `publishing composition patterns
13575
-
13576
- ${error.stack ?? error.message}`;
13577
- }
13578
- }
13579
- );
13580
- } catch {
13581
- process.exit(1);
13552
+ for (const { entityType, module, label } of publishableEntities) {
13553
+ const entityConfig = config2.entitiesConfig?.[entityType];
13554
+ const scope = publishScopes.get(entityType);
13555
+ if (entityConfig?.disabled === true || entityConfig?.push?.disabled === true || !scope) {
13556
+ continue;
13582
13557
  }
13583
- }
13584
- if (config2.entitiesConfig?.composition && config2.entitiesConfig?.composition?.push?.disabled !== true && config2.entitiesConfig?.composition?.publish) {
13585
- try {
13586
- await spinPromise(
13587
- CompositionPublishModule.handler({
13588
- ...otherParams,
13589
- serialization: config2,
13590
- all: true,
13591
- onlyCompositions: true,
13592
- directory: getPushFilename("composition", config2),
13593
- resolvedBatchSize: getEntityBatchSize("composition", config2)
13594
- }),
13595
- {
13596
- text: "publishing compositions...",
13597
- successText: "published compositions",
13598
- failText(error) {
13599
- return `publishing compositions
13600
-
13601
- ${error.stack ?? error.message}`;
13558
+ const directory = getPushFilename(entityType, config2);
13559
+ await runStep({
13560
+ text: `publishing ${label}...`,
13561
+ // a push that changed nothing is not an error, but it must not read as "published" either
13562
+ successText: (outcome) => outcome.skippedReason ? `skipped ${label}: ${outcome.skippedReason}` : `published ${label}`,
13563
+ failLabel: `publishing ${label}`,
13564
+ run: async () => {
13565
+ let ids;
13566
+ if (scope === "pushed") {
13567
+ const written = pushedIds.get(entityType) ?? [];
13568
+ if (written.length === 0) {
13569
+ return { skippedReason: "nothing was pushed" };
13602
13570
  }
13571
+ ids = written.join(",");
13603
13572
  }
13604
- );
13605
- } catch {
13606
- process.exit(1);
13607
- }
13608
- }
13609
- if (config2.entitiesConfig?.entry && config2.entitiesConfig?.entry?.push?.disabled !== true && config2.entitiesConfig?.entry?.publish) {
13610
- try {
13611
- await spinPromise(
13612
- EntryPublishModule.handler({
13573
+ await module.handler({
13613
13574
  ...otherParams,
13614
13575
  serialization: config2,
13615
- all: true,
13616
- directory: getPushFilename("entry", config2),
13617
- resolvedBatchSize: getEntityBatchSize("entry", config2)
13618
- }),
13619
- {
13620
- text: "publishing entries...",
13621
- successText: "published entries",
13622
- failText(error) {
13623
- return `publishing entries
13624
-
13625
- ${error.stack ?? error.message}`;
13626
- }
13627
- }
13628
- );
13629
- } catch {
13630
- process.exit(1);
13631
- }
13576
+ all: scope === "all",
13577
+ ids,
13578
+ ...getEntityDiscriminators(entityType),
13579
+ directory,
13580
+ resolvedBatchSize: getEntityBatchSize(entityType, config2)
13581
+ });
13582
+ return {};
13583
+ }
13584
+ });
13632
13585
  }
13633
- if (config2.entitiesConfig?.entryPattern && config2.entitiesConfig?.entryPattern?.push?.disabled !== true && config2.entitiesConfig?.entryPattern?.publish) {
13634
- try {
13635
- await spinPromise(
13636
- EntryPatternPublishModule.handler({
13637
- ...otherParams,
13638
- serialization: config2,
13639
- all: true,
13640
- directory: getPushFilename("entryPattern", config2),
13641
- resolvedBatchSize: getEntityBatchSize("entryPattern", config2)
13642
- }),
13643
- {
13644
- text: "publishing entry patterns...",
13645
- successText: "published entry patterns",
13646
- failText(error) {
13647
- return `publishing entry patterns
13586
+ }
13587
+ };
13588
+ var publishableEntities = [
13589
+ {
13590
+ entityType: "componentPattern",
13591
+ module: ComponentPatternPublishModule,
13592
+ label: "component patterns"
13593
+ },
13594
+ {
13595
+ entityType: "compositionPattern",
13596
+ module: CompositionPatternPublishModule,
13597
+ label: "composition patterns"
13598
+ },
13599
+ { entityType: "composition", module: CompositionPublishModule, label: "compositions" },
13600
+ { entityType: "entry", module: EntryPublishModule, label: "entries" },
13601
+ { entityType: "entryPattern", module: EntryPatternPublishModule, label: "entry patterns" }
13602
+ ];
13603
+ var getEntityDiscriminators = (entityType) => ({
13604
+ onlyCompositions: entityType === "composition" ? true : void 0,
13605
+ onlyPatterns: ["pattern", "componentPattern", "compositionPattern"].includes(entityType) ? true : void 0,
13606
+ patternType: entityType === "compositionPattern" ? "composition" : entityType === "componentPattern" ? "component" : void 0
13607
+ });
13608
+ var runStep = async ({
13609
+ text,
13610
+ successText,
13611
+ failLabel,
13612
+ run
13613
+ }) => {
13614
+ try {
13615
+ await spinPromise(run(), {
13616
+ text,
13617
+ successText,
13618
+ failText(error) {
13619
+ return `${failLabel}
13648
13620
 
13649
13621
  ${error.stack ?? error.message}`;
13650
- }
13651
- }
13652
- );
13653
- } catch {
13654
- process.exit(1);
13655
13622
  }
13656
- }
13623
+ });
13624
+ } catch {
13625
+ process.exit(1);
13657
13626
  }
13658
13627
  };
13659
13628
  var getPushMode = (entityType, config2) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uniformdev/cli",
3
- "version": "20.74.6-alpha.2+d9426e9b81",
3
+ "version": "20.74.6-alpha.3+ac26410bba",
4
4
  "description": "Uniform command line interface tool",
5
5
  "license": "SEE LICENSE IN LICENSE.txt",
6
6
  "main": "./cli.js",
@@ -27,13 +27,13 @@
27
27
  "dependencies": {
28
28
  "@inquirer/prompts": "^8.5.2",
29
29
  "@thi.ng/mime": "^2.2.23",
30
- "@uniformdev/assets": "20.74.6-alpha.2+d9426e9b81",
31
- "@uniformdev/canvas": "20.74.6-alpha.2+d9426e9b81",
32
- "@uniformdev/context": "20.74.6-alpha.2+d9426e9b81",
33
- "@uniformdev/files": "20.74.6-alpha.2+d9426e9b81",
34
- "@uniformdev/project-map": "20.74.6-alpha.2+d9426e9b81",
35
- "@uniformdev/redirect": "20.74.6-alpha.2+d9426e9b81",
36
- "@uniformdev/richtext": "20.74.6-alpha.2+d9426e9b81",
30
+ "@uniformdev/assets": "20.74.6-alpha.3+ac26410bba",
31
+ "@uniformdev/canvas": "20.74.6-alpha.3+ac26410bba",
32
+ "@uniformdev/context": "20.74.6-alpha.3+ac26410bba",
33
+ "@uniformdev/files": "20.74.6-alpha.3+ac26410bba",
34
+ "@uniformdev/project-map": "20.74.6-alpha.3+ac26410bba",
35
+ "@uniformdev/redirect": "20.74.6-alpha.3+ac26410bba",
36
+ "@uniformdev/richtext": "20.74.6-alpha.3+ac26410bba",
37
37
  "call-bind": "^1.0.2",
38
38
  "colorette": "2.0.20",
39
39
  "cosmiconfig": "9.0.2",
@@ -79,5 +79,5 @@
79
79
  "publishConfig": {
80
80
  "access": "public"
81
81
  },
82
- "gitHead": "d9426e9b81a6943318d903c723f23f3c0cbb17ad"
82
+ "gitHead": "ac26410bba86c828620eb1876847bbaffd639036"
83
83
  }