@tinacms/graphql 1.0.5 → 1.1.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.
@@ -147,6 +147,7 @@ export declare const NAMER: {
147
147
  dataFilterTypeName: (namespace: string[]) => string;
148
148
  dataMutationTypeNameOn: (namespace: string[]) => string;
149
149
  dataMutationTypeName: (namespace: string[]) => string;
150
+ dataMutationUpdateTypeName: (namespace: string[]) => string;
150
151
  updateName: (namespace: string[]) => string;
151
152
  createName: (namespace: string[]) => string;
152
153
  documentQueryName: () => string;
@@ -251,6 +251,7 @@ export declare class Builder {
251
251
  private _buildFieldFilter;
252
252
  private _buildFieldMutation;
253
253
  private _buildReferenceMutation;
254
+ private _buildUpdateDocumentMutationParams;
254
255
  private _buildObjectOrUnionData;
255
256
  private _connectionFilterBuilder;
256
257
  private _connectionFieldBuilder;
@@ -21,4 +21,10 @@ export interface Bridge {
21
21
  */
22
22
  supportsBuilding(): boolean;
23
23
  putConfig(filepath: string, data: string): Promise<void>;
24
+ /**
25
+ * Optionally, the bridge can perform
26
+ * operations in a separate path.
27
+ */
28
+ outputPath?: string;
29
+ addOutputPath?(outputPath: string): void;
24
30
  }
@@ -23,6 +23,7 @@ declare type IndexStatusCallback = (event: IndexStatusEvent) => Promise<void>;
23
23
  declare type CreateDatabase = {
24
24
  bridge: Bridge;
25
25
  store: Store;
26
+ tinaDirectory?: string;
26
27
  indexStatusCallback?: IndexStatusCallback;
27
28
  };
28
29
  export declare const createDatabase: (config: CreateDatabase) => Promise<Database>;
@@ -41,12 +42,14 @@ export declare class Database {
41
42
  config: CreateDatabase;
42
43
  bridge: Bridge;
43
44
  store: Store;
45
+ tinaDirectory: string;
44
46
  indexStatusCallback: IndexStatusCallback | undefined;
45
47
  private tinaSchema;
46
48
  private collectionIndexDefinitions;
47
49
  private _lookup;
48
50
  constructor(config: CreateDatabase);
49
51
  private collectionForPath;
52
+ private getGeneratedFolder;
50
53
  private partitionPathsByCollection;
51
54
  get: <T extends object>(filepath: string) => Promise<T>;
52
55
  addPendingDocument: (filepath: string, data: {
@@ -93,9 +96,10 @@ export declare class Database {
93
96
  tinaSchema: TinaSchema;
94
97
  }) => Promise<void>;
95
98
  private indexStatusCallbackWrapper;
96
- indexContent: ({ graphQLSchema, tinaSchema, }: {
99
+ indexContent: ({ graphQLSchema, tinaSchema, lookup: lookupFromLockFile, }: {
97
100
  graphQLSchema: DocumentNode;
98
101
  tinaSchema: TinaSchema;
102
+ lookup?: object;
99
103
  }) => Promise<void>;
100
104
  deleteContentByPaths: (documentPaths: string[]) => Promise<void>;
101
105
  indexContentByPaths: (documentPaths: string[]) => Promise<void>;
package/dist/index.js CHANGED
@@ -1101,6 +1101,9 @@ var NAMER = {
1101
1101
  dataMutationTypeName: (namespace) => {
1102
1102
  return generateNamespacedFieldName(namespace, "Mutation");
1103
1103
  },
1104
+ dataMutationUpdateTypeName: (namespace) => {
1105
+ return generateNamespacedFieldName(namespace, "UpdateMutation");
1106
+ },
1104
1107
  updateName: (namespace) => {
1105
1108
  return `update${generateNamespacedFieldName(namespace)}`;
1106
1109
  },
@@ -1509,7 +1512,7 @@ var Builder = class {
1509
1512
  astBuilder.InputValueDefinition({
1510
1513
  name: "params",
1511
1514
  required: true,
1512
- type: await this._buildReferenceMutation({
1515
+ type: await this._buildUpdateDocumentMutationParams({
1513
1516
  namespace: ["document"],
1514
1517
  collections: collections.map((collection) => collection.name)
1515
1518
  })
@@ -2110,6 +2113,22 @@ var Builder = class {
2110
2113
  })
2111
2114
  });
2112
2115
  };
2116
+ this._buildUpdateDocumentMutationParams = async (field) => {
2117
+ const fields = await sequential(this.tinaSchema.getCollectionsByName(field.collections), async (collection) => {
2118
+ return astBuilder.InputValueDefinition({
2119
+ name: collection.name,
2120
+ type: NAMER.dataMutationTypeName([collection.name])
2121
+ });
2122
+ });
2123
+ fields.push(astBuilder.InputValueDefinition({
2124
+ name: "relativePath",
2125
+ type: astBuilder.TYPES.String
2126
+ }));
2127
+ return astBuilder.InputObjectTypeDefinition({
2128
+ name: NAMER.dataMutationUpdateTypeName(field.namespace),
2129
+ fields
2130
+ });
2131
+ };
2113
2132
  this._buildObjectOrUnionData = async (collectableTemplate, extraFields = [], extraInterfaces = [], collection) => {
2114
2133
  if (collectableTemplate.type === "union") {
2115
2134
  const name2 = NAMER.dataTypeName(collectableTemplate.namespace);
@@ -2376,7 +2395,7 @@ var validationCollectionsPathAndMatch = (collections) => {
2376
2395
  return typeof (x == null ? void 0 : x.match) === "undefined";
2377
2396
  }).map((x) => x.path);
2378
2397
  if (noMatchCollections.length !== new Set(noMatchCollections).size) {
2379
- throw new Error("path must be unique when no `match` is provided");
2398
+ throw new Error("path must be unique");
2380
2399
  }
2381
2400
  const hasMatchAndPath = collections.filter((x) => {
2382
2401
  return typeof x.path !== "undefined" && typeof x.match !== "undefined";
@@ -2454,7 +2473,7 @@ var validateField = async (field) => {
2454
2473
 
2455
2474
  // package.json
2456
2475
  var name = "@tinacms/graphql";
2457
- var version = "1.0.5";
2476
+ var version = "1.1.0";
2458
2477
  var main = "dist/index.js";
2459
2478
  var typings = "dist/index.d.ts";
2460
2479
  var files = [
@@ -3144,7 +3163,8 @@ var Resolver = class {
3144
3163
  isCreation,
3145
3164
  isDeletion,
3146
3165
  isAddPendingDocument,
3147
- isCollectionSpecific
3166
+ isCollectionSpecific,
3167
+ isUpdateName
3148
3168
  }) => {
3149
3169
  let collectionLookup = collectionName || void 0;
3150
3170
  if (!collectionLookup && isCollectionSpecific === false) {
@@ -3170,14 +3190,28 @@ var Resolver = class {
3170
3190
  isAddPendingDocument
3171
3191
  });
3172
3192
  }
3173
- if (isDeletion) {
3174
- if (!alreadyExists) {
3193
+ if (!alreadyExists) {
3194
+ if (isDeletion) {
3175
3195
  throw new Error(`Unable to delete document, ${realPath} does not exist`);
3176
3196
  }
3197
+ if (isUpdateName) {
3198
+ throw new Error(`Unable to update document, ${realPath} does not exist`);
3199
+ }
3200
+ }
3201
+ if (isDeletion) {
3177
3202
  const doc = await this.getDocument(realPath);
3178
3203
  await this.deleteDocument(realPath);
3179
3204
  return doc;
3180
3205
  }
3206
+ if (isUpdateName) {
3207
+ assertShape(args, (yup3) => yup3.object({ params: yup3.object().required() }));
3208
+ assertShape(args == null ? void 0 : args.params, (yup3) => yup3.object({ relativePath: yup3.string().required() }));
3209
+ const doc = await this.getDocument(realPath);
3210
+ const newRealPath = import_path2.default.join(collection == null ? void 0 : collection.path, args.params.relativePath);
3211
+ await this.database.put(newRealPath, doc._rawData, collection.name);
3212
+ await this.deleteDocument(realPath);
3213
+ return this.getDocument(newRealPath);
3214
+ }
3181
3215
  if (alreadyExists === false) {
3182
3216
  throw new Error(`Unable to update document, ${realPath} does not exist`);
3183
3217
  }
@@ -3272,6 +3306,7 @@ var Resolver = class {
3272
3306
  Object.entries(fieldParams).forEach(([fieldName, fieldValue]) => {
3273
3307
  if (Array.isArray(fieldValue)) {
3274
3308
  if (fieldValue.length === 0) {
3309
+ accum[fieldName] = [];
3275
3310
  return;
3276
3311
  }
3277
3312
  }
@@ -3483,6 +3518,7 @@ var resolve = async ({
3483
3518
  }
3484
3519
  },
3485
3520
  fieldResolver: async (source = {}, _args = {}, _context, info) => {
3521
+ var _a2;
3486
3522
  try {
3487
3523
  const args = JSON.parse(JSON.stringify(_args));
3488
3524
  const returnType = (0, import_graphql4.getNamedType)(info.returnType).toString();
@@ -3496,8 +3532,8 @@ var resolve = async ({
3496
3532
  if (info.fieldName === "collections") {
3497
3533
  const collectionNode2 = info.fieldNodes.find((x) => x.name.value === "collections");
3498
3534
  const hasDocuments2 = collectionNode2.selectionSet.selections.find((x) => {
3499
- var _a2;
3500
- return ((_a2 = x == null ? void 0 : x.name) == null ? void 0 : _a2.value) === "documents";
3535
+ var _a3;
3536
+ return ((_a3 = x == null ? void 0 : x.name) == null ? void 0 : _a3.value) === "documents";
3501
3537
  });
3502
3538
  return tinaSchema.getCollections().map((collection) => {
3503
3539
  return resolver.resolveCollection(args, collection.name, Boolean(hasDocuments2));
@@ -3505,8 +3541,8 @@ var resolve = async ({
3505
3541
  }
3506
3542
  const collectionNode = info.fieldNodes.find((x) => x.name.value === "collection");
3507
3543
  const hasDocuments = collectionNode.selectionSet.selections.find((x) => {
3508
- var _a2;
3509
- return ((_a2 = x == null ? void 0 : x.name) == null ? void 0 : _a2.value) === "documents";
3544
+ var _a3;
3545
+ return ((_a3 = x == null ? void 0 : x.name) == null ? void 0 : _a3.value) === "documents";
3510
3546
  });
3511
3547
  return resolver.resolveCollection(args, args.collection, Boolean(hasDocuments));
3512
3548
  }
@@ -3555,6 +3591,7 @@ var resolve = async ({
3555
3591
  isMutation,
3556
3592
  isCreation,
3557
3593
  isDeletion: info.fieldName === "deleteDocument",
3594
+ isUpdateName: Boolean((_a2 = args == null ? void 0 : args.params) == null ? void 0 : _a2.relativePath),
3558
3595
  isAddPendingDocument: false,
3559
3596
  isCollectionSpecific: false
3560
3597
  });
@@ -3747,7 +3784,6 @@ var createDatabase = async (config) => {
3747
3784
  }));
3748
3785
  };
3749
3786
  var SYSTEM_FILES = ["_schema", "_graphql", "_lookup"];
3750
- var GENERATED_FOLDER = import_path3.default.join(".tina", "__generated__");
3751
3787
  var defaultStatusCallback = () => Promise.resolve();
3752
3788
  var Database = class {
3753
3789
  constructor(config) {
@@ -3757,6 +3793,7 @@ var Database = class {
3757
3793
  const collection = tinaSchema.getCollectionByFullPath(filepath);
3758
3794
  return collection;
3759
3795
  };
3796
+ this.getGeneratedFolder = () => import_path3.default.join(this.tinaDirectory, "__generated__");
3760
3797
  this.get = async (filepath) => {
3761
3798
  if (SYSTEM_FILES.includes(filepath)) {
3762
3799
  throw new Error(`Unexpected get for config file ${filepath}`);
@@ -3899,7 +3936,7 @@ var Database = class {
3899
3936
  return stringifiedFile;
3900
3937
  };
3901
3938
  this.getLookup = async (returnType) => {
3902
- const lookupPath = import_path3.default.join(GENERATED_FOLDER, `_lookup.json`);
3939
+ const lookupPath = import_path3.default.join(this.getGeneratedFolder(), `_lookup.json`);
3903
3940
  if (!this._lookup) {
3904
3941
  const _lookup = await this.store.get(normalizePath(lookupPath));
3905
3942
  this._lookup = _lookup;
@@ -3907,16 +3944,16 @@ var Database = class {
3907
3944
  return this._lookup[returnType];
3908
3945
  };
3909
3946
  this.getGraphQLSchema = async () => {
3910
- const graphqlPath = import_path3.default.join(GENERATED_FOLDER, `_graphql.json`);
3947
+ const graphqlPath = import_path3.default.join(this.getGeneratedFolder(), `_graphql.json`);
3911
3948
  return this.store.get(normalizePath(graphqlPath));
3912
3949
  };
3913
3950
  this.getGraphQLSchemaFromBridge = async () => {
3914
- const graphqlPath = import_path3.default.join(GENERATED_FOLDER, `_graphql.json`);
3951
+ const graphqlPath = import_path3.default.join(this.getGeneratedFolder(), `_graphql.json`);
3915
3952
  const _graphql = await this.bridge.get(normalizePath(graphqlPath));
3916
3953
  return JSON.parse(_graphql);
3917
3954
  };
3918
3955
  this.getTinaSchema = async () => {
3919
- const schemaPath = import_path3.default.join(GENERATED_FOLDER, `_schema.json`);
3956
+ const schemaPath = import_path3.default.join(this.getGeneratedFolder(), `_schema.json`);
3920
3957
  return this.store.get(normalizePath(schemaPath));
3921
3958
  };
3922
3959
  this.getSchema = async () => {
@@ -4025,7 +4062,7 @@ var Database = class {
4025
4062
  cursor: (0, import_datalayer2.btoa)(edge.cursor)
4026
4063
  };
4027
4064
  } catch (error) {
4028
- if (error instanceof Error && !edge.path.includes(".tina/__generated__/_graphql.json")) {
4065
+ if (error instanceof Error && (!edge.path.includes(".tina/__generated__/_graphql.json") || !edge.path.includes("tina/__generated__/_graphql.json"))) {
4029
4066
  throw new TinaQueryError({
4030
4067
  originalError: error,
4031
4068
  file: edge.path,
@@ -4050,21 +4087,22 @@ var Database = class {
4050
4087
  tinaSchema
4051
4088
  }) => {
4052
4089
  if (this.bridge.supportsBuilding()) {
4053
- await this.bridge.putConfig(normalizePath(import_path3.default.join(GENERATED_FOLDER, `_graphql.json`)), JSON.stringify(graphQLSchema));
4054
- await this.bridge.putConfig(normalizePath(import_path3.default.join(GENERATED_FOLDER, `_schema.json`)), JSON.stringify(tinaSchema.schema));
4090
+ await this.bridge.putConfig(normalizePath(import_path3.default.join(this.getGeneratedFolder(), `_graphql.json`)), JSON.stringify(graphQLSchema));
4091
+ await this.bridge.putConfig(normalizePath(import_path3.default.join(this.getGeneratedFolder(), `_schema.json`)), JSON.stringify(tinaSchema.schema));
4055
4092
  }
4056
4093
  };
4057
4094
  this.indexContent = async ({
4058
4095
  graphQLSchema,
4059
- tinaSchema
4096
+ tinaSchema,
4097
+ lookup: lookupFromLockFile
4060
4098
  }) => {
4061
4099
  await this.indexStatusCallbackWrapper(async () => {
4062
- const lookup = JSON.parse(await this.bridge.get(normalizePath(import_path3.default.join(GENERATED_FOLDER, "_lookup.json"))));
4100
+ const lookup = lookupFromLockFile || JSON.parse(await this.bridge.get(normalizePath(import_path3.default.join(this.getGeneratedFolder(), "_lookup.json"))));
4063
4101
  if (this.store.supportsSeeding()) {
4064
4102
  await this.store.clear();
4065
- await this.store.seed(normalizePath(import_path3.default.join(GENERATED_FOLDER, "_graphql.json")), graphQLSchema);
4066
- await this.store.seed(normalizePath(import_path3.default.join(GENERATED_FOLDER, "_schema.json")), tinaSchema.schema);
4067
- await this.store.seed(normalizePath(import_path3.default.join(GENERATED_FOLDER, "_lookup.json")), lookup);
4103
+ await this.store.seed(normalizePath(import_path3.default.join(this.getGeneratedFolder(), "_graphql.json")), graphQLSchema);
4104
+ await this.store.seed(normalizePath(import_path3.default.join(this.getGeneratedFolder(), "_schema.json")), tinaSchema.schema);
4105
+ await this.store.seed(normalizePath(import_path3.default.join(this.getGeneratedFolder(), "_lookup.json")), lookup);
4068
4106
  await this._indexAllContent();
4069
4107
  } else {
4070
4108
  if (this.store.supportsIndexing()) {
@@ -4112,7 +4150,7 @@ var Database = class {
4112
4150
  });
4113
4151
  };
4114
4152
  this.addToLookupMap = async (lookup) => {
4115
- const lookupPath = import_path3.default.join(GENERATED_FOLDER, `_lookup.json`);
4153
+ const lookupPath = import_path3.default.join(this.getGeneratedFolder(), `_lookup.json`);
4116
4154
  let lookupMap;
4117
4155
  try {
4118
4156
  lookupMap = JSON.parse(await this.bridge.get(normalizePath(lookupPath)));
@@ -4124,6 +4162,7 @@ var Database = class {
4124
4162
  });
4125
4163
  await this.bridge.putConfig(normalizePath(lookupPath), JSON.stringify(updatedLookup));
4126
4164
  };
4165
+ this.tinaDirectory = config.tinaDirectory || ".tina";
4127
4166
  this.bridge = config.bridge;
4128
4167
  this.store = config.store;
4129
4168
  this.indexStatusCallback = config.indexStatusCallback || defaultStatusCallback;
@@ -168,7 +168,7 @@ export declare class Resolver {
168
168
  __typename: string;
169
169
  id: string;
170
170
  }>;
171
- resolveDocument: ({ args, collection: collectionName, isMutation, isCreation, isDeletion, isAddPendingDocument, isCollectionSpecific, }: {
171
+ resolveDocument: ({ args, collection: collectionName, isMutation, isCreation, isDeletion, isAddPendingDocument, isCollectionSpecific, isUpdateName, }: {
172
172
  args: unknown;
173
173
  collection?: string;
174
174
  isMutation: boolean;
@@ -176,6 +176,7 @@ export declare class Resolver {
176
176
  isDeletion?: boolean;
177
177
  isAddPendingDocument?: boolean;
178
178
  isCollectionSpecific?: boolean;
179
+ isUpdateName?: boolean;
179
180
  }) => Promise<{
180
181
  _sys: {
181
182
  title: any;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tinacms/graphql",
3
- "version": "1.0.5",
3
+ "version": "1.1.0",
4
4
  "main": "dist/index.js",
5
5
  "typings": "dist/index.d.ts",
6
6
  "files": [
@@ -20,9 +20,9 @@
20
20
  "dependencies": {
21
21
  "@graphql-tools/relay-operation-optimizer": "^6.4.1",
22
22
  "@iarna/toml": "^2.2.5",
23
- "@tinacms/datalayer": "1.0.0",
24
- "@tinacms/mdx": "1.1.0",
25
- "@tinacms/schema-tools": "1.2.0",
23
+ "@tinacms/datalayer": "1.0.1",
24
+ "@tinacms/mdx": "1.1.1",
25
+ "@tinacms/schema-tools": "1.2.1",
26
26
  "body-parser": "^1.19.0",
27
27
  "cors": "^2.8.5",
28
28
  "dataloader": "^2.0.0",
@@ -72,8 +72,8 @@
72
72
  "directory": "packages/tina-graphql"
73
73
  },
74
74
  "devDependencies": {
75
- "@tinacms/datalayer": "1.0.0",
76
- "@tinacms/schema-tools": "1.2.0",
75
+ "@tinacms/datalayer": "1.0.1",
76
+ "@tinacms/schema-tools": "1.2.1",
77
77
  "@tinacms/scripts": "1.0.1",
78
78
  "@types/cors": "^2.8.7",
79
79
  "@types/estree": "^0.0.50",