@snowtop/ent 0.0.32-alpha.4 → 0.0.34

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.
@@ -14,6 +14,7 @@ export interface Builder<T extends Ent> {
14
14
  build(): Promise<Changeset<T>>;
15
15
  operation: WriteOperation;
16
16
  editedEnt?(): Promise<T | null>;
17
+ nodeType: string;
17
18
  }
18
19
  export interface Executor extends Iterable<DataOperation>, Iterator<DataOperation> {
19
20
  placeholderID: ID;
@@ -66,7 +66,7 @@ export declare class Orchestrator<T extends Ent> {
66
66
  validX(): Promise<void>;
67
67
  build(): Promise<EntChangeset<T>>;
68
68
  private viewerForEntLoad;
69
- private returnedRow;
69
+ returnedRow(): Promise<Data | null>;
70
70
  editedEnt(): Promise<T | null>;
71
71
  editedEntX(): Promise<T>;
72
72
  }
package/core/base.d.ts CHANGED
@@ -92,6 +92,12 @@ export interface LoadEntOptions<T extends Ent> extends LoadableEntOptions<T>, Se
92
92
  export interface LoadCustomEntOptions<T extends Ent> extends SelectBaseDataOptions {
93
93
  ent: EntConstructor<T>;
94
94
  }
95
+ export interface LoaderInfo {
96
+ tableName: string;
97
+ fields: string[];
98
+ nodeType: string;
99
+ loaderFactory: LoaderFactory<any, Data | null>;
100
+ }
95
101
  export interface EditEntOptions<T extends Ent> extends LoadableEntOptions<T>, EditRowOptions {
96
102
  }
97
103
  declare enum privacyResult {
@@ -6,5 +6,5 @@ export { GraphQLEdgeType, GraphQLConnectionType, } from "./query/connection_type
6
6
  export { GraphQLNodeInterface } from "./builtins/node";
7
7
  export { GraphQLConnectionInterface } from "./builtins/connection";
8
8
  export { GraphQLEdgeInterface } from "./builtins/edge";
9
- export { NodeResolver, EntNodeResolver, registerResolver, clearResolvers, resolveID, nodeIDEncoder, mustDecodeIDFromGQLID, encodeGQLID, } from "./node_resolver";
9
+ export { NodeResolver, EntNodeResolver, registerResolver, clearResolvers, resolveID, nodeIDEncoder, mustDecodeIDFromGQLID, mustDecodeNullableIDFromGQLID, encodeGQLID, } from "./node_resolver";
10
10
  export { convertFromGQLEnum, convertToGQLEnum } from "./enums";
package/graphql/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.convertToGQLEnum = exports.convertFromGQLEnum = exports.encodeGQLID = exports.mustDecodeIDFromGQLID = exports.nodeIDEncoder = exports.resolveID = exports.clearResolvers = exports.registerResolver = exports.EntNodeResolver = exports.GraphQLEdgeInterface = exports.GraphQLConnectionInterface = exports.GraphQLNodeInterface = exports.GraphQLConnectionType = exports.GraphQLEdgeType = exports.GraphQLEdgeConnection = exports.GraphQLPageInfo = exports.GraphQLTime = exports.gqlFileUpload = exports.GQLCapture = exports.gqlConnection = exports.gqlContextType = exports.gqlMutation = exports.gqlQuery = exports.gqlObjectType = exports.gqlInputObjectType = exports.gqlArgType = exports.gqlArg = exports.gqlField = void 0;
3
+ exports.convertToGQLEnum = exports.convertFromGQLEnum = exports.encodeGQLID = exports.mustDecodeNullableIDFromGQLID = exports.mustDecodeIDFromGQLID = exports.nodeIDEncoder = exports.resolveID = exports.clearResolvers = exports.registerResolver = exports.EntNodeResolver = exports.GraphQLEdgeInterface = exports.GraphQLConnectionInterface = exports.GraphQLNodeInterface = exports.GraphQLConnectionType = exports.GraphQLEdgeType = exports.GraphQLEdgeConnection = exports.GraphQLPageInfo = exports.GraphQLTime = exports.gqlFileUpload = exports.GQLCapture = exports.gqlConnection = exports.gqlContextType = exports.gqlMutation = exports.gqlQuery = exports.gqlObjectType = exports.gqlInputObjectType = exports.gqlArgType = exports.gqlArg = exports.gqlField = void 0;
4
4
  var graphql_1 = require("./graphql");
5
5
  Object.defineProperty(exports, "gqlField", { enumerable: true, get: function () { return graphql_1.gqlField; } });
6
6
  Object.defineProperty(exports, "gqlArg", { enumerable: true, get: function () { return graphql_1.gqlArg; } });
@@ -35,6 +35,7 @@ Object.defineProperty(exports, "clearResolvers", { enumerable: true, get: functi
35
35
  Object.defineProperty(exports, "resolveID", { enumerable: true, get: function () { return node_resolver_1.resolveID; } });
36
36
  Object.defineProperty(exports, "nodeIDEncoder", { enumerable: true, get: function () { return node_resolver_1.nodeIDEncoder; } });
37
37
  Object.defineProperty(exports, "mustDecodeIDFromGQLID", { enumerable: true, get: function () { return node_resolver_1.mustDecodeIDFromGQLID; } });
38
+ Object.defineProperty(exports, "mustDecodeNullableIDFromGQLID", { enumerable: true, get: function () { return node_resolver_1.mustDecodeNullableIDFromGQLID; } });
38
39
  Object.defineProperty(exports, "encodeGQLID", { enumerable: true, get: function () { return node_resolver_1.encodeGQLID; } });
39
40
  var enums_1 = require("./enums");
40
41
  Object.defineProperty(exports, "convertFromGQLEnum", { enumerable: true, get: function () { return enums_1.convertFromGQLEnum; } });
@@ -24,5 +24,6 @@ export declare function clearResolvers(): Promise<void>;
24
24
  export declare function resolveID(viewer: Viewer, id: string): Promise<Node | null>;
25
25
  export declare const nodeIDEncoder: GraphQLFieldResolver<Ent, {}>;
26
26
  export declare function mustDecodeIDFromGQLID(id: string): ID;
27
+ export declare function mustDecodeNullableIDFromGQLID(id: string | null | undefined): any;
27
28
  export declare function encodeGQLID(node: Ent): string;
28
29
  export {};
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.encodeGQLID = exports.mustDecodeIDFromGQLID = exports.nodeIDEncoder = exports.resolveID = exports.clearResolvers = exports.registerResolver = exports.EntNodeResolver = void 0;
3
+ exports.encodeGQLID = exports.mustDecodeNullableIDFromGQLID = exports.mustDecodeIDFromGQLID = exports.nodeIDEncoder = exports.resolveID = exports.clearResolvers = exports.registerResolver = exports.EntNodeResolver = void 0;
4
4
  class EntNodeResolver {
5
5
  constructor(loader) {
6
6
  this.loader = loader;
@@ -76,6 +76,19 @@ function mustDecodeIDFromGQLID(id) {
76
76
  return decoded;
77
77
  }
78
78
  exports.mustDecodeIDFromGQLID = mustDecodeIDFromGQLID;
79
+ // TODO get the right (non-any) return type here. may need to change codegen to do the right thing here
80
+ function mustDecodeNullableIDFromGQLID(id) {
81
+ // support undefined because fields in action
82
+ if (id === null || id === undefined) {
83
+ return id;
84
+ }
85
+ const decoded = EntNodeResolver.decode(id);
86
+ if (!decoded) {
87
+ throw new Error(`wasn't able to decode invalid ${id}`);
88
+ }
89
+ return decoded;
90
+ }
91
+ exports.mustDecodeNullableIDFromGQLID = mustDecodeNullableIDFromGQLID;
79
92
  // This takes an ent and returns the graphql id
80
93
  function encodeGQLID(node) {
81
94
  // let's do 3 parts. we take the "node" prefix
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@snowtop/ent",
3
- "version": "0.0.32-alpha.4",
3
+ "version": "0.0.34",
4
4
  "description": "snowtop ent framework",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
package/schema/field.d.ts CHANGED
@@ -144,7 +144,7 @@ export declare class ListField extends BaseField {
144
144
  private validators;
145
145
  constructor(field: Field, options: FieldOptions);
146
146
  validate(validator: (val: any[]) => boolean): this;
147
- valid(val: any): boolean;
147
+ valid(val: any): Promise<boolean>;
148
148
  private postgresVal;
149
149
  format(val: any): any;
150
150
  minLen(l: number): this;
package/schema/field.js CHANGED
@@ -24,6 +24,7 @@ const luxon_1 = require("luxon");
24
24
  const snake_case_1 = require("snake-case");
25
25
  const db_1 = __importStar(require("../core/db"));
26
26
  const schema_1 = require("./schema");
27
+ const util_1 = require("util");
27
28
  class BaseField {
28
29
  logValue(val) {
29
30
  if (this.sensitive) {
@@ -82,8 +83,8 @@ class UUIDField extends BaseField {
82
83
  }
83
84
  }
84
85
  if (options.fieldEdge?.enforceSchema &&
85
- !options.fieldEdge.getLoaderOptions) {
86
- throw new Error(`cannot enforceSchema if getLoaderOptions wasn't passed in`);
86
+ !options.fieldEdge.getLoaderInfoFromSchema) {
87
+ throw new Error(`cannot enforceSchema if getLoaderInfoFromSchema wasn't passed in`);
87
88
  }
88
89
  }
89
90
  isBuilder(val) {
@@ -93,14 +94,17 @@ class UUIDField extends BaseField {
93
94
  if (!this.options.fieldEdge?.enforceSchema) {
94
95
  return true;
95
96
  }
96
- const getLoaderOptions = this.options.fieldEdge.getLoaderOptions;
97
- const loadRowOptions = getLoaderOptions(this.options.fieldEdge.schema);
97
+ const getLoaderInfo = this.options.fieldEdge.getLoaderInfoFromSchema;
98
+ const loaderInfo = getLoaderInfo(this.options.fieldEdge.schema);
99
+ if (!loaderInfo) {
100
+ throw new Error(`couldn't get loaderInfo for ${this.options.fieldEdge.schema}`);
101
+ }
98
102
  if (this.isBuilder(val)) {
99
- // if builder, the ent type of the builder and the ent type returned by the load constructor should match
100
- return val.ent === loadRowOptions.ent;
103
+ // if builder, the nodeType of the builder and the nodeType of the loaderInfo should match
104
+ return val.nodeType === loaderInfo.nodeType;
101
105
  }
102
106
  // TODO we need context here to make sure that we hit local cache
103
- const row = await loadRowOptions.loaderFactory.createLoader().load(val);
107
+ const row = await loaderInfo.loaderFactory.createLoader().load(val);
104
108
  return row !== null;
105
109
  }
106
110
  }
@@ -564,7 +568,7 @@ class ListField extends BaseField {
564
568
  this.validators.push(validator);
565
569
  return this;
566
570
  }
567
- valid(val) {
571
+ async valid(val) {
568
572
  if (!Array.isArray(val)) {
569
573
  return false;
570
574
  }
@@ -573,15 +577,18 @@ class ListField extends BaseField {
573
577
  return false;
574
578
  }
575
579
  }
576
- if (!this.field.valid) {
580
+ const valid = this.field.valid;
581
+ if (!valid) {
577
582
  return true;
578
583
  }
579
- for (const v of val) {
580
- if (!this.field.valid(v)) {
581
- return false;
582
- }
584
+ const res = valid.apply(this.field, [val[0]]);
585
+ if (util_1.types.isPromise(res)) {
586
+ const ret = await Promise.all(val.map(async (v) => await valid.apply(this.field, [v])));
587
+ return ret.every((v) => v);
583
588
  }
584
- return true;
589
+ const ret = val.map((v) => valid.apply(this.field, [v]));
590
+ const result = ret.every((v) => v);
591
+ return result;
585
592
  }
586
593
  postgresVal(val, jsonType) {
587
594
  if (!jsonType) {
@@ -1,4 +1,4 @@
1
- import { Data, Ent, LoadEntOptions } from "../core/base";
1
+ import { Data, Ent, LoaderInfo } from "../core/base";
2
2
  import { Builder } from "../action/action";
3
3
  export default interface Schema {
4
4
  fields: Field[];
@@ -102,7 +102,7 @@ export interface ForeignKey {
102
102
  disableIndex?: boolean;
103
103
  disableBuilderType?: boolean;
104
104
  }
105
- declare type getLoaderOptionsFn = (type: any) => LoadEntOptions<Ent>;
105
+ declare type getLoaderInfoFn = (type: string) => LoaderInfo;
106
106
  export interface InverseFieldEdge {
107
107
  name: string;
108
108
  edgeConstName?: string;
@@ -113,7 +113,7 @@ export interface FieldEdge {
113
113
  schema: string;
114
114
  inverseEdge?: string | InverseFieldEdge;
115
115
  enforceSchema?: boolean;
116
- getLoaderOptions?: getLoaderOptionsFn;
116
+ getLoaderInfoFromSchema?: getLoaderInfoFn;
117
117
  disableBuilderType?: boolean;
118
118
  }
119
119
  export interface FieldOptions {
@@ -171,6 +171,7 @@ export interface ActionField {
171
171
  nullable?: boolean | NullableListOptions;
172
172
  list?: boolean;
173
173
  actionName?: string;
174
+ excludedFields?: string[];
174
175
  }
175
176
  export interface Action {
176
177
  operation: ActionOperation;
@@ -71,6 +71,7 @@ export declare class SimpleBuilder<T extends Ent> implements Builder<T> {
71
71
  placeholderID: ID;
72
72
  orchestrator: Orchestrator<T>;
73
73
  fields: Map<string, any>;
74
+ nodeType: string;
74
75
  constructor(viewer: Viewer, schema: BuilderSchema<T>, fields: Map<string, any>, operation?: WriteOperation, existingEnt?: T | undefined, action?: Action<T> | undefined);
75
76
  build(): Promise<Changeset<T>>;
76
77
  editedEnt(): Promise<T | null>;
@@ -13,6 +13,7 @@ const pluralize_1 = __importDefault(require("pluralize"));
13
13
  const snake_case_1 = require("snake-case");
14
14
  const loaders_1 = require("../core/loaders");
15
15
  const convert_1 = require("../core/convert");
16
+ const camel_case_1 = require("camel-case");
16
17
  class User {
17
18
  constructor(viewer, data) {
18
19
  this.viewer = viewer;
@@ -126,6 +127,7 @@ class SimpleBuilder {
126
127
  }
127
128
  this.ent = schema.ent;
128
129
  const tableName = getTableName(schema);
130
+ this.nodeType = (0, camel_case_1.camelCase)(schema.ent.name);
129
131
  this.orchestrator = new orchestrator_1.Orchestrator({
130
132
  viewer: this.viewer,
131
133
  operation: operation,
@@ -27,6 +27,7 @@ export declare function expectQueryFromRoot(config: queryRootConfig, ...options:
27
27
  export interface mutationRootConfig extends queryConfig {
28
28
  mutation: string;
29
29
  disableInputWrapping?: boolean;
30
+ nullQueryPaths?: string[];
30
31
  }
31
32
  export declare function expectMutation(config: mutationRootConfig, ...options: Option[]): Promise<supertest.SuperTest<supertest.Test>>;
32
33
  export {};
@@ -121,6 +121,22 @@ function getDataToReturn(data, colNames, returningAll) {
121
121
  return ret;
122
122
  }
123
123
  exports.getDataToReturn = getDataToReturn;
124
+ function processBeforeStoring(val) {
125
+ if (typeof val !== "string") {
126
+ return val;
127
+ }
128
+ // convert postgres lists into lists before storing
129
+ if (val[0] === "{" && val[val.length - 1] === "}") {
130
+ try {
131
+ // valid json, don't convert
132
+ JSON.parse(val);
133
+ }
134
+ catch (e) {
135
+ return val.substring(1, val.length - 1).split(",");
136
+ }
137
+ }
138
+ return val;
139
+ }
124
140
  function parseInsertStatement(ast, values, // values passed to query
125
141
  returningAll) {
126
142
  const tableName = getTableName(ast.table);
@@ -138,7 +154,7 @@ returningAll) {
138
154
  // INSERT INTO tableName (cols) VALUES (pos args)
139
155
  for (let i = 0; i < columns.length; i++) {
140
156
  let col = columns[i];
141
- data[col] = values[i];
157
+ data[col] = processBeforeStoring(values[i]);
142
158
  }
143
159
  let returningData = null;
144
160
  if (returningAll) {
@@ -411,7 +427,7 @@ function parseUpdateStatement(ast, values, map, returningAll) {
411
427
  for (const set of ast.set) {
412
428
  let col = set.column;
413
429
  let value = getValueFromRegex(set.value, values);
414
- overwrite[col] = value;
430
+ overwrite[col] = processBeforeStoring(value);
415
431
  }
416
432
  let columns = new Set();
417
433
  if (ast.returning) {