@tinacms/graphql 1.6.1 → 1.6.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.
@@ -1,7 +1,7 @@
1
1
  /**
2
2
 
3
3
  */
4
- import { type FieldDefinitionNode, type ScalarTypeDefinitionNode, type InputValueDefinitionNode, type ObjectTypeDefinitionNode, type InterfaceTypeDefinitionNode, type NamedTypeNode, type UnionTypeDefinitionNode, type TypeDefinitionNode, type DirectiveNode, type EnumTypeDefinitionNode, type InputObjectTypeDefinitionNode, type DocumentNode, type FragmentDefinitionNode, type SelectionNode, type FieldNode, type InlineFragmentNode, type OperationDefinitionNode } from 'graphql';
4
+ import { type FieldDefinitionNode, type ScalarTypeDefinitionNode, type InputValueDefinitionNode, type ObjectTypeDefinitionNode, type InterfaceTypeDefinitionNode, type NamedTypeNode, type UnionTypeDefinitionNode, type TypeDefinitionNode, type DirectiveNode, type EnumTypeDefinitionNode, type InputObjectTypeDefinitionNode, type DocumentNode, type FragmentDefinitionNode, type SelectionNode, type FieldNode, type InlineFragmentNode, type OperationDefinitionNode, type DefinitionNode } from 'graphql';
5
5
  export declare const SysFieldDefinition: {
6
6
  kind: "Field";
7
7
  name: {
@@ -153,7 +153,7 @@ export declare const astBuilder: {
153
153
  }) => DocumentNode;
154
154
  };
155
155
  type scalarNames = 'string' | 'boolean' | 'datetime' | 'image' | 'text' | 'number';
156
- export declare const extractInlineTypes: (item: TypeDefinitionNode | TypeDefinitionNode[]) => any;
156
+ export declare const extractInlineTypes: (item: DefinitionNode | DefinitionNode[]) => DefinitionNode[];
157
157
  export declare function walk(maybeNode: TypeDefinitionNode, visited?: WeakSet<WeakKey>): IterableIterator<TypeDefinitionNode>;
158
158
  export declare const NAMER: {
159
159
  dataFilterTypeNameOn: (namespace: string[]) => string;
package/dist/build.d.ts CHANGED
@@ -1,16 +1,14 @@
1
1
  /**
2
2
 
3
3
  */
4
+ import { type DocumentNode } from 'graphql';
4
5
  import type { TinaSchema, Config } from '@tinacms/schema-tools';
5
6
  export declare const buildDotTinaFiles: ({ config, flags, buildSDK, }: {
6
7
  config: Config;
7
8
  flags?: string[];
8
9
  buildSDK?: boolean;
9
10
  }) => Promise<{
10
- graphQLSchema: {
11
- kind: "Document";
12
- definitions: any;
13
- };
11
+ graphQLSchema: DocumentNode;
14
12
  tinaSchema: TinaSchema;
15
13
  lookup: Record<string, import("./database").LookupMapType>;
16
14
  fragDoc: string;
package/dist/index.d.ts CHANGED
@@ -16,10 +16,7 @@ export { createSchema } from './schema/createSchema';
16
16
  export { buildDotTinaFiles };
17
17
  export type DummyType = unknown;
18
18
  export declare const buildSchema: (config: Config, flags?: string[]) => Promise<{
19
- graphQLSchema: {
20
- kind: "Document";
21
- definitions: any;
22
- };
19
+ graphQLSchema: import("graphql").DocumentNode;
23
20
  tinaSchema: import("@tinacms/schema-tools").TinaSchema;
24
21
  lookup: Record<string, import("./database").LookupMapType>;
25
22
  fragDoc: string;
package/dist/index.js CHANGED
@@ -66,7 +66,7 @@ module.exports = __toCommonJS(index_exports);
66
66
 
67
67
  // src/build.ts
68
68
  var import_graphql2 = require("graphql");
69
- var import_lodash3 = __toESM(require("lodash.uniqby"));
69
+ var import_es_toolkit3 = require("es-toolkit");
70
70
 
71
71
  // src/util.ts
72
72
  var yup = __toESM(require("yup"));
@@ -122,7 +122,7 @@ var flattenDeep = (arr) => arr.flatMap(
122
122
  );
123
123
 
124
124
  // src/ast-builder/index.ts
125
- var import_lodash = __toESM(require("lodash.uniqby"));
125
+ var import_es_toolkit = require("es-toolkit");
126
126
  var SysFieldDefinition = {
127
127
  kind: "Field",
128
128
  name: {
@@ -1037,12 +1037,13 @@ var astBuilder = {
1037
1037
  };
1038
1038
  },
1039
1039
  toGraphQLAst: (ast) => {
1040
- const definitions = (0, import_lodash.default)(
1040
+ const definitions = (0, import_es_toolkit.uniqBy)(
1041
1041
  [
1042
1042
  ...extractInlineTypes(ast.query),
1043
1043
  ...extractInlineTypes(ast.globalTemplates),
1044
1044
  ...ast.definitions
1045
1045
  ],
1046
+ // @ts-ignore - all nodes have a name property in practice
1046
1047
  (field) => field.name.value
1047
1048
  );
1048
1049
  return {
@@ -1065,7 +1066,7 @@ var extractInlineTypes = (item) => {
1065
1066
  const accumulator = [item];
1066
1067
  for (const node of walk(item)) {
1067
1068
  if (node.kind === "UnionTypeDefinition") {
1068
- node.types = (0, import_lodash.default)(node.types, (type) => type.name.value);
1069
+ node.types = (0, import_es_toolkit.uniqBy)(node.types, (type) => type.name.value);
1069
1070
  }
1070
1071
  if (node.kind === "NamedType") {
1071
1072
  if (typeof node.name.value !== "string") {
@@ -2777,7 +2778,7 @@ var Builder = class {
2777
2778
  this._buildDataField = async (field) => {
2778
2779
  const listWarningMsg = `
2779
2780
  WARNING: The user interface for ${field.type} does not support \`list: true\`
2780
- Visit https://tina.io/docs/errors/ui-not-supported/ for more information
2781
+ Visit https://tina.io/docs/r/content-fields/#list-fields/ for more information
2781
2782
 
2782
2783
  `;
2783
2784
  switch (field.type) {
@@ -2930,8 +2931,8 @@ var import_schema_tools3 = require("@tinacms/schema-tools");
2930
2931
 
2931
2932
  // src/schema/validate.ts
2932
2933
  var import_schema_tools = require("@tinacms/schema-tools");
2933
- var import_lodash2 = __toESM(require("lodash.clonedeep"));
2934
2934
  var yup2 = __toESM(require("yup"));
2935
+ var import_es_toolkit2 = require("es-toolkit");
2935
2936
  var import_schema_tools2 = require("@tinacms/schema-tools");
2936
2937
  var FIELD_TYPES = [
2937
2938
  "string",
@@ -2946,7 +2947,7 @@ var FIELD_TYPES = [
2946
2947
  ];
2947
2948
  var validateSchema = async (schema) => {
2948
2949
  const schema2 = (0, import_schema_tools.addNamespaceToSchema)(
2949
- (0, import_lodash2.default)(schema)
2950
+ (0, import_es_toolkit2.cloneDeep)(schema)
2950
2951
  );
2951
2952
  const collections = await sequential(
2952
2953
  schema2.collections,
@@ -3083,7 +3084,7 @@ var validateField = async (field) => {
3083
3084
  // package.json
3084
3085
  var package_default = {
3085
3086
  name: "@tinacms/graphql",
3086
- version: "1.6.1",
3087
+ version: "1.6.3",
3087
3088
  main: "dist/index.js",
3088
3089
  module: "dist/index.mjs",
3089
3090
  typings: "dist/index.d.ts",
@@ -3118,6 +3119,7 @@ var package_default = {
3118
3119
  "@tinacms/schema-tools": "workspace:*",
3119
3120
  "abstract-level": "catalog:",
3120
3121
  "date-fns": "^2.30.0",
3122
+ "es-toolkit": "^1.42.0",
3121
3123
  "fast-glob": "catalog:",
3122
3124
  "fs-extra": "catalog:",
3123
3125
  "glob-parent": "catalog:",
@@ -3127,15 +3129,12 @@ var package_default = {
3127
3129
  "js-sha1": "catalog:",
3128
3130
  "js-yaml": "^3.14.1",
3129
3131
  "jsonpath-plus": "catalog:",
3130
- "lodash.clonedeep": "catalog:",
3131
- "lodash.set": "catalog:",
3132
- "lodash.uniqby": "catalog:",
3133
3132
  "many-level": "catalog:",
3134
3133
  micromatch: "catalog:",
3135
3134
  "normalize-path": "catalog:",
3136
3135
  "readable-stream": "catalog:",
3137
3136
  scmp: "catalog:",
3138
- yup: "^0.32.11"
3137
+ yup: "^1.6.1"
3139
3138
  },
3140
3139
  publishConfig: {
3141
3140
  registry: "https://registry.npmjs.org"
@@ -3152,21 +3151,18 @@ var package_default = {
3152
3151
  "@types/express": "catalog:",
3153
3152
  "@types/fs-extra": "^9.0.13",
3154
3153
  "@types/js-yaml": "^3.12.10",
3155
- "@types/lodash.camelcase": "catalog:",
3156
- "@types/lodash.upperfirst": "catalog:",
3157
3154
  "@types/lru-cache": "catalog:",
3158
3155
  "@types/mdast": "catalog:",
3159
3156
  "@types/micromatch": "catalog:",
3160
3157
  "@types/node": "^22.13.1",
3161
3158
  "@types/normalize-path": "catalog:",
3162
3159
  "@types/ws": "catalog:",
3163
- "@types/yup": "^0.29.14",
3164
3160
  "jest-file-snapshot": "^0.5.0",
3165
3161
  "memory-level": "catalog:",
3166
3162
  typescript: "^5.7.3",
3167
3163
  vite: "^4.5.9",
3168
3164
  vitest: "^0.32.4",
3169
- zod: "^3.24.2"
3165
+ zod: "catalog:"
3170
3166
  }
3171
3167
  };
3172
3168
 
@@ -3236,9 +3232,9 @@ var _buildFragments = async (builder, tinaSchema) => {
3236
3232
  });
3237
3233
  const fragDoc = {
3238
3234
  kind: "Document",
3239
- definitions: (0, import_lodash3.default)(
3240
- // @ts-ignore
3235
+ definitions: (0, import_es_toolkit3.uniqBy)(
3241
3236
  extractInlineTypes(fragmentDefinitionsFields),
3237
+ // @ts-ignore - all nodes returned by extractInlineTypes have a name property
3242
3238
  (node) => node.name.value
3243
3239
  )
3244
3240
  };
@@ -3269,9 +3265,9 @@ var _buildQueries = async (builder, tinaSchema) => {
3269
3265
  });
3270
3266
  const queryDoc = {
3271
3267
  kind: "Document",
3272
- definitions: (0, import_lodash3.default)(
3273
- // @ts-ignore
3268
+ definitions: (0, import_es_toolkit3.uniqBy)(
3274
3269
  extractInlineTypes(operationsDefinitions),
3270
+ // @ts-ignore - all nodes returned by extractInlineTypes have a name property
3275
3271
  (node) => node.name.value
3276
3272
  )
3277
3273
  };
@@ -3358,14 +3354,15 @@ var _buildSchema = async (builder, tinaSchema) => {
3358
3354
  fields: mutationTypeDefinitionFields
3359
3355
  })
3360
3356
  );
3361
- return {
3357
+ const schema = {
3362
3358
  kind: "Document",
3363
- definitions: (0, import_lodash3.default)(
3364
- // @ts-ignore
3359
+ definitions: (0, import_es_toolkit3.uniqBy)(
3365
3360
  extractInlineTypes(definitions),
3361
+ // @ts-ignore - all nodes returned by extractInlineTypes have a name property
3366
3362
  (node) => node.name.value
3367
3363
  )
3368
3364
  };
3365
+ return schema;
3369
3366
  };
3370
3367
 
3371
3368
  // src/resolve.ts
@@ -4447,7 +4444,6 @@ var TinaFetchError = class extends Error {
4447
4444
  super(message);
4448
4445
  this.name = "TinaFetchError";
4449
4446
  this.collection = args.collection;
4450
- this.stack = args.stack;
4451
4447
  this.file = args.file;
4452
4448
  this.originalError = args.originalError;
4453
4449
  }
@@ -4829,8 +4825,7 @@ var transformDocumentIntoPayload = async (fullPath, rawData, tinaSchema, config,
4829
4825
  originalError: e,
4830
4826
  collection: collection.name,
4831
4827
  includeAuditMessage: !isAudit,
4832
- file: relativePath,
4833
- stack: e.stack
4828
+ file: relativePath
4834
4829
  });
4835
4830
  }
4836
4831
  const titleField = template.fields.find((x) => {
@@ -5741,8 +5736,129 @@ var resolveDateInput = (value) => {
5741
5736
  return date;
5742
5737
  };
5743
5738
 
5744
- // src/resolve.ts
5745
- var import_lodash4 = __toESM(require("lodash.set"));
5739
+ // src/resolver/auth-fields.ts
5740
+ var import_compat = require("es-toolkit/compat");
5741
+ async function getUserDocumentContext(tinaSchema, resolver) {
5742
+ const collection = tinaSchema.getCollections().find((c) => c.isAuthCollection);
5743
+ if (!collection) {
5744
+ throw new Error("Auth collection not found");
5745
+ }
5746
+ const userFields = mapUserFields(collection, ["_rawData"]);
5747
+ if (!userFields.length) {
5748
+ throw new Error(`No user field found in collection ${collection.name}`);
5749
+ }
5750
+ if (userFields.length > 1) {
5751
+ throw new Error(
5752
+ `Multiple user fields found in collection ${collection.name}`
5753
+ );
5754
+ }
5755
+ const userField = userFields[0];
5756
+ const realPath = `${collection.path}/index.json`;
5757
+ const userDoc = await resolver.getDocument(realPath);
5758
+ const users = get(userDoc, userField.path);
5759
+ if (!users) {
5760
+ throw new Error("No users found");
5761
+ }
5762
+ return { collection, userField, users, userDoc, realPath };
5763
+ }
5764
+ function findUserInCollection(users, userField, userSub) {
5765
+ const { idFieldName } = userField;
5766
+ if (!idFieldName) {
5767
+ throw new Error("No uid field found on user field");
5768
+ }
5769
+ return users.find((u) => u[idFieldName] === userSub) || null;
5770
+ }
5771
+ async function handleAuthenticate({
5772
+ tinaSchema,
5773
+ resolver,
5774
+ sub,
5775
+ password,
5776
+ ctxUser
5777
+ }) {
5778
+ const userSub = sub || ctxUser?.sub;
5779
+ const { userField, users } = await getUserDocumentContext(
5780
+ tinaSchema,
5781
+ resolver
5782
+ );
5783
+ const user = findUserInCollection(users, userField, userSub);
5784
+ if (!user) {
5785
+ return null;
5786
+ }
5787
+ const { passwordFieldName } = userField;
5788
+ const saltedHash = get(user, [passwordFieldName || "", "value"]);
5789
+ if (!saltedHash) {
5790
+ throw new Error("No password field found on user field");
5791
+ }
5792
+ const matches = await checkPasswordHash({
5793
+ saltedHash,
5794
+ password
5795
+ });
5796
+ return matches ? user : null;
5797
+ }
5798
+ async function handleAuthorize({
5799
+ tinaSchema,
5800
+ resolver,
5801
+ sub,
5802
+ ctxUser
5803
+ }) {
5804
+ const userSub = sub || ctxUser?.sub;
5805
+ const { userField, users } = await getUserDocumentContext(
5806
+ tinaSchema,
5807
+ resolver
5808
+ );
5809
+ const user = findUserInCollection(users, userField, userSub);
5810
+ return user ? user : null;
5811
+ }
5812
+ async function handleUpdatePassword({
5813
+ tinaSchema,
5814
+ resolver,
5815
+ password,
5816
+ ctxUser
5817
+ }) {
5818
+ if (!ctxUser?.sub) {
5819
+ throw new Error("Not authorized");
5820
+ }
5821
+ if (!password) {
5822
+ throw new Error("No password provided");
5823
+ }
5824
+ const { collection, userField, users, realPath } = await getUserDocumentContext(tinaSchema, resolver);
5825
+ const { idFieldName, passwordFieldName } = userField;
5826
+ const user = users.find((u) => u[idFieldName] === ctxUser.sub);
5827
+ if (!user) {
5828
+ throw new Error("Not authorized");
5829
+ }
5830
+ user[passwordFieldName] = {
5831
+ value: password,
5832
+ passwordChangeRequired: false
5833
+ };
5834
+ const params = {};
5835
+ (0, import_compat.set)(
5836
+ params,
5837
+ userField.path.slice(1),
5838
+ // remove _rawData from users path
5839
+ users.map((u) => {
5840
+ if (user[idFieldName] === u[idFieldName]) {
5841
+ return user;
5842
+ }
5843
+ return {
5844
+ // don't overwrite other users' passwords
5845
+ ...u,
5846
+ [passwordFieldName]: {
5847
+ ...u[passwordFieldName],
5848
+ value: ""
5849
+ }
5850
+ };
5851
+ })
5852
+ );
5853
+ await resolver.updateResolveDocument({
5854
+ collection,
5855
+ args: { params },
5856
+ realPath,
5857
+ isCollectionSpecific: true,
5858
+ isAddPendingDocument: false
5859
+ });
5860
+ return true;
5861
+ }
5746
5862
 
5747
5863
  // src/error.ts
5748
5864
  var import_graphql4 = require("graphql");
@@ -5852,119 +5968,33 @@ var resolve = async ({
5852
5968
  );
5853
5969
  }
5854
5970
  }
5855
- if (info.fieldName === "authenticate" || info.fieldName === "authorize") {
5856
- const sub = args.sub || ctxUser?.sub;
5857
- const collection = tinaSchema.getCollections().find((c) => c.isAuthCollection);
5858
- if (!collection) {
5859
- throw new Error("Auth collection not found");
5860
- }
5861
- const userFields = mapUserFields(collection, ["_rawData"]);
5862
- if (!userFields.length) {
5863
- throw new Error(
5864
- `No user field found in collection ${collection.name}`
5865
- );
5866
- }
5867
- if (userFields.length > 1) {
5868
- throw new Error(
5869
- `Multiple user fields found in collection ${collection.name}`
5870
- );
5871
- }
5872
- const userField = userFields[0];
5873
- const realPath = `${collection.path}/index.json`;
5874
- const userDoc = await resolver.getDocument(realPath);
5875
- const users = get(userDoc, userField.path);
5876
- if (!users) {
5877
- throw new Error("No users found");
5878
- }
5879
- const { idFieldName, passwordFieldName } = userField;
5880
- if (!idFieldName) {
5881
- throw new Error("No uid field found on user field");
5882
- }
5883
- const user = users.find((u) => u[idFieldName] === sub);
5884
- if (!user) {
5885
- return null;
5886
- }
5887
- if (info.fieldName === "authenticate") {
5888
- const saltedHash = get(user, [passwordFieldName || "", "value"]);
5889
- if (!saltedHash) {
5890
- throw new Error("No password field found on user field");
5891
- }
5892
- const matches = await checkPasswordHash({
5893
- saltedHash,
5894
- password: args.password
5895
- });
5896
- if (matches) {
5897
- return user;
5898
- }
5899
- return null;
5900
- }
5901
- return user;
5971
+ if (info.fieldName === "authenticate") {
5972
+ return handleAuthenticate({
5973
+ tinaSchema,
5974
+ resolver,
5975
+ sub: args.sub,
5976
+ password: args.password,
5977
+ info,
5978
+ ctxUser
5979
+ });
5980
+ }
5981
+ if (info.fieldName === "authorize") {
5982
+ return handleAuthorize({
5983
+ tinaSchema,
5984
+ resolver,
5985
+ sub: args.sub,
5986
+ info,
5987
+ ctxUser
5988
+ });
5902
5989
  }
5903
5990
  if (info.fieldName === "updatePassword") {
5904
- if (!ctxUser?.sub) {
5905
- throw new Error("Not authorized");
5906
- }
5907
- if (!args.password) {
5908
- throw new Error("No password provided");
5909
- }
5910
- const collection = tinaSchema.getCollections().find((c) => c.isAuthCollection);
5911
- if (!collection) {
5912
- throw new Error("Auth collection not found");
5913
- }
5914
- const userFields = mapUserFields(collection, ["_rawData"]);
5915
- if (!userFields.length) {
5916
- throw new Error(
5917
- `No user field found in collection ${collection.name}`
5918
- );
5919
- }
5920
- if (userFields.length > 1) {
5921
- throw new Error(
5922
- `Multiple user fields found in collection ${collection.name}`
5923
- );
5924
- }
5925
- const userField = userFields[0];
5926
- const realPath = `${collection.path}/index.json`;
5927
- const userDoc = await resolver.getDocument(realPath);
5928
- const users = get(userDoc, userField.path);
5929
- if (!users) {
5930
- throw new Error("No users found");
5931
- }
5932
- const { idFieldName, passwordFieldName } = userField;
5933
- const user = users.find((u) => u[idFieldName] === ctxUser.sub);
5934
- if (!user) {
5935
- throw new Error("Not authorized");
5936
- }
5937
- user[passwordFieldName] = {
5938
- value: args.password,
5939
- passwordChangeRequired: false
5940
- };
5941
- const params = {};
5942
- (0, import_lodash4.default)(
5943
- params,
5944
- userField.path.slice(1),
5945
- // remove _rawData from users path
5946
- users.map((u) => {
5947
- if (user[idFieldName] === u[idFieldName]) {
5948
- return user;
5949
- }
5950
- return {
5951
- // don't overwrite other users' passwords
5952
- ...u,
5953
- [passwordFieldName]: {
5954
- ...u[passwordFieldName],
5955
- value: ""
5956
- }
5957
- };
5958
- })
5959
- );
5960
- await resolver.updateResolveDocument({
5961
- collection,
5962
- args: { params },
5963
- realPath,
5964
- isCollectionSpecific: true,
5965
- isAddPendingDocument: false
5991
+ return handleUpdatePassword({
5992
+ tinaSchema,
5993
+ resolver,
5994
+ password: args.password,
5995
+ info,
5996
+ ctxUser
5966
5997
  });
5967
- return true;
5968
5998
  }
5969
5999
  if (!lookup) {
5970
6000
  return value;
@@ -6177,7 +6207,7 @@ var import_node_path = __toESM(require("node:path"));
6177
6207
  var import_graphql6 = require("graphql");
6178
6208
  var import_micromatch2 = __toESM(require("micromatch"));
6179
6209
  var import_js_sha12 = __toESM(require("js-sha1"));
6180
- var import_lodash5 = __toESM(require("lodash.set"));
6210
+ var import_compat2 = require("es-toolkit/compat");
6181
6211
  var createLocalDatabase = (config) => {
6182
6212
  const level = new TinaLevelClient(config?.port);
6183
6213
  level.openConnection();
@@ -6552,8 +6582,7 @@ var Database = class {
6552
6582
  throw new TinaFetchError(`Error in PUT for ${filepath}`, {
6553
6583
  originalError: error,
6554
6584
  file: filepath,
6555
- collection: collectionName,
6556
- stack: error.stack
6585
+ collection: collectionName
6557
6586
  });
6558
6587
  }
6559
6588
  };
@@ -6913,8 +6942,7 @@ var Database = class {
6913
6942
  throw new TinaQueryError({
6914
6943
  originalError: error,
6915
6944
  file: path7,
6916
- collection: collection.name,
6917
- stack: error.stack
6945
+ collection: collection.name
6918
6946
  });
6919
6947
  }
6920
6948
  throw error;
@@ -7290,7 +7318,7 @@ var hashPasswordVisitor = async (node, path7) => {
7290
7318
  const passwordValuePath = [...path7, "value"];
7291
7319
  const plaintextPassword = get(node, passwordValuePath);
7292
7320
  if (plaintextPassword) {
7293
- (0, import_lodash5.default)(
7321
+ (0, import_compat2.set)(
7294
7322
  node,
7295
7323
  passwordValuePath,
7296
7324
  await generatePasswordHash({ password: plaintextPassword })
@@ -7444,8 +7472,7 @@ var _indexContent = async ({
7444
7472
  throw new TinaFetchError(`Unable to seed ${filepath}`, {
7445
7473
  originalError: error,
7446
7474
  file: filepath,
7447
- collection: collection?.name,
7448
- stack: error.stack
7475
+ collection: collection?.name
7449
7476
  });
7450
7477
  }
7451
7478
  });
package/dist/index.mjs CHANGED
@@ -1,6 +1,8 @@
1
1
  // src/build.ts
2
- import { print } from "graphql";
3
- import uniqBy2 from "lodash.uniqby";
2
+ import {
3
+ print
4
+ } from "graphql";
5
+ import { uniqBy as uniqBy2 } from "es-toolkit";
4
6
 
5
7
  // src/util.ts
6
8
  import * as yup from "yup";
@@ -56,7 +58,7 @@ var flattenDeep = (arr) => arr.flatMap(
56
58
  );
57
59
 
58
60
  // src/ast-builder/index.ts
59
- import uniqBy from "lodash.uniqby";
61
+ import { uniqBy } from "es-toolkit";
60
62
  var SysFieldDefinition = {
61
63
  kind: "Field",
62
64
  name: {
@@ -977,6 +979,7 @@ var astBuilder = {
977
979
  ...extractInlineTypes(ast.globalTemplates),
978
980
  ...ast.definitions
979
981
  ],
982
+ // @ts-ignore - all nodes have a name property in practice
980
983
  (field) => field.name.value
981
984
  );
982
985
  return {
@@ -2711,7 +2714,7 @@ var Builder = class {
2711
2714
  this._buildDataField = async (field) => {
2712
2715
  const listWarningMsg = `
2713
2716
  WARNING: The user interface for ${field.type} does not support \`list: true\`
2714
- Visit https://tina.io/docs/errors/ui-not-supported/ for more information
2717
+ Visit https://tina.io/docs/r/content-fields/#list-fields/ for more information
2715
2718
 
2716
2719
  `;
2717
2720
  switch (field.type) {
@@ -2864,8 +2867,8 @@ import { TinaSchema } from "@tinacms/schema-tools";
2864
2867
 
2865
2868
  // src/schema/validate.ts
2866
2869
  import { addNamespaceToSchema } from "@tinacms/schema-tools";
2867
- import deepClone from "lodash.clonedeep";
2868
2870
  import * as yup2 from "yup";
2871
+ import { cloneDeep } from "es-toolkit";
2869
2872
  import {
2870
2873
  validateTinaCloudSchemaConfig
2871
2874
  } from "@tinacms/schema-tools";
@@ -2882,7 +2885,7 @@ var FIELD_TYPES = [
2882
2885
  ];
2883
2886
  var validateSchema = async (schema) => {
2884
2887
  const schema2 = addNamespaceToSchema(
2885
- deepClone(schema)
2888
+ cloneDeep(schema)
2886
2889
  );
2887
2890
  const collections = await sequential(
2888
2891
  schema2.collections,
@@ -3019,7 +3022,7 @@ var validateField = async (field) => {
3019
3022
  // package.json
3020
3023
  var package_default = {
3021
3024
  name: "@tinacms/graphql",
3022
- version: "1.6.1",
3025
+ version: "1.6.3",
3023
3026
  main: "dist/index.js",
3024
3027
  module: "dist/index.mjs",
3025
3028
  typings: "dist/index.d.ts",
@@ -3054,6 +3057,7 @@ var package_default = {
3054
3057
  "@tinacms/schema-tools": "workspace:*",
3055
3058
  "abstract-level": "catalog:",
3056
3059
  "date-fns": "^2.30.0",
3060
+ "es-toolkit": "^1.42.0",
3057
3061
  "fast-glob": "catalog:",
3058
3062
  "fs-extra": "catalog:",
3059
3063
  "glob-parent": "catalog:",
@@ -3063,15 +3067,12 @@ var package_default = {
3063
3067
  "js-sha1": "catalog:",
3064
3068
  "js-yaml": "^3.14.1",
3065
3069
  "jsonpath-plus": "catalog:",
3066
- "lodash.clonedeep": "catalog:",
3067
- "lodash.set": "catalog:",
3068
- "lodash.uniqby": "catalog:",
3069
3070
  "many-level": "catalog:",
3070
3071
  micromatch: "catalog:",
3071
3072
  "normalize-path": "catalog:",
3072
3073
  "readable-stream": "catalog:",
3073
3074
  scmp: "catalog:",
3074
- yup: "^0.32.11"
3075
+ yup: "^1.6.1"
3075
3076
  },
3076
3077
  publishConfig: {
3077
3078
  registry: "https://registry.npmjs.org"
@@ -3088,21 +3089,18 @@ var package_default = {
3088
3089
  "@types/express": "catalog:",
3089
3090
  "@types/fs-extra": "^9.0.13",
3090
3091
  "@types/js-yaml": "^3.12.10",
3091
- "@types/lodash.camelcase": "catalog:",
3092
- "@types/lodash.upperfirst": "catalog:",
3093
3092
  "@types/lru-cache": "catalog:",
3094
3093
  "@types/mdast": "catalog:",
3095
3094
  "@types/micromatch": "catalog:",
3096
3095
  "@types/node": "^22.13.1",
3097
3096
  "@types/normalize-path": "catalog:",
3098
3097
  "@types/ws": "catalog:",
3099
- "@types/yup": "^0.29.14",
3100
3098
  "jest-file-snapshot": "^0.5.0",
3101
3099
  "memory-level": "catalog:",
3102
3100
  typescript: "^5.7.3",
3103
3101
  vite: "^4.5.9",
3104
3102
  vitest: "^0.32.4",
3105
- zod: "^3.24.2"
3103
+ zod: "catalog:"
3106
3104
  }
3107
3105
  };
3108
3106
 
@@ -3173,8 +3171,8 @@ var _buildFragments = async (builder, tinaSchema) => {
3173
3171
  const fragDoc = {
3174
3172
  kind: "Document",
3175
3173
  definitions: uniqBy2(
3176
- // @ts-ignore
3177
3174
  extractInlineTypes(fragmentDefinitionsFields),
3175
+ // @ts-ignore - all nodes returned by extractInlineTypes have a name property
3178
3176
  (node) => node.name.value
3179
3177
  )
3180
3178
  };
@@ -3206,8 +3204,8 @@ var _buildQueries = async (builder, tinaSchema) => {
3206
3204
  const queryDoc = {
3207
3205
  kind: "Document",
3208
3206
  definitions: uniqBy2(
3209
- // @ts-ignore
3210
3207
  extractInlineTypes(operationsDefinitions),
3208
+ // @ts-ignore - all nodes returned by extractInlineTypes have a name property
3211
3209
  (node) => node.name.value
3212
3210
  )
3213
3211
  };
@@ -3294,14 +3292,15 @@ var _buildSchema = async (builder, tinaSchema) => {
3294
3292
  fields: mutationTypeDefinitionFields
3295
3293
  })
3296
3294
  );
3297
- return {
3295
+ const schema = {
3298
3296
  kind: "Document",
3299
3297
  definitions: uniqBy2(
3300
- // @ts-ignore
3301
3298
  extractInlineTypes(definitions),
3299
+ // @ts-ignore - all nodes returned by extractInlineTypes have a name property
3302
3300
  (node) => node.name.value
3303
3301
  )
3304
3302
  };
3303
+ return schema;
3305
3304
  };
3306
3305
 
3307
3306
  // src/resolve.ts
@@ -4385,7 +4384,6 @@ var TinaFetchError = class extends Error {
4385
4384
  super(message);
4386
4385
  this.name = "TinaFetchError";
4387
4386
  this.collection = args.collection;
4388
- this.stack = args.stack;
4389
4387
  this.file = args.file;
4390
4388
  this.originalError = args.originalError;
4391
4389
  }
@@ -4767,8 +4765,7 @@ var transformDocumentIntoPayload = async (fullPath, rawData, tinaSchema, config,
4767
4765
  originalError: e,
4768
4766
  collection: collection.name,
4769
4767
  includeAuditMessage: !isAudit,
4770
- file: relativePath,
4771
- stack: e.stack
4768
+ file: relativePath
4772
4769
  });
4773
4770
  }
4774
4771
  const titleField = template.fields.find((x) => {
@@ -5679,8 +5676,129 @@ var resolveDateInput = (value) => {
5679
5676
  return date;
5680
5677
  };
5681
5678
 
5682
- // src/resolve.ts
5683
- import set from "lodash.set";
5679
+ // src/resolver/auth-fields.ts
5680
+ import { set } from "es-toolkit/compat";
5681
+ async function getUserDocumentContext(tinaSchema, resolver) {
5682
+ const collection = tinaSchema.getCollections().find((c) => c.isAuthCollection);
5683
+ if (!collection) {
5684
+ throw new Error("Auth collection not found");
5685
+ }
5686
+ const userFields = mapUserFields(collection, ["_rawData"]);
5687
+ if (!userFields.length) {
5688
+ throw new Error(`No user field found in collection ${collection.name}`);
5689
+ }
5690
+ if (userFields.length > 1) {
5691
+ throw new Error(
5692
+ `Multiple user fields found in collection ${collection.name}`
5693
+ );
5694
+ }
5695
+ const userField = userFields[0];
5696
+ const realPath = `${collection.path}/index.json`;
5697
+ const userDoc = await resolver.getDocument(realPath);
5698
+ const users = get(userDoc, userField.path);
5699
+ if (!users) {
5700
+ throw new Error("No users found");
5701
+ }
5702
+ return { collection, userField, users, userDoc, realPath };
5703
+ }
5704
+ function findUserInCollection(users, userField, userSub) {
5705
+ const { idFieldName } = userField;
5706
+ if (!idFieldName) {
5707
+ throw new Error("No uid field found on user field");
5708
+ }
5709
+ return users.find((u) => u[idFieldName] === userSub) || null;
5710
+ }
5711
+ async function handleAuthenticate({
5712
+ tinaSchema,
5713
+ resolver,
5714
+ sub,
5715
+ password,
5716
+ ctxUser
5717
+ }) {
5718
+ const userSub = sub || ctxUser?.sub;
5719
+ const { userField, users } = await getUserDocumentContext(
5720
+ tinaSchema,
5721
+ resolver
5722
+ );
5723
+ const user = findUserInCollection(users, userField, userSub);
5724
+ if (!user) {
5725
+ return null;
5726
+ }
5727
+ const { passwordFieldName } = userField;
5728
+ const saltedHash = get(user, [passwordFieldName || "", "value"]);
5729
+ if (!saltedHash) {
5730
+ throw new Error("No password field found on user field");
5731
+ }
5732
+ const matches = await checkPasswordHash({
5733
+ saltedHash,
5734
+ password
5735
+ });
5736
+ return matches ? user : null;
5737
+ }
5738
+ async function handleAuthorize({
5739
+ tinaSchema,
5740
+ resolver,
5741
+ sub,
5742
+ ctxUser
5743
+ }) {
5744
+ const userSub = sub || ctxUser?.sub;
5745
+ const { userField, users } = await getUserDocumentContext(
5746
+ tinaSchema,
5747
+ resolver
5748
+ );
5749
+ const user = findUserInCollection(users, userField, userSub);
5750
+ return user ? user : null;
5751
+ }
5752
+ async function handleUpdatePassword({
5753
+ tinaSchema,
5754
+ resolver,
5755
+ password,
5756
+ ctxUser
5757
+ }) {
5758
+ if (!ctxUser?.sub) {
5759
+ throw new Error("Not authorized");
5760
+ }
5761
+ if (!password) {
5762
+ throw new Error("No password provided");
5763
+ }
5764
+ const { collection, userField, users, realPath } = await getUserDocumentContext(tinaSchema, resolver);
5765
+ const { idFieldName, passwordFieldName } = userField;
5766
+ const user = users.find((u) => u[idFieldName] === ctxUser.sub);
5767
+ if (!user) {
5768
+ throw new Error("Not authorized");
5769
+ }
5770
+ user[passwordFieldName] = {
5771
+ value: password,
5772
+ passwordChangeRequired: false
5773
+ };
5774
+ const params = {};
5775
+ set(
5776
+ params,
5777
+ userField.path.slice(1),
5778
+ // remove _rawData from users path
5779
+ users.map((u) => {
5780
+ if (user[idFieldName] === u[idFieldName]) {
5781
+ return user;
5782
+ }
5783
+ return {
5784
+ // don't overwrite other users' passwords
5785
+ ...u,
5786
+ [passwordFieldName]: {
5787
+ ...u[passwordFieldName],
5788
+ value: ""
5789
+ }
5790
+ };
5791
+ })
5792
+ );
5793
+ await resolver.updateResolveDocument({
5794
+ collection,
5795
+ args: { params },
5796
+ realPath,
5797
+ isCollectionSpecific: true,
5798
+ isAddPendingDocument: false
5799
+ });
5800
+ return true;
5801
+ }
5684
5802
 
5685
5803
  // src/error.ts
5686
5804
  import { GraphQLError as GraphQLError3 } from "graphql";
@@ -5790,119 +5908,33 @@ var resolve = async ({
5790
5908
  );
5791
5909
  }
5792
5910
  }
5793
- if (info.fieldName === "authenticate" || info.fieldName === "authorize") {
5794
- const sub = args.sub || ctxUser?.sub;
5795
- const collection = tinaSchema.getCollections().find((c) => c.isAuthCollection);
5796
- if (!collection) {
5797
- throw new Error("Auth collection not found");
5798
- }
5799
- const userFields = mapUserFields(collection, ["_rawData"]);
5800
- if (!userFields.length) {
5801
- throw new Error(
5802
- `No user field found in collection ${collection.name}`
5803
- );
5804
- }
5805
- if (userFields.length > 1) {
5806
- throw new Error(
5807
- `Multiple user fields found in collection ${collection.name}`
5808
- );
5809
- }
5810
- const userField = userFields[0];
5811
- const realPath = `${collection.path}/index.json`;
5812
- const userDoc = await resolver.getDocument(realPath);
5813
- const users = get(userDoc, userField.path);
5814
- if (!users) {
5815
- throw new Error("No users found");
5816
- }
5817
- const { idFieldName, passwordFieldName } = userField;
5818
- if (!idFieldName) {
5819
- throw new Error("No uid field found on user field");
5820
- }
5821
- const user = users.find((u) => u[idFieldName] === sub);
5822
- if (!user) {
5823
- return null;
5824
- }
5825
- if (info.fieldName === "authenticate") {
5826
- const saltedHash = get(user, [passwordFieldName || "", "value"]);
5827
- if (!saltedHash) {
5828
- throw new Error("No password field found on user field");
5829
- }
5830
- const matches = await checkPasswordHash({
5831
- saltedHash,
5832
- password: args.password
5833
- });
5834
- if (matches) {
5835
- return user;
5836
- }
5837
- return null;
5838
- }
5839
- return user;
5911
+ if (info.fieldName === "authenticate") {
5912
+ return handleAuthenticate({
5913
+ tinaSchema,
5914
+ resolver,
5915
+ sub: args.sub,
5916
+ password: args.password,
5917
+ info,
5918
+ ctxUser
5919
+ });
5920
+ }
5921
+ if (info.fieldName === "authorize") {
5922
+ return handleAuthorize({
5923
+ tinaSchema,
5924
+ resolver,
5925
+ sub: args.sub,
5926
+ info,
5927
+ ctxUser
5928
+ });
5840
5929
  }
5841
5930
  if (info.fieldName === "updatePassword") {
5842
- if (!ctxUser?.sub) {
5843
- throw new Error("Not authorized");
5844
- }
5845
- if (!args.password) {
5846
- throw new Error("No password provided");
5847
- }
5848
- const collection = tinaSchema.getCollections().find((c) => c.isAuthCollection);
5849
- if (!collection) {
5850
- throw new Error("Auth collection not found");
5851
- }
5852
- const userFields = mapUserFields(collection, ["_rawData"]);
5853
- if (!userFields.length) {
5854
- throw new Error(
5855
- `No user field found in collection ${collection.name}`
5856
- );
5857
- }
5858
- if (userFields.length > 1) {
5859
- throw new Error(
5860
- `Multiple user fields found in collection ${collection.name}`
5861
- );
5862
- }
5863
- const userField = userFields[0];
5864
- const realPath = `${collection.path}/index.json`;
5865
- const userDoc = await resolver.getDocument(realPath);
5866
- const users = get(userDoc, userField.path);
5867
- if (!users) {
5868
- throw new Error("No users found");
5869
- }
5870
- const { idFieldName, passwordFieldName } = userField;
5871
- const user = users.find((u) => u[idFieldName] === ctxUser.sub);
5872
- if (!user) {
5873
- throw new Error("Not authorized");
5874
- }
5875
- user[passwordFieldName] = {
5876
- value: args.password,
5877
- passwordChangeRequired: false
5878
- };
5879
- const params = {};
5880
- set(
5881
- params,
5882
- userField.path.slice(1),
5883
- // remove _rawData from users path
5884
- users.map((u) => {
5885
- if (user[idFieldName] === u[idFieldName]) {
5886
- return user;
5887
- }
5888
- return {
5889
- // don't overwrite other users' passwords
5890
- ...u,
5891
- [passwordFieldName]: {
5892
- ...u[passwordFieldName],
5893
- value: ""
5894
- }
5895
- };
5896
- })
5897
- );
5898
- await resolver.updateResolveDocument({
5899
- collection,
5900
- args: { params },
5901
- realPath,
5902
- isCollectionSpecific: true,
5903
- isAddPendingDocument: false
5931
+ return handleUpdatePassword({
5932
+ tinaSchema,
5933
+ resolver,
5934
+ password: args.password,
5935
+ info,
5936
+ ctxUser
5904
5937
  });
5905
- return true;
5906
5938
  }
5907
5939
  if (!lookup) {
5908
5940
  return value;
@@ -6115,7 +6147,7 @@ import path4 from "node:path";
6115
6147
  import { GraphQLError as GraphQLError5 } from "graphql";
6116
6148
  import micromatch2 from "micromatch";
6117
6149
  import sha2 from "js-sha1";
6118
- import set2 from "lodash.set";
6150
+ import { set as set2 } from "es-toolkit/compat";
6119
6151
  var createLocalDatabase = (config) => {
6120
6152
  const level = new TinaLevelClient(config?.port);
6121
6153
  level.openConnection();
@@ -6490,8 +6522,7 @@ var Database = class {
6490
6522
  throw new TinaFetchError(`Error in PUT for ${filepath}`, {
6491
6523
  originalError: error,
6492
6524
  file: filepath,
6493
- collection: collectionName,
6494
- stack: error.stack
6525
+ collection: collectionName
6495
6526
  });
6496
6527
  }
6497
6528
  };
@@ -6851,8 +6882,7 @@ var Database = class {
6851
6882
  throw new TinaQueryError({
6852
6883
  originalError: error,
6853
6884
  file: path7,
6854
- collection: collection.name,
6855
- stack: error.stack
6885
+ collection: collection.name
6856
6886
  });
6857
6887
  }
6858
6888
  throw error;
@@ -7382,8 +7412,7 @@ var _indexContent = async ({
7382
7412
  throw new TinaFetchError(`Unable to seed ${filepath}`, {
7383
7413
  originalError: error,
7384
7414
  file: filepath,
7385
- collection: collection?.name,
7386
- stack: error.stack
7415
+ collection: collection?.name
7387
7416
  });
7388
7417
  }
7389
7418
  });
@@ -0,0 +1,31 @@
1
+ import type { TinaSchema } from '@tinacms/schema-tools';
2
+ import type { GraphQLResolveInfo } from 'graphql';
3
+ import type { Resolver } from './index';
4
+ export declare function handleAuthenticate({ tinaSchema, resolver, sub, password, ctxUser, }: {
5
+ tinaSchema: TinaSchema;
6
+ resolver: Resolver;
7
+ sub?: string;
8
+ password: string;
9
+ info: GraphQLResolveInfo;
10
+ ctxUser?: {
11
+ sub?: string;
12
+ };
13
+ }): Promise<any>;
14
+ export declare function handleAuthorize({ tinaSchema, resolver, sub, ctxUser, }: {
15
+ tinaSchema: TinaSchema;
16
+ resolver: Resolver;
17
+ sub?: string;
18
+ info: GraphQLResolveInfo;
19
+ ctxUser?: {
20
+ sub?: string;
21
+ };
22
+ }): Promise<any>;
23
+ export declare function handleUpdatePassword({ tinaSchema, resolver, password, ctxUser, }: {
24
+ tinaSchema: TinaSchema;
25
+ resolver: Resolver;
26
+ password: string;
27
+ info: GraphQLResolveInfo;
28
+ ctxUser?: {
29
+ sub?: string;
30
+ };
31
+ }): Promise<boolean>;
@@ -15,6 +15,7 @@ export declare class TinaGraphQLError extends Error implements GraphQLError {
15
15
  constructor(message: string, extensions?: Record<string, any>);
16
16
  }
17
17
  export type TypeFetchErrorArgs = {
18
+ /** @deprecated */
18
19
  stack?: string;
19
20
  file?: string;
20
21
  includeAuditMessage?: boolean;
@@ -22,7 +23,6 @@ export type TypeFetchErrorArgs = {
22
23
  collection?: string;
23
24
  };
24
25
  export declare class TinaFetchError extends Error {
25
- stack?: string;
26
26
  collection?: string;
27
27
  file?: string;
28
28
  originalError: Error;
@@ -36,7 +36,6 @@ export declare class TinaQueryError extends TinaFetchError {
36
36
  constructor(args: TypeFetchErrorArgs);
37
37
  }
38
38
  export declare class TinaParseDocumentError extends TinaFetchError {
39
- stack?: string;
40
39
  collection?: string;
41
40
  file?: string;
42
41
  originalError: Error;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tinacms/graphql",
3
- "version": "1.6.1",
3
+ "version": "1.6.3",
4
4
  "main": "dist/index.js",
5
5
  "module": "dist/index.mjs",
6
6
  "typings": "dist/index.d.ts",
@@ -26,6 +26,7 @@
26
26
  "@iarna/toml": "^2.2.5",
27
27
  "abstract-level": "^1.0.4",
28
28
  "date-fns": "^2.30.0",
29
+ "es-toolkit": "^1.42.0",
29
30
  "fast-glob": "^3.3.3",
30
31
  "fs-extra": "^11.3.0",
31
32
  "glob-parent": "^6.0.2",
@@ -35,17 +36,14 @@
35
36
  "js-sha1": "^0.6.0",
36
37
  "js-yaml": "^3.14.1",
37
38
  "jsonpath-plus": "10.1.0",
38
- "lodash.clonedeep": "^4.5.0",
39
- "lodash.set": "^4.3.2",
40
- "lodash.uniqby": "^4.7.0",
41
39
  "many-level": "^2.0.0",
42
40
  "micromatch": "4.0.8",
43
41
  "normalize-path": "^3.0.0",
44
42
  "readable-stream": "^4.7.0",
45
43
  "scmp": "^2.1.0",
46
- "yup": "^0.32.11",
47
- "@tinacms/schema-tools": "1.9.1",
48
- "@tinacms/mdx": "1.8.1"
44
+ "yup": "^1.6.1",
45
+ "@tinacms/mdx": "1.8.3",
46
+ "@tinacms/schema-tools": "1.10.1"
49
47
  },
50
48
  "publishConfig": {
51
49
  "registry": "https://registry.npmjs.org"
@@ -60,23 +58,20 @@
60
58
  "@types/express": "^4.17.21",
61
59
  "@types/fs-extra": "^9.0.13",
62
60
  "@types/js-yaml": "^3.12.10",
63
- "@types/lodash.camelcase": "^4.3.9",
64
- "@types/lodash.upperfirst": "^4.3.9",
65
61
  "@types/lru-cache": "^5.1.1",
66
62
  "@types/mdast": "^3.0.15",
67
63
  "@types/micromatch": "^4.0.9",
68
64
  "@types/node": "^22.13.1",
69
65
  "@types/normalize-path": "^3.0.2",
70
66
  "@types/ws": "^7.4.7",
71
- "@types/yup": "^0.29.14",
72
67
  "jest-file-snapshot": "^0.5.0",
73
68
  "memory-level": "^1.0.0",
74
69
  "typescript": "^5.7.3",
75
70
  "vite": "^4.5.9",
76
71
  "vitest": "^0.32.4",
77
72
  "zod": "^3.24.2",
78
- "@tinacms/scripts": "1.4.0",
79
- "@tinacms/schema-tools": "1.9.1"
73
+ "@tinacms/schema-tools": "1.10.1",
74
+ "@tinacms/scripts": "1.4.1"
80
75
  },
81
76
  "scripts": {
82
77
  "types": "pnpm tsc",