prismic-ts-codegen 0.1.3-alpha.0 → 0.1.5

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/bin/cli.mjs CHANGED
@@ -15,10 +15,6 @@ import * as prismicCT from '@prismicio/custom-types-client';
15
15
  import _jiti from 'jiti';
16
16
 
17
17
  const BLANK_LINE_IDENTIFIER = "// ___BLANK_LINE_TO_BE_REPLACED___";
18
- const NON_EDITABLE_FILE_HEADER = stripIndent`
19
- // Code generated by prismic-ts-codegen. DO NOT EDIT.
20
- ${BLANK_LINE_IDENTIFIER}
21
- `;
22
18
  const CUSTOM_TYPES_DOCUMENTATION_URL = "https://prismic.io/docs/core-concepts/custom-types";
23
19
  const SHARED_SLICES_DOCUMENTATION_URL = "https://prismic.io/docs/core-concepts/reusing-slices";
24
20
  const FIELD_DOCUMENTATION_URLS = {
@@ -209,10 +205,18 @@ const pascalCase = (input) => pascalCase$1(input, {
209
205
  transform: pascalCaseTransformMerge
210
206
  });
211
207
 
212
- const buildSharedSliceInterfaceName = (config) => {
208
+ const buildSharedSliceInterfaceNamePart = (config) => {
213
209
  return pascalCase(`${config.id} Slice`);
214
210
  };
215
211
 
212
+ const buildTypeName = (...parts) => {
213
+ let name = pascalCase(parts.filter(Boolean).join(" "));
214
+ if (/^[0-9]/.test(name) ? "_" : "") {
215
+ name = `_${name}`;
216
+ }
217
+ return name;
218
+ };
219
+
216
220
  const addInterfacePropertyForField = (config) => {
217
221
  switch (config.model.type) {
218
222
  case "UID": {
@@ -262,12 +266,16 @@ const addInterfacePropertyForField = (config) => {
262
266
  if (config.fieldConfigs.embed?.providerTypes) {
263
267
  for (const providerType in config.fieldConfigs.embed?.providerTypes) {
264
268
  const configuredProviderType = config.fieldConfigs.embed?.providerTypes[providerType];
265
- providerTypes.push(`({ provider_name: "${providerType}" } & ${configuredProviderType})`);
269
+ providerTypes.push(
270
+ `({ provider_name: "${providerType}" } & ${configuredProviderType})`
271
+ );
266
272
  }
267
273
  }
268
274
  config.interface.addProperty({
269
275
  name: config.id,
270
- type: providerTypes.length > 0 ? `prismicT.EmbedField<prismicT.AnyOEmbed & prismicT.OEmbedExtra & (${providerTypes.join(" | ")})>` : "prismicT.EmbedField",
276
+ type: providerTypes.length > 0 ? `prismicT.EmbedField<prismicT.AnyOEmbed & prismicT.OEmbedExtra & (${providerTypes.join(
277
+ " | "
278
+ )})>` : "prismicT.EmbedField",
271
279
  docs: buildFieldDocs({
272
280
  id: config.id,
273
281
  model: config.model,
@@ -471,7 +479,13 @@ const addInterfacePropertyForField = (config) => {
471
479
  }
472
480
  case "Group": {
473
481
  const itemInterface = config.sourceFile.addInterface({
474
- name: pascalCase(`${config.path[0].id} Document Data ${config.id} Item`),
482
+ name: buildTypeName(
483
+ config.path[0].id,
484
+ "Document",
485
+ "Data",
486
+ config.id,
487
+ "Item"
488
+ ),
475
489
  docs: [
476
490
  {
477
491
  description: (writer) => {
@@ -523,12 +537,22 @@ const addInterfacePropertyForField = (config) => {
523
537
  for (const choiceId in config.model.config.choices) {
524
538
  const choice = config.model.config.choices[choiceId];
525
539
  if (choice.type === CustomTypeModelSliceType.SharedSlice) {
526
- choiceInterfaceNames.push(buildSharedSliceInterfaceName({ id: choiceId }));
540
+ choiceInterfaceNames.push(
541
+ buildSharedSliceInterfaceNamePart({ id: choiceId })
542
+ );
527
543
  } else if (choice.type === CustomTypeModelSliceType.Slice) {
528
544
  let primaryInterface;
529
545
  if (choice["non-repeat"] && Object.keys(choice["non-repeat"]).length > 0) {
530
546
  primaryInterface = config.sourceFile.addInterface({
531
- name: pascalCase(`${config.path[0].id} Document Data ${config.id} ${choiceId} Slice Primary`),
547
+ name: buildTypeName(
548
+ config.path[0].id,
549
+ "Document",
550
+ "Data",
551
+ config.id,
552
+ choiceId,
553
+ "Slice",
554
+ "Primary"
555
+ ),
532
556
  docs: [
533
557
  {
534
558
  description: (writer) => {
@@ -549,7 +573,9 @@ const addInterfacePropertyForField = (config) => {
549
573
  }
550
574
  ]
551
575
  });
552
- writer.writeLine(`Primary content in ${humanReadablePath}`);
576
+ writer.writeLine(
577
+ `Primary content in ${humanReadablePath}`
578
+ );
553
579
  }
554
580
  }
555
581
  ]
@@ -579,7 +605,15 @@ const addInterfacePropertyForField = (config) => {
579
605
  let itemInterface;
580
606
  if (choice.repeat && Object.keys(choice.repeat).length > 0) {
581
607
  itemInterface = config.sourceFile.addInterface({
582
- name: pascalCase(`${config.path[0].id} Document Data ${config.id} ${choiceId} Slice Item`),
608
+ name: buildTypeName(
609
+ config.path[0].id,
610
+ "Document",
611
+ "Data",
612
+ config.id,
613
+ choiceId,
614
+ "Slice",
615
+ "Item"
616
+ ),
583
617
  docs: [
584
618
  {
585
619
  description: (writer) => {
@@ -629,7 +663,14 @@ const addInterfacePropertyForField = (config) => {
629
663
  });
630
664
  }
631
665
  const sliceType = config.sourceFile.addTypeAlias({
632
- name: pascalCase(`${config.path[0].id} Document Data ${config.id} ${choiceId} Slice`),
666
+ name: buildTypeName(
667
+ config.path[0].id,
668
+ "Document",
669
+ "Data",
670
+ config.id,
671
+ choiceId,
672
+ "Slice"
673
+ ),
633
674
  type: `prismicT.Slice<"${choiceId}", ${primaryInterface ? `Simplify<${primaryInterface.getName()}>` : "Record<string, never>"}, ${itemInterface ? `Simplify<${itemInterface.getName()}>` : "never"}>`,
634
675
  isExported: true
635
676
  });
@@ -638,7 +679,13 @@ const addInterfacePropertyForField = (config) => {
638
679
  }
639
680
  }
640
681
  const slicesType = config.sourceFile.addTypeAlias({
641
- name: pascalCase(`${config.path[0].id} Document Data ${config.id} Slice`),
682
+ name: buildTypeName(
683
+ config.path[0].id,
684
+ "Document",
685
+ "Data",
686
+ config.id,
687
+ "Slice"
688
+ ),
642
689
  type: choiceInterfaceNames.length > 0 ? choiceInterfaceNames.join(" | ") : "never",
643
690
  docs: [
644
691
  {
@@ -709,7 +756,7 @@ const addTypeAliasForCustomType = ({
709
756
  let dataInterface;
710
757
  if (hasDataFields) {
711
758
  dataInterface = sourceFile.addInterface({
712
- name: pascalCase(`${model.id} Document Data`),
759
+ name: buildTypeName(model.id, "Document", "Data"),
713
760
  docs: [
714
761
  {
715
762
  description: `Content for ${model.label} documents`
@@ -734,7 +781,7 @@ const addTypeAliasForCustomType = ({
734
781
  }
735
782
  } else {
736
783
  dataInterface = sourceFile.addTypeAlias({
737
- name: pascalCase(`${model.id} Document Data`),
784
+ name: buildTypeName(model.id, "Document", "Data"),
738
785
  type: `Record<string, never>`,
739
786
  docs: [
740
787
  {
@@ -744,7 +791,7 @@ const addTypeAliasForCustomType = ({
744
791
  });
745
792
  }
746
793
  return sourceFile.addTypeAlias({
747
- name: pascalCase(`${model.id} Document`),
794
+ name: buildTypeName(model.id, "Document"),
748
795
  typeParameters: [
749
796
  {
750
797
  name: "Lang",
@@ -760,7 +807,9 @@ const addTypeAliasForCustomType = ({
760
807
  writer.blankLine();
761
808
  writer.writeLine(`- **API ID**: \`${model.id}\``);
762
809
  writer.writeLine(`- **Repeatable**: \`${model.repeatable}\``);
763
- writer.writeLine(`- **Documentation**: ${CUSTOM_TYPES_DOCUMENTATION_URL}`);
810
+ writer.writeLine(
811
+ `- **Documentation**: ${CUSTOM_TYPES_DOCUMENTATION_URL}`
812
+ );
764
813
  },
765
814
  tags: [
766
815
  {
@@ -780,7 +829,11 @@ const addTypeAliasForSharedSlice = (config) => {
780
829
  let primaryInterface;
781
830
  if (variation.primary && Object.keys(variation.primary).length > 0) {
782
831
  primaryInterface = config.sourceFile.addInterface({
783
- name: pascalCase(`${buildSharedSliceInterfaceName({ id: config.model.id })} ${variation.id} Primary`),
832
+ name: buildTypeName(
833
+ buildSharedSliceInterfaceNamePart({ id: config.model.id }),
834
+ variation.id,
835
+ "Primary"
836
+ ),
784
837
  docs: [
785
838
  {
786
839
  description: (writer) => {
@@ -821,7 +874,11 @@ const addTypeAliasForSharedSlice = (config) => {
821
874
  let itemInterface;
822
875
  if (variation.items && Object.keys(variation.items).length > 0) {
823
876
  itemInterface = config.sourceFile.addInterface({
824
- name: pascalCase(`${buildSharedSliceInterfaceName({ id: config.model.id })} ${variation.id} Item`),
877
+ name: buildTypeName(
878
+ buildSharedSliceInterfaceNamePart({ id: config.model.id }),
879
+ variation.id,
880
+ "Item"
881
+ ),
825
882
  docs: [
826
883
  {
827
884
  description: (writer) => {
@@ -861,18 +918,23 @@ const addTypeAliasForSharedSlice = (config) => {
861
918
  });
862
919
  }
863
920
  const variationType = config.sourceFile.addTypeAlias({
864
- name: pascalCase(`${buildSharedSliceInterfaceName({
865
- id: config.model.id
866
- })} ${variation.id}`),
921
+ name: buildTypeName(
922
+ buildSharedSliceInterfaceNamePart({ id: config.model.id }),
923
+ variation.id
924
+ ),
867
925
  type: `prismicT.SharedSliceVariation<"${variation.id}", ${primaryInterface ? `Simplify<${primaryInterface.getName()}>` : "Record<string, never>"}, ${itemInterface ? `Simplify<${itemInterface.getName()}>` : "never"}>`,
868
926
  docs: [
869
927
  {
870
928
  description: (writer) => {
871
- writer.writeLine(`${variation.name} variation for ${config.model.name} Slice`);
929
+ writer.writeLine(
930
+ `${variation.name} variation for ${config.model.name} Slice`
931
+ );
872
932
  writer.blankLine();
873
933
  writer.writeLine(`- **API ID**: \`${variation.id}\``);
874
934
  writer.writeLine(`- **Description**: \`${variation.description}\``);
875
- writer.writeLine(`- **Documentation**: ${SHARED_SLICES_DOCUMENTATION_URL}`);
935
+ writer.writeLine(
936
+ `- **Documentation**: ${SHARED_SLICES_DOCUMENTATION_URL}`
937
+ );
876
938
  }
877
939
  }
878
940
  ],
@@ -881,7 +943,7 @@ const addTypeAliasForSharedSlice = (config) => {
881
943
  variationTypeNames.push(variationType.getName());
882
944
  }
883
945
  const variationsType = config.sourceFile.addTypeAlias({
884
- name: pascalCase(`${config.model.id} Slice Variation`),
946
+ name: buildTypeName(config.model.id, "Slice", "Variation"),
885
947
  type: variationTypeNames.length > 0 ? variationTypeNames.join(" | ") : "never",
886
948
  docs: [
887
949
  {
@@ -900,9 +962,9 @@ const addTypeAliasForSharedSlice = (config) => {
900
962
  ]
901
963
  });
902
964
  return config.sourceFile.addTypeAlias({
903
- name: pascalCase(buildSharedSliceInterfaceName({
904
- id: config.model.id
905
- })),
965
+ name: buildTypeName(
966
+ buildSharedSliceInterfaceNamePart({ id: config.model.id })
967
+ ),
906
968
  type: `prismicT.SharedSlice<"${config.model.id}", ${variationsType.getName()}>`,
907
969
  docs: [
908
970
  {
@@ -910,8 +972,12 @@ const addTypeAliasForSharedSlice = (config) => {
910
972
  writer.writeLine(`${config.model.name} Shared Slice`);
911
973
  writer.blankLine();
912
974
  writer.writeLine(`- **API ID**: \`${config.model.id}\``);
913
- writer.writeLine(`- **Description**: \`${config.model.description}\``);
914
- writer.writeLine(`- **Documentation**: ${SHARED_SLICES_DOCUMENTATION_URL}`);
975
+ writer.writeLine(
976
+ `- **Description**: \`${config.model.description}\``
977
+ );
978
+ writer.writeLine(
979
+ `- **Documentation**: ${SHARED_SLICES_DOCUMENTATION_URL}`
980
+ );
915
981
  }
916
982
  }
917
983
  ],
@@ -932,8 +998,7 @@ const generateTypes = (config = {}) => {
932
998
  sourceFile.addImportDeclaration({
933
999
  moduleSpecifier: "@prismicio/types",
934
1000
  namespaceImport: "prismicT",
935
- isTypeOnly: true,
936
- leadingTrivia: NON_EDITABLE_FILE_HEADER
1001
+ isTypeOnly: true
937
1002
  });
938
1003
  sourceFile.addStatements(BLANK_LINE_IDENTIFIER);
939
1004
  const simplifyTypeAlias = sourceFile.addTypeAlias({
@@ -957,7 +1022,9 @@ const generateTypes = (config = {}) => {
957
1022
  if (config.customTypeModels.length > 0) {
958
1023
  sourceFile.addTypeAlias({
959
1024
  name: "AllDocumentTypes",
960
- type: config.customTypeModels.map((customTypeModel) => pascalCase(`${customTypeModel.id} Document`)).join(" | "),
1025
+ type: config.customTypeModels.map(
1026
+ (customTypeModel) => buildTypeName(customTypeModel.id, "Document")
1027
+ ).join(" | "),
961
1028
  isExported: true
962
1029
  });
963
1030
  }
@@ -1039,17 +1106,26 @@ const configSchema = Joi.object({
1039
1106
  includeCreateClientInterface: Joi.boolean(),
1040
1107
  includeContentNamespace: Joi.boolean()
1041
1108
  }),
1042
- locales: Joi.alternatives(Joi.array().items(Joi.string().required()), Joi.object({
1043
- ids: Joi.array().items(Joi.string().required()),
1044
- fetchFromRepository: Joi.boolean()
1045
- })),
1046
- models: Joi.alternatives(Joi.array().items(Joi.string()), Joi.object({
1047
- files: Joi.array().items(Joi.string()),
1048
- fetchFromRepository: Joi.boolean()
1049
- })),
1109
+ locales: Joi.alternatives(
1110
+ Joi.array().items(Joi.string().required()),
1111
+ Joi.object({
1112
+ ids: Joi.array().items(Joi.string().required()),
1113
+ fetchFromRepository: Joi.boolean()
1114
+ })
1115
+ ),
1116
+ models: Joi.alternatives(
1117
+ Joi.array().items(Joi.string()),
1118
+ Joi.object({
1119
+ files: Joi.array().items(Joi.string()),
1120
+ fetchFromRepository: Joi.boolean()
1121
+ })
1122
+ ),
1050
1123
  fields: Joi.object({
1051
1124
  embed: Joi.object({
1052
- providerTypes: Joi.object().pattern(Joi.string(), Joi.string().required())
1125
+ providerTypes: Joi.object().pattern(
1126
+ Joi.string(),
1127
+ Joi.string().required()
1128
+ )
1053
1129
  }),
1054
1130
  integrationFields: Joi.object({
1055
1131
  catalogTypes: Joi.object().pattern(Joi.string(), Joi.string().required())
@@ -1128,6 +1204,10 @@ const loadModels = async (config) => {
1128
1204
  };
1129
1205
 
1130
1206
  const jiti = _jiti(process.cwd());
1207
+ const loadModuleWithJiti = (id) => {
1208
+ const mod = jiti(id);
1209
+ return "default" in mod ? mod.default : mod;
1210
+ };
1131
1211
  const DEFAULT_CONFIG_PATHS = [
1132
1212
  "prismicCodegen.config.ts",
1133
1213
  "prismicCodegen.config.js"
@@ -1135,22 +1215,24 @@ const DEFAULT_CONFIG_PATHS = [
1135
1215
  const loadConfig = (config) => {
1136
1216
  if (config.path) {
1137
1217
  if (existsSync(config.path)) {
1138
- return jiti(config.path);
1218
+ return loadModuleWithJiti(resolve(config.path));
1139
1219
  } else {
1140
1220
  throw new Error(`Config file does not exist: ${config.path}`);
1141
1221
  }
1142
1222
  } else {
1143
1223
  for (const configPath of DEFAULT_CONFIG_PATHS) {
1144
1224
  if (existsSync(configPath)) {
1145
- const mod = jiti(resolve(configPath));
1146
- return "default" in mod ? mod.default : mod;
1225
+ return loadModuleWithJiti(resolve(configPath));
1147
1226
  }
1148
1227
  }
1149
1228
  }
1150
1229
  return {};
1151
1230
  };
1152
1231
 
1153
- const cli = meow(`
1232
+ const NON_EDITABLE_FILE_HEADER = "// Code generated by prismic-ts-codegen. DO NOT EDIT.";
1233
+
1234
+ const cli = meow(
1235
+ `
1154
1236
  Usage:
1155
1237
  prismic-ts-codegen [options...]
1156
1238
  prismic-ts-codegen init [options...]
@@ -1160,16 +1242,18 @@ const cli = meow(`
1160
1242
 
1161
1243
  Options:
1162
1244
  -c, --config <path> Path to a prismic-ts-codegen configuration file.
1163
- `, {
1164
- importMeta: import.meta,
1165
- flags: {
1166
- config: {
1167
- type: "string",
1168
- alias: "c",
1169
- isRequired: false
1245
+ `,
1246
+ {
1247
+ importMeta: import.meta,
1248
+ flags: {
1249
+ config: {
1250
+ type: "string",
1251
+ alias: "c",
1252
+ isRequired: false
1253
+ }
1170
1254
  }
1171
1255
  }
1172
- });
1256
+ );
1173
1257
  const main = async () => {
1174
1258
  if (cli.input[0] === "init") {
1175
1259
  const configPath = cli.flags.config || "prismicCodegen.config.ts";
@@ -1221,6 +1305,11 @@ Created prismic-ts-codegen config file: ${configPath}`);
1221
1305
  fetchFromRepository: config.locales && "fetchFromRepository" in config.locales && config.locales.fetchFromRepository
1222
1306
  });
1223
1307
  const hasCustomTypeModels = customTypeModels.length > 0;
1308
+ if (config.clientIntegration?.includeCreateClientInterface && !hasCustomTypeModels) {
1309
+ console.info(
1310
+ "[INFO]: prismic-ts-codegen was configured to automatically integrate with `@prismicio/client`, but the integration was not generated because no Custom Type models were found. Automatic integration requires at least one Custom Type model."
1311
+ );
1312
+ }
1224
1313
  const types = generateTypes({
1225
1314
  customTypeModels,
1226
1315
  sharedSliceModels,
@@ -1231,11 +1320,11 @@ Created prismic-ts-codegen config file: ${configPath}`);
1231
1320
  includeContentNamespace: config.clientIntegration?.includeContentNamespace ?? true
1232
1321
  }
1233
1322
  });
1234
- if (config.clientIntegration?.includeCreateClientInterface && !hasCustomTypeModels) {
1235
- console.info("[INFO]: prismic-ts-codegen was configured to automatically integrate with `@prismicio/client`, but the integration was not generated because no Custom Type models were found. Automatic integration requires at least one Custom Type model.");
1236
- }
1323
+ const fileContents = `${NON_EDITABLE_FILE_HEADER}
1324
+
1325
+ ${types}`;
1237
1326
  if (config.output) {
1238
- writeFileSync(resolve(config.output), types);
1327
+ writeFileSync(resolve(config.output), fileContents);
1239
1328
  console.info(`
1240
1329
  Generated types in: ${config.output}`);
1241
1330
  } else {