@messagevisor/catalog 0.1.0 → 0.3.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.
@@ -164,6 +164,26 @@ function git(root: string, args: string[]) {
164
164
  });
165
165
  }
166
166
 
167
+ function gitCommit(root: string, message: string) {
168
+ childProcess.execFileSync(
169
+ "git",
170
+ [
171
+ "-C",
172
+ root,
173
+ "-c",
174
+ "user.name=Catalog Tester",
175
+ "-c",
176
+ "user.email=catalog@example.com",
177
+ "commit",
178
+ "-m",
179
+ message,
180
+ ],
181
+ {
182
+ stdio: ["ignore", "ignore", "ignore"],
183
+ },
184
+ );
185
+ }
186
+
167
187
  describe("catalog", function () {
168
188
  const roots: string[] = [];
169
189
  let consoleLogSpy: jest.SpyInstance;
@@ -371,6 +391,89 @@ describe("catalog", function () {
371
391
  expect(history.entries).toEqual([]);
372
392
  });
373
393
 
394
+ it("streams Git history into project, entity, and last-modified catalog data", async function () {
395
+ const root = await createProject();
396
+ roots.push(root);
397
+ git(root, ["init"]);
398
+ git(root, ["add", "."]);
399
+ gitCommit(root, "initial catalog fixtures");
400
+
401
+ await writeFile(
402
+ root,
403
+ "tests/messages/common/welcome.spec.yml",
404
+ "cases:\n - description: Test only\n",
405
+ );
406
+ git(root, ["add", "."]);
407
+ gitCommit(root, "test-only change");
408
+
409
+ await writeFile(
410
+ root,
411
+ "messages/common/welcome.yml",
412
+ ["description: Welcome updated", "translations:", " en: Welcome back", ""].join("\n"),
413
+ );
414
+ await writeFile(
415
+ root,
416
+ "messages/common/with space.yml",
417
+ "description: With space\ntranslations:\n en: Spaced\n",
418
+ );
419
+ git(root, ["add", "."]);
420
+ gitCommit(root, "message updates");
421
+
422
+ const projectConfig = getProjectConfig(root);
423
+ const datasource = new Datasource(projectConfig, root);
424
+
425
+ await catalogApi.exportCatalog(root, projectConfig, datasource, {
426
+ outDir: "catalog-out",
427
+ copyAssets: false,
428
+ });
429
+
430
+ const projectHistory = await readJson<any>(
431
+ root,
432
+ "catalog-out/data/project/history/page-1.json",
433
+ );
434
+ const messageHistory = await readJson<any>(
435
+ root,
436
+ "catalog-out/data/root/history/message/common.welcome/page-1.json",
437
+ );
438
+ const spacedMessageHistory = await readJson<any>(
439
+ root,
440
+ "catalog-out/data/root/history/message/common.with%20space/page-1.json",
441
+ );
442
+ const index = await readJson<any>(root, "catalog-out/data/root/index.json");
443
+ const message = await readJson<any>(
444
+ root,
445
+ "catalog-out/data/root/entities/message/common.welcome.json",
446
+ );
447
+
448
+ expect(projectHistory.entries).toHaveLength(2);
449
+ expect(projectHistory.entries[0].entities).toEqual(
450
+ expect.arrayContaining([
451
+ { type: "message", key: "common.welcome" },
452
+ { type: "message", key: "common.with space" },
453
+ ]),
454
+ );
455
+ expect(projectHistory.entries).not.toEqual(
456
+ expect.arrayContaining([
457
+ expect.objectContaining({
458
+ entities: expect.arrayContaining([{ type: "test", key: "common.welcome" }]),
459
+ }),
460
+ ]),
461
+ );
462
+ expect(messageHistory.entries).toHaveLength(2);
463
+ expect(spacedMessageHistory.entries[0].entities).toEqual(
464
+ expect.arrayContaining([{ type: "message", key: "common.with space" }]),
465
+ );
466
+ expect(message.lastModified).toMatchObject({
467
+ author: "Catalog Tester",
468
+ commit: projectHistory.entries[0].commit,
469
+ });
470
+ expect(
471
+ index.entities.message.find((entry: any) => entry.key === "common.welcome").lastModified,
472
+ ).toMatchObject({
473
+ commit: projectHistory.entries[0].commit,
474
+ });
475
+ });
476
+
374
477
  it("exports branch-aware repository links and hash router mode when requested", async function () {
375
478
  const root = await createProject();
376
479
  roots.push(root);
@@ -605,6 +708,125 @@ describe("catalog", function () {
605
708
  });
606
709
  });
607
710
 
711
+ it("groups streamed Git history by set", async function () {
712
+ const root = await fs.promises.mkdtemp(path.join(os.tmpdir(), "messagevisor-catalog-"));
713
+ roots.push(root);
714
+
715
+ await writeFile(root, "messagevisor.config.js", "module.exports = { sets: true };\n");
716
+ await writeFile(root, "sets/storefront/locales/en.yml", "description: English\n");
717
+ await writeFile(
718
+ root,
719
+ "sets/storefront/messages/common/welcome.yml",
720
+ "description: Storefront\ntranslations:\n en: Storefront\n",
721
+ );
722
+ await writeFile(root, "sets/admin/locales/en.yml", "description: English\n");
723
+ await writeFile(
724
+ root,
725
+ "sets/admin/messages/common/welcome.yml",
726
+ "description: Admin\ntranslations:\n en: Admin\n",
727
+ );
728
+ await writeFile(
729
+ root,
730
+ "sets/admin/tests/messages/common/welcome.spec.yml",
731
+ "cases:\n - description: Test only\n",
732
+ );
733
+
734
+ git(root, ["init"]);
735
+ git(root, ["add", "."]);
736
+ gitCommit(root, "initial sets");
737
+
738
+ const projectConfig = getProjectConfig(root);
739
+ const datasource = new Datasource(projectConfig, root);
740
+
741
+ await catalogApi.exportCatalog(root, projectConfig, datasource, {
742
+ outDir: "catalog-out",
743
+ copyAssets: false,
744
+ });
745
+
746
+ const projectHistory = await readJson<any>(
747
+ root,
748
+ "catalog-out/data/project/history/page-1.json",
749
+ );
750
+ const storefrontHistory = await readJson<any>(
751
+ root,
752
+ "catalog-out/data/sets/storefront/history/page-1.json",
753
+ );
754
+ const adminHistory = await readJson<any>(
755
+ root,
756
+ "catalog-out/data/sets/admin/history/page-1.json",
757
+ );
758
+ const adminMessageHistory = await readJson<any>(
759
+ root,
760
+ "catalog-out/data/sets/admin/history/message/common.welcome/page-1.json",
761
+ );
762
+
763
+ expect(projectHistory.entries).toHaveLength(1);
764
+ expect(storefrontHistory.entries).toHaveLength(1);
765
+ expect(adminHistory.entries).toHaveLength(1);
766
+ expect(adminMessageHistory.entries[0].entities).toEqual(
767
+ expect.arrayContaining([{ type: "message", key: "common.welcome", set: "admin" }]),
768
+ );
769
+ expect(adminHistory.entries[0].entities).not.toEqual(
770
+ expect.arrayContaining([{ type: "test", key: "common.welcome", set: "admin" }]),
771
+ );
772
+ });
773
+
774
+ it("paginates many streamed Git history entries without loading one raw output blob", async function () {
775
+ const root = await fs.promises.mkdtemp(path.join(os.tmpdir(), "messagevisor-catalog-"));
776
+ roots.push(root);
777
+ await writeFile(root, "messagevisor.config.js", "module.exports = {};\n");
778
+ await writeFile(root, "locales/en.yml", "description: English\n");
779
+ await writeFile(
780
+ root,
781
+ "messages/common/welcome.yml",
782
+ "description: Welcome\ntranslations:\n en: Welcome\n",
783
+ );
784
+ await writeFile(
785
+ root,
786
+ "messages/common/with space.yml",
787
+ "description: With space\ntranslations:\n en: Spaced\n",
788
+ );
789
+
790
+ git(root, ["init"]);
791
+ git(root, ["add", "."]);
792
+ gitCommit(root, "initial catalog project");
793
+
794
+ for (let index = 0; index < 60; index++) {
795
+ await writeFile(
796
+ root,
797
+ "messages/common/welcome.yml",
798
+ `description: Welcome ${index}\ntranslations:\n en: Welcome ${index}\n`,
799
+ );
800
+ git(root, ["add", "."]);
801
+ gitCommit(root, `message update ${index}`);
802
+ }
803
+
804
+ const projectConfig = getProjectConfig(root);
805
+ const datasource = new Datasource(projectConfig, root);
806
+
807
+ await catalogApi.exportCatalog(root, projectConfig, datasource, {
808
+ outDir: "catalog-out",
809
+ copyAssets: false,
810
+ });
811
+
812
+ const projectHistory = await readJson<any>(
813
+ root,
814
+ "catalog-out/data/project/history/page-1.json",
815
+ );
816
+ const messageHistory = await readJson<any>(
817
+ root,
818
+ "catalog-out/data/root/history/message/common.welcome/page-1.json",
819
+ );
820
+
821
+ expect(projectHistory.totalPages).toBe(2);
822
+ expect(projectHistory.entries).toHaveLength(50);
823
+ expect(projectHistory.entries[0].entities).toEqual([
824
+ { type: "message", key: "common.welcome" },
825
+ ]);
826
+ expect(messageHistory.totalPages).toBe(2);
827
+ expect(messageHistory.entries).toHaveLength(50);
828
+ });
829
+
608
830
  it("uses root-relative asset paths for browser-router refresh safety", async function () {
609
831
  const viteConfigSource = await fs.promises.readFile(
610
832
  path.join(__dirname, "../../vite.config.ts"),