@snowtop/ent 0.1.0-alpha13 → 0.1.0-alpha16

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.
Files changed (39) hide show
  1. package/action/action.d.ts +19 -19
  2. package/action/executor.d.ts +3 -3
  3. package/action/executor.js +2 -2
  4. package/action/experimental_action.d.ts +21 -20
  5. package/action/experimental_action.js +10 -4
  6. package/action/orchestrator.d.ts +13 -13
  7. package/action/orchestrator.js +6 -4
  8. package/action/privacy.d.ts +2 -2
  9. package/core/base.d.ts +20 -20
  10. package/core/config.d.ts +5 -0
  11. package/core/context.d.ts +2 -2
  12. package/core/ent.d.ts +13 -13
  13. package/core/loaders/assoc_count_loader.d.ts +2 -2
  14. package/core/loaders/assoc_edge_loader.d.ts +2 -2
  15. package/core/loaders/object_loader.d.ts +3 -3
  16. package/core/loaders/query_loader.d.ts +2 -2
  17. package/core/loaders/raw_count_loader.d.ts +2 -2
  18. package/core/privacy.d.ts +24 -24
  19. package/core/query/assoc_query.d.ts +6 -6
  20. package/core/query/custom_query.d.ts +5 -5
  21. package/core/query/query.d.ts +1 -1
  22. package/core/viewer.d.ts +3 -3
  23. package/graphql/query/edge_connection.d.ts +9 -9
  24. package/graphql/query/page_info.d.ts +1 -1
  25. package/package.json +1 -1
  26. package/parse_schema/parse.d.ts +2 -0
  27. package/parse_schema/parse.js +4 -0
  28. package/schema/base_schema.js +3 -0
  29. package/schema/schema.d.ts +1 -0
  30. package/scripts/move_generated.js +2 -3
  31. package/scripts/transform_actions.d.ts +1 -0
  32. package/scripts/transform_actions.js +266 -0
  33. package/scripts/transform_code.js +1 -3
  34. package/testutils/builder.d.ts +10 -9
  35. package/testutils/builder.js +16 -3
  36. package/testutils/fake_data/user_query.d.ts +2 -2
  37. package/testutils/fake_log.d.ts +3 -3
  38. package/tsc/ast.d.ts +11 -0
  39. package/tsc/ast.js +46 -13
package/core/privacy.d.ts CHANGED
@@ -6,22 +6,22 @@ export declare class EntPrivacyError extends Error implements PrivacyError {
6
6
  constructor(privacyPolicy: PrivacyPolicy, rule: PrivacyPolicyRule, ent?: Ent);
7
7
  }
8
8
  export declare const AlwaysAllowRule: {
9
- apply(_v: Viewer, _ent?: Ent | undefined): Promise<PrivacyResult>;
9
+ apply(_v: Viewer, _ent?: Ent<Viewer<Ent<any> | null, ID | null>> | undefined): Promise<PrivacyResult>;
10
10
  };
11
11
  export declare const AlwaysDenyRule: {
12
- apply(_v: Viewer, _ent?: Ent | undefined): Promise<PrivacyResult>;
12
+ apply(_v: Viewer, _ent?: Ent<Viewer<Ent<any> | null, ID | null>> | undefined): Promise<PrivacyResult>;
13
13
  };
14
14
  export declare const DenyIfLoggedOutRule: {
15
- apply(v: Viewer, _ent?: Ent | undefined): Promise<PrivacyResult>;
15
+ apply(v: Viewer, _ent?: Ent<Viewer<Ent<any> | null, ID | null>> | undefined): Promise<PrivacyResult>;
16
16
  };
17
17
  export declare const DenyIfLoggedInRule: {
18
- apply(v: Viewer, _ent?: Ent | undefined): Promise<PrivacyResult>;
18
+ apply(v: Viewer, _ent?: Ent<Viewer<Ent<any> | null, ID | null>> | undefined): Promise<PrivacyResult>;
19
19
  };
20
20
  export declare const AllowIfHasIdentity: {
21
- apply(v: Viewer, _ent?: Ent | undefined): Promise<PrivacyResult>;
21
+ apply(v: Viewer, _ent?: Ent<Viewer<Ent<any> | null, ID | null>> | undefined): Promise<PrivacyResult>;
22
22
  };
23
23
  export declare const AllowIfViewerRule: {
24
- apply(v: Viewer, ent?: Ent | undefined): Promise<PrivacyResult>;
24
+ apply(v: Viewer, ent?: Ent<Viewer<Ent<any> | null, ID | null>> | undefined): Promise<PrivacyResult>;
25
25
  };
26
26
  export declare class AllowIfViewerEqualsRule {
27
27
  private id;
@@ -71,45 +71,45 @@ export declare class DenyIfEntPropertyIsRule<T extends Ent> implements PrivacyPo
71
71
  constructor(property: keyof T, val: any);
72
72
  apply(v: Viewer, ent?: T): Promise<PrivacyResult>;
73
73
  }
74
- export declare class AllowIfEntIsVisibleRule<T extends Ent> implements PrivacyPolicyRule {
74
+ export declare class AllowIfEntIsVisibleRule<TEnt extends Ent<TViewer>, TViewer extends Viewer> implements PrivacyPolicyRule {
75
75
  private id;
76
76
  private options;
77
- constructor(id: ID, options: LoadEntOptions<T>);
78
- apply(v: Viewer, _ent?: Ent): Promise<PrivacyResult>;
77
+ constructor(id: ID, options: LoadEntOptions<TEnt, TViewer>);
78
+ apply(v: TViewer, _ent?: Ent): Promise<PrivacyResult>;
79
79
  }
80
- export declare class AllowIfEntIsNotVisibleRule<T extends Ent> implements PrivacyPolicyRule {
80
+ export declare class AllowIfEntIsNotVisibleRule<TEnt extends Ent<TViewer>, TViewer extends Viewer> implements PrivacyPolicyRule {
81
81
  private id;
82
82
  private options;
83
- constructor(id: ID, options: LoadEntOptions<T>);
84
- apply(v: Viewer, _ent?: Ent): Promise<PrivacyResult>;
83
+ constructor(id: ID, options: LoadEntOptions<TEnt, TViewer>);
84
+ apply(v: TViewer, _ent?: Ent): Promise<PrivacyResult>;
85
85
  }
86
- export declare class AllowIfEntIsVisiblePolicy<T extends Ent> implements PrivacyPolicy {
86
+ export declare class AllowIfEntIsVisiblePolicy<TEnt extends Ent<TViewer>, TViewer extends Viewer> implements PrivacyPolicy<TEnt, TViewer> {
87
87
  private id;
88
88
  private options;
89
- constructor(id: ID, options: LoadEntOptions<T>);
89
+ constructor(id: ID, options: LoadEntOptions<TEnt, TViewer>);
90
90
  rules: {
91
- apply(_v: Viewer, _ent?: Ent | undefined): Promise<PrivacyResult>;
91
+ apply(_v: Viewer<Ent<any> | null, ID | null>, _ent?: Ent<Viewer<Ent<any> | null, ID | null>> | undefined): Promise<PrivacyResult>;
92
92
  }[];
93
93
  }
94
- export declare class DenyIfEntIsVisiblePolicy<T extends Ent> implements PrivacyPolicy {
94
+ export declare class DenyIfEntIsVisiblePolicy<TEnt extends Ent<TViewer>, TViewer extends Viewer> implements PrivacyPolicy<TEnt, TViewer> {
95
95
  private id;
96
96
  private options;
97
- constructor(id: ID, options: LoadEntOptions<T>);
97
+ constructor(id: ID, options: LoadEntOptions<TEnt, TViewer>);
98
98
  rules: {
99
- apply(_v: Viewer, _ent?: Ent | undefined): Promise<PrivacyResult>;
99
+ apply(_v: Viewer<Ent<any> | null, ID | null>, _ent?: Ent<Viewer<Ent<any> | null, ID | null>> | undefined): Promise<PrivacyResult>;
100
100
  }[];
101
101
  }
102
- export declare class DenyIfEntIsVisibleRule<T extends Ent> implements PrivacyPolicyRule {
102
+ export declare class DenyIfEntIsVisibleRule<TEnt extends Ent<TViewer>, TViewer extends Viewer> implements PrivacyPolicyRule<TEnt, TViewer> {
103
103
  private id;
104
104
  private options;
105
- constructor(id: ID, options: LoadEntOptions<T>);
106
- apply(v: Viewer, _ent?: Ent): Promise<PrivacyResult>;
105
+ constructor(id: ID, options: LoadEntOptions<TEnt, TViewer>);
106
+ apply(v: TViewer, _ent?: Ent): Promise<PrivacyResult>;
107
107
  }
108
- export declare class DenyIfEntIsNotVisibleRule<T extends Ent> implements PrivacyPolicyRule {
108
+ export declare class DenyIfEntIsNotVisibleRule<TEnt extends Ent<TViewer>, TViewer extends Viewer> implements PrivacyPolicyRule {
109
109
  private id;
110
110
  private options;
111
- constructor(id: ID, options: LoadEntOptions<T>);
112
- apply(v: Viewer, _ent?: Ent): Promise<PrivacyResult>;
111
+ constructor(id: ID, options: LoadEntOptions<TEnt, TViewer>);
112
+ apply(v: TViewer, _ent?: Ent): Promise<PrivacyResult>;
113
113
  }
114
114
  export declare class AllowIfEdgeExistsRule implements PrivacyPolicyRule {
115
115
  private id1;
@@ -3,15 +3,15 @@ import { AssocEdge } from "../ent";
3
3
  import { AssocEdgeCountLoaderFactory } from "../loaders/assoc_count_loader";
4
4
  import { AssocEdgeLoaderFactory } from "../loaders/assoc_edge_loader";
5
5
  import { EdgeQuery, BaseEdgeQuery, IDInfo } from "./query";
6
- export declare type EdgeQuerySource<TSource extends Ent, TDest extends Ent = Ent> = TSource | TSource[] | ID | ID[] | EdgeQuery<TDest, Ent, AssocEdge>;
7
- declare type loaderOptionsFunc = (type: string) => LoadEntOptions<Ent>;
8
- export declare abstract class AssocEdgeQueryBase<TSource extends Ent, TDest extends Ent, TEdge extends AssocEdge> extends BaseEdgeQuery<TSource, TDest, TEdge> implements EdgeQuery<TSource, TDest, TEdge> {
9
- viewer: Viewer;
10
- src: EdgeQuerySource<TSource, TDest>;
6
+ export declare type EdgeQuerySource<TSource extends Ent<TViewer>, TDest extends Ent<TViewer> = Ent<any>, TViewer extends Viewer = Viewer> = TSource | TSource[] | ID | ID[] | EdgeQuery<TDest, Ent, AssocEdge>;
7
+ declare type loaderOptionsFunc<TViewer extends Viewer> = (type: string) => LoadEntOptions<Ent, TViewer>;
8
+ export declare abstract class AssocEdgeQueryBase<TSource extends Ent<TViewer>, TDest extends Ent<TViewer>, TEdge extends AssocEdge, TViewer extends Viewer = Viewer> extends BaseEdgeQuery<TSource, TDest, TEdge> implements EdgeQuery<TSource, TDest, TEdge> {
9
+ viewer: TViewer;
10
+ src: EdgeQuerySource<TSource, TDest, TViewer>;
11
11
  private countLoaderFactory;
12
12
  private dataLoaderFactory;
13
13
  private options;
14
- constructor(viewer: Viewer, src: EdgeQuerySource<TSource, TDest>, countLoaderFactory: AssocEdgeCountLoaderFactory, dataLoaderFactory: AssocEdgeLoaderFactory<TEdge>, options: LoadEntOptions<TDest> | loaderOptionsFunc);
14
+ constructor(viewer: TViewer, src: EdgeQuerySource<TSource, TDest, TViewer>, countLoaderFactory: AssocEdgeCountLoaderFactory, dataLoaderFactory: AssocEdgeLoaderFactory<TEdge>, options: LoadEntOptions<TDest, TViewer> | loaderOptionsFunc<TViewer>);
15
15
  private isEdgeQuery;
16
16
  abstract sourceEnt(id: ID): Promise<Ent | null>;
17
17
  private getSingleID;
@@ -1,17 +1,17 @@
1
1
  import { Data, Ent, ID, EdgeQueryableDataOptions, LoadEntOptions, Viewer, LoaderFactory, ConfigurableLoaderFactory } from "../base";
2
2
  import { BaseEdgeQuery, IDInfo, EdgeQuery } from "./query";
3
- export interface CustomEdgeQueryOptions<TSource extends Ent, TDest extends Ent> {
3
+ export interface CustomEdgeQueryOptions<TSource extends Ent<TViewer>, TDest extends Ent<TViewer>, TViewer extends Viewer = Viewer> {
4
4
  src: TSource | ID;
5
5
  countLoaderFactory: LoaderFactory<ID, number>;
6
6
  dataLoaderFactory: ConfigurableLoaderFactory<ID, Data[]>;
7
- options: LoadEntOptions<TDest>;
7
+ options: LoadEntOptions<TDest, TViewer>;
8
8
  sortColumn?: string;
9
9
  }
10
- export declare abstract class CustomEdgeQueryBase<TSource extends Ent, TDest extends Ent> extends BaseEdgeQuery<TSource, TDest, Data> implements EdgeQuery<TSource, TDest, Data> {
11
- viewer: Viewer;
10
+ export declare abstract class CustomEdgeQueryBase<TSource extends Ent<TViewer>, TDest extends Ent<TViewer>, TViewer extends Viewer = Viewer> extends BaseEdgeQuery<TSource, TDest, Data> implements EdgeQuery<TSource, TDest, Data> {
11
+ viewer: TViewer;
12
12
  private options;
13
13
  private id;
14
- constructor(viewer: Viewer, options: CustomEdgeQueryOptions<TSource, TDest>);
14
+ constructor(viewer: TViewer, options: CustomEdgeQueryOptions<TSource, TDest, TViewer>);
15
15
  abstract sourceEnt(id: ID): Promise<Ent | null>;
16
16
  private idVisible;
17
17
  queryRawCount(): Promise<number>;
@@ -41,7 +41,7 @@ export declare abstract class BaseEdgeQuery<TSource extends Ent, TDest extends E
41
41
  private idMap;
42
42
  private idsToFetch;
43
43
  constructor(viewer: Viewer, sortCol: string);
44
- getPrivacyPolicy(): PrivacyPolicy<Ent>;
44
+ getPrivacyPolicy(): PrivacyPolicy<Ent<Viewer<Ent<any> | null, ID | null>>, Viewer<Ent<any> | null, ID | null>>;
45
45
  abstract sourceEnt(id: ID): Promise<Ent | null>;
46
46
  first(n: number, after?: string): this;
47
47
  last(n: number, before?: string): this;
package/core/viewer.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { ID, Ent, Viewer, Context } from "./base";
2
2
  export declare class LoggedOutViewer implements Viewer {
3
- context?: Context | undefined;
4
- constructor(context?: Context | undefined);
3
+ context?: Context<Viewer<Ent<any> | null, ID | null>> | undefined;
4
+ constructor(context?: Context<Viewer<Ent<any> | null, ID | null>> | undefined);
5
5
  viewerID: null;
6
6
  viewer(): Promise<null>;
7
7
  instanceKey(): string;
@@ -18,6 +18,6 @@ export declare class IDViewer implements Viewer {
18
18
  constructor(viewerID: ID, opts?: Partial<IDViewerOptions>);
19
19
  constructor(opts: IDViewerOptions);
20
20
  setContext(ctx: Context): this;
21
- viewer(): Promise<Ent | null>;
21
+ viewer(): Promise<Ent<Viewer<Ent<any> | null, ID | null>> | null>;
22
22
  instanceKey(): string;
23
23
  }
@@ -1,30 +1,30 @@
1
1
  import { EdgeQuery, PaginationInfo } from "../../core/query/query";
2
- import { Data, Ent, Viewer } from "../../core/base";
2
+ import { Data, Ent, ID, Viewer } from "../../core/base";
3
3
  export interface GraphQLEdge<T extends Data> {
4
4
  edge: T;
5
5
  node: Ent;
6
6
  cursor: string;
7
7
  }
8
- interface edgeQueryCtr<T extends Ent, TEdge extends Data> {
9
- (v: Viewer, src: T): EdgeQuery<T, Ent, TEdge>;
8
+ interface edgeQueryCtr<T extends Ent, TEdge extends Data, TViewer extends Viewer> {
9
+ (v: TViewer, src: T): EdgeQuery<T, Ent, TEdge>;
10
10
  }
11
- interface edgeQueryCtr2<T extends Ent, TEdge extends Data> {
12
- (v: Viewer): EdgeQuery<T, Ent, TEdge>;
11
+ interface edgeQueryCtr2<T extends Ent, TEdge extends Data, TViewer extends Viewer> {
12
+ (v: TViewer): EdgeQuery<T, Ent, TEdge>;
13
13
  }
14
- export declare class GraphQLEdgeConnection<TSource extends Ent, TEdge extends Data> {
14
+ export declare class GraphQLEdgeConnection<TSource extends Ent, TEdge extends Data, TViewer extends Viewer = Viewer> {
15
15
  query: EdgeQuery<TSource, Ent, TEdge>;
16
16
  private results;
17
17
  private viewer;
18
18
  private source?;
19
19
  private args?;
20
- constructor(viewer: Viewer, source: TSource, getQuery: edgeQueryCtr<TSource, TEdge>, args?: Data);
21
- constructor(viewer: Viewer, getQuery: edgeQueryCtr2<TSource, TEdge>, args?: Data);
20
+ constructor(viewer: TViewer, source: TSource, getQuery: edgeQueryCtr<TSource, TEdge, TViewer>, args?: Data);
21
+ constructor(viewer: TViewer, getQuery: edgeQueryCtr2<TSource, TEdge, TViewer>, args?: Data);
22
22
  first(limit: number, cursor?: string): void;
23
23
  last(limit: number, cursor?: string): void;
24
24
  modifyQuery(fn: (query: EdgeQuery<TSource, Ent, TEdge>) => EdgeQuery<TSource, Ent, TEdge>): void;
25
25
  queryTotalCount(): Promise<number>;
26
26
  queryEdges(): Promise<GraphQLEdge<TEdge>[]>;
27
- queryNodes(): Promise<Ent[]>;
27
+ queryNodes(): Promise<Ent<Viewer<Ent<any> | null, ID | null>>[]>;
28
28
  private defaultPageInfo;
29
29
  queryPageInfo(): Promise<PaginationInfo>;
30
30
  private queryData;
@@ -1,4 +1,4 @@
1
1
  import { GraphQLObjectType } from "graphql";
2
2
  import { RequestContext } from "../../core/context";
3
3
  import { PaginationInfo } from "../../core/query/query";
4
- export declare const GraphQLPageInfo: GraphQLObjectType<PaginationInfo, RequestContext>;
4
+ export declare const GraphQLPageInfo: GraphQLObjectType<PaginationInfo, RequestContext<import("../..").Viewer<import("../..").Ent<any> | null, import("../..").ID | null>>>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@snowtop/ent",
3
- "version": "0.1.0-alpha13",
3
+ "version": "0.1.0-alpha16",
4
4
  "description": "snowtop ent framework",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -24,6 +24,7 @@ declare type ProcessedSchema = Omit<Schema, "edges" | "actions" | "edgeGroups" |
24
24
  assocEdgeGroups: ProcessedAssocEdgeGroup[];
25
25
  fields: ProcessedField[];
26
26
  schemaPath?: string;
27
+ patternNames?: string[];
27
28
  };
28
29
  declare type ProcessedAssocEdgeGroup = Omit<AssocEdgeGroup, "edgeAction"> & {
29
30
  edgeAction?: OutputAction;
@@ -38,6 +39,7 @@ interface ProcessedPattern {
38
39
  name: string;
39
40
  assocEdges: ProcessedAssocEdge[];
40
41
  fields: ProcessedField[];
42
+ disableMixin?: boolean;
41
43
  }
42
44
  declare type ProcessedType = Omit<Type, "subFields" | "listElemType" | "unionFields"> & {
43
45
  subFields?: ProcessedField[];
@@ -130,6 +130,7 @@ function processPattern(patterns, pattern, processedSchema) {
130
130
  name: pattern.name,
131
131
  assocEdges: edges,
132
132
  fields: fields,
133
+ disableMixin: pattern.disableMixin,
133
134
  };
134
135
  }
135
136
  else {
@@ -202,9 +203,11 @@ function parseSchema(potentialSchemas) {
202
203
  };
203
204
  // let's put patterns first just so we have id, created_at, updated_at first
204
205
  // ¯\_(ツ)_/¯
206
+ let patternNames = [];
205
207
  if (schema.patterns) {
206
208
  for (const pattern of schema.patterns) {
207
209
  const ret = processPattern(patterns, pattern, processedSchema);
210
+ patternNames.push(pattern.name);
208
211
  if (ret.transformsSelect) {
209
212
  if (processedSchema.transformsSelect) {
210
213
  throw new Error(`can only have one pattern which transforms default querying behavior`);
@@ -221,6 +224,7 @@ function parseSchema(potentialSchemas) {
221
224
  }
222
225
  const fields = processFields(schema.fields);
223
226
  processedSchema.fields.push(...fields);
227
+ processedSchema.patternNames = patternNames;
224
228
  if (schema.edges) {
225
229
  const edges = processEdges(schema.edges);
226
230
  processedSchema.assocEdges.push(...edges);
@@ -66,6 +66,7 @@ let nodeFieldsWithTZ = {
66
66
  exports.Node = {
67
67
  name: "node",
68
68
  fields: nodeFields,
69
+ disableMixin: true,
69
70
  };
70
71
  // Ent schema. has Node Pattern by default.
71
72
  // exists just to have less typing and easier for clients to implement
@@ -95,6 +96,7 @@ class EntSchemaWithTZ {
95
96
  // default schema added
96
97
  name: "nodeWithTZ",
97
98
  fields: nodeFieldsWithTZ,
99
+ disableMixin: true,
98
100
  },
99
101
  ];
100
102
  this.fields = cfg.fields;
@@ -131,6 +133,7 @@ class BaseEntSchemaWithTZ {
131
133
  // default schema added
132
134
  name: "nodeWithTZ",
133
135
  fields: nodeFieldsWithTZ,
136
+ disableMixin: true,
134
137
  },
135
138
  ];
136
139
  }
@@ -69,6 +69,7 @@ export declare type Edge = AssocEdge;
69
69
  export interface Pattern {
70
70
  name: string;
71
71
  fields: FieldMap | Field[];
72
+ disableMixin?: boolean;
72
73
  edges?: Edge[];
73
74
  transformRead?: () => Clause;
74
75
  transformWrite?: <T extends Ent>(stmt: UpdateOperation<T>) => TransformedUpdateOperation<T> | null;
@@ -122,12 +122,11 @@ function main() {
122
122
  (0, child_process_1.execSync)("prettier src/graphql/*.ts --write");
123
123
  }
124
124
  function isGeneratedPath(node, sourceFile, dirPath) {
125
- const text = node.moduleSpecifier.getText(sourceFile).slice(1, -1);
126
125
  // it's relative and has generated in there, continue
127
- if (!((text.startsWith("..") || text.startsWith("./")) &&
128
- text.indexOf("/generated") !== -1)) {
126
+ if (!(0, ast_1.isRelativeGeneratedImport)(node, sourceFile)) {
129
127
  return;
130
128
  }
129
+ const text = node.moduleSpecifier.getText(sourceFile).slice(1, -1);
131
130
  const oldPath = path.join(dirPath, text);
132
131
  const relFromRoot = path.relative(".", oldPath);
133
132
  const conv = transformPath(relFromRoot);
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,266 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
8
+ }));
9
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
10
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
11
+ }) : function(o, v) {
12
+ o["default"] = v;
13
+ });
14
+ var __importStar = (this && this.__importStar) || function (mod) {
15
+ if (mod && mod.__esModule) return mod;
16
+ var result = {};
17
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18
+ __setModuleDefault(result, mod);
19
+ return result;
20
+ };
21
+ var __importDefault = (this && this.__importDefault) || function (mod) {
22
+ return (mod && mod.__esModule) ? mod : { "default": mod };
23
+ };
24
+ Object.defineProperty(exports, "__esModule", { value: true });
25
+ const glob_1 = require("glob");
26
+ const typescript_1 = __importDefault(require("typescript"));
27
+ const compilerOptions_1 = require("../tsc/compilerOptions");
28
+ const ast_1 = require("../tsc/ast");
29
+ const child_process_1 = require("child_process");
30
+ const fs = __importStar(require("fs"));
31
+ const action_1 = require("../action");
32
+ const viewer_1 = require("../core/viewer");
33
+ const path = __importStar(require("path"));
34
+ const js_yaml_1 = require("js-yaml");
35
+ function transformRelative(file, importPath, relative) {
36
+ if (!relative || !importPath.startsWith("src")) {
37
+ return importPath;
38
+ }
39
+ const fileFullPath = path.join(process.cwd(), file);
40
+ const impFullPath = path.join(process.cwd(), importPath);
41
+ // relative path is from directory
42
+ return normalizePath(path.relative(path.dirname(fileFullPath), impFullPath));
43
+ }
44
+ function normalizePath(p) {
45
+ if (p.endsWith("..")) {
46
+ return p + "/";
47
+ }
48
+ return p;
49
+ }
50
+ function findInput(file, sourceFile) {
51
+ // @ts-ignore
52
+ const importStatements = sourceFile.statements.filter((stmt) => typescript_1.default.isImportDeclaration(stmt));
53
+ for (const imp of importStatements) {
54
+ const text = imp.moduleSpecifier.getText(sourceFile).slice(1, -1);
55
+ if ((0, ast_1.isRelativeGeneratedImport)(imp, sourceFile)) {
56
+ // base file and we're importing from it
57
+ // e.g. in create_user_action, we're importing from create_user_action_base
58
+ if (path.basename(file).slice(0, -3) + "_base" !== path.basename(text)) {
59
+ continue;
60
+ }
61
+ const impInfo = (0, ast_1.getImportInfo)(imp, sourceFile);
62
+ if (!impInfo) {
63
+ continue;
64
+ }
65
+ const inputs = impInfo.imports
66
+ .filter((imp) => imp.trim() && imp.endsWith("Input"))
67
+ .map((v) => v.trim());
68
+ if (inputs.length === 1) {
69
+ return inputs[0];
70
+ }
71
+ }
72
+ }
73
+ return null;
74
+ }
75
+ function getCustomInfo() {
76
+ let yaml = {};
77
+ let relativeImports = false;
78
+ try {
79
+ yaml = (0, js_yaml_1.load)(fs.readFileSync(path.join(process.cwd(), "ent.yml"), {
80
+ encoding: "utf8",
81
+ }));
82
+ relativeImports = yaml?.codegen?.relativeImports || false;
83
+ if (yaml?.codegen?.templatizedViewer) {
84
+ return {
85
+ viewerInfo: yaml.codegen.templatizedViewer,
86
+ relativeImports,
87
+ };
88
+ }
89
+ }
90
+ catch (e) { }
91
+ return {
92
+ viewerInfo: {
93
+ path: "@snowtop/ent",
94
+ name: "Viewer",
95
+ },
96
+ relativeImports,
97
+ };
98
+ }
99
+ async function main() {
100
+ let files = glob_1.glob.sync("src/ent/**/actions/**/*_action.ts");
101
+ const target = (0, compilerOptions_1.getTargetFromCurrentDir)();
102
+ const customInfo = getCustomInfo();
103
+ const viewerInfo = customInfo.viewerInfo;
104
+ files.forEach((file) => {
105
+ let { contents, sourceFile } = (0, compilerOptions_1.createSourceFile)(target, file);
106
+ let traversed = false;
107
+ let nodes = [];
108
+ // require action
109
+ const p = require(path.join(process.cwd(), "./" + file.slice(0, -3)));
110
+ const action = new p.default(new viewer_1.LoggedOutViewer(), {});
111
+ const builder = action.builder.constructor.name;
112
+ const nodeName = action.builder.ent.name;
113
+ const existingEnt = action.builder.operation === action_1.WriteOperation.Insert
114
+ ? `${nodeName} | null`
115
+ : nodeName;
116
+ const viewer = customInfo.viewerInfo.name;
117
+ const input = findInput(file, sourceFile);
118
+ if (!input) {
119
+ return;
120
+ }
121
+ let newImports = [];
122
+ typescript_1.default.forEachChild(sourceFile, function (node) {
123
+ if (!typescript_1.default.isClassDeclaration(node) || !node.heritageClauses) {
124
+ nodes.push({ node });
125
+ return;
126
+ }
127
+ let classInfo = (0, ast_1.getClassInfo)(contents, sourceFile, node);
128
+ // only do classes
129
+ if (!classInfo) {
130
+ return;
131
+ }
132
+ let klassContents = "";
133
+ for (const mm of node.members) {
134
+ const conv = getConversionInfo(mm);
135
+ if (conv !== null) {
136
+ const property = mm;
137
+ // if invalid, bounce
138
+ if (!property.initializer) {
139
+ traversed = false;
140
+ return;
141
+ }
142
+ traversed = true;
143
+ const pp = property.initializer.getFullText(sourceFile).trim();
144
+ const code = `${conv.method}(): ${conv.interface}<${nodeName}, ${builder}<${input}, ${existingEnt}>, ${viewer}, ${input}, ${existingEnt}>[] {
145
+ return ${pp}
146
+ }`;
147
+ newImports.push(conv.interface);
148
+ klassContents += (0, ast_1.getPreText)(contents, mm, sourceFile) + code;
149
+ }
150
+ else {
151
+ klassContents += mm.getFullText(sourceFile);
152
+ }
153
+ }
154
+ // wrap comments and transform to export class Foo extends Bar { ${inner} }
155
+ nodes.push({ rawString: classInfo.wrapClassContents(klassContents) });
156
+ });
157
+ // if traversed, overwrite.
158
+ if (!traversed) {
159
+ return;
160
+ }
161
+ let newContents = "";
162
+ let afterProcessed = false;
163
+ let imports = new Map([
164
+ [
165
+ transformRelative(file, viewerInfo.path, customInfo.relativeImports),
166
+ [viewer],
167
+ ],
168
+ [
169
+ transformRelative(file, "src/ent", customInfo.relativeImports),
170
+ [nodeName],
171
+ ],
172
+ ["@snowtop/ent/action", newImports],
173
+ ]);
174
+ let seen = new Map();
175
+ const processAfterImport = () => {
176
+ // do this for the first non-import node we see
177
+ // we want to add new imports to end of imports and there's an assumption that imports are ordered
178
+ // at top of file
179
+ if (!afterProcessed) {
180
+ for (const [imp, list] of imports) {
181
+ if (seen.has(imp)) {
182
+ continue;
183
+ }
184
+ newContents += `\nimport { ${list.join(", ")} } from "${imp}"`;
185
+ }
186
+ afterProcessed = true;
187
+ }
188
+ };
189
+ for (const node of nodes) {
190
+ if (node.node) {
191
+ if (typescript_1.default.isImportDeclaration(node.node)) {
192
+ const impInfo = (0, ast_1.getImportInfo)(node.node, sourceFile);
193
+ if (impInfo) {
194
+ const impPath = normalizePath(impInfo.importPath);
195
+ // normalize paths...
196
+ const list = imports.get(impPath);
197
+ if (list) {
198
+ let transformed = (0, ast_1.transformImport)(contents, node.node, sourceFile, {
199
+ newImports: list,
200
+ // don't use normalized path here, we wanna use the path that's in code...
201
+ transformPath: impInfo.importPath,
202
+ });
203
+ if (transformed) {
204
+ newContents += transformed;
205
+ seen.set(impPath, true);
206
+ continue;
207
+ }
208
+ }
209
+ }
210
+ }
211
+ else {
212
+ if (!typescript_1.default.isExportDeclaration(node.node)) {
213
+ processAfterImport();
214
+ }
215
+ }
216
+ newContents += node.node.getFullText(sourceFile);
217
+ }
218
+ else if (node.rawString) {
219
+ processAfterImport();
220
+ newContents += node.rawString;
221
+ }
222
+ else {
223
+ throw new Error(`malformed node with no node or rawString`);
224
+ }
225
+ fs.writeFileSync(file, newContents);
226
+ }
227
+ });
228
+ (0, child_process_1.execSync)("prettier src/ent/**/actions/**/*.ts --write");
229
+ }
230
+ let m = {
231
+ triggers: {
232
+ m: "getTriggers",
233
+ i: "Trigger",
234
+ },
235
+ observers: {
236
+ m: "getObservers",
237
+ i: "Observer",
238
+ },
239
+ validators: {
240
+ m: "getValidators",
241
+ i: "Validator",
242
+ },
243
+ };
244
+ function getConversionInfo(mm) {
245
+ if (mm.kind !== typescript_1.default.SyntaxKind.PropertyDeclaration) {
246
+ return null;
247
+ }
248
+ const text = mm.name.escapedText;
249
+ const v = m[text];
250
+ if (v === undefined) {
251
+ return null;
252
+ }
253
+ return {
254
+ text,
255
+ method: v.m,
256
+ interface: v.i,
257
+ };
258
+ }
259
+ main()
260
+ .then(() => {
261
+ process.exit(0);
262
+ })
263
+ .catch((err) => {
264
+ console.error(err);
265
+ process.exit(1);
266
+ });
@@ -45,7 +45,6 @@ async function main() {
45
45
  if (!classInfo || classInfo.extends !== classInfo.name + "Base") {
46
46
  return;
47
47
  }
48
- // need to check for PrivacyPolicy import...
49
48
  traversed = true;
50
49
  let klassContents = "";
51
50
  for (const mm of node.members) {
@@ -60,7 +59,7 @@ async function main() {
60
59
  const code = `getPrivacyPolicy(): PrivacyPolicy<this> {
61
60
  return ${pp}
62
61
  }`;
63
- klassContents += code;
62
+ klassContents += (0, ast_1.getPreText)(contents, mm, sourceFile) + code;
64
63
  }
65
64
  else {
66
65
  klassContents += mm.getFullText(sourceFile);
@@ -68,7 +67,6 @@ async function main() {
68
67
  }
69
68
  // wrap comments and transform to export class Foo extends Bar { ${inner} }
70
69
  nodes.push({ rawString: classInfo.wrapClassContents(klassContents) });
71
- // console.debug(classInfo.wrapClassContents(klassContents));
72
70
  });
73
71
  // if traversed, overwrite.
74
72
  if (!traversed) {
@@ -77,12 +77,13 @@ export declare class SimpleBuilder<T extends Ent, TExistingEnt extends TMaybleNu
77
77
  existingEnt: TExistingEnt;
78
78
  ent: EntConstructor<T>;
79
79
  placeholderID: ID;
80
- orchestrator: Orchestrator<T, Data>;
80
+ orchestrator: Orchestrator<T, Data, Viewer>;
81
81
  fields: Map<string, any>;
82
82
  nodeType: string;
83
- constructor(viewer: Viewer, schema: BuilderSchema<T>, fields: Map<string, any>, operation: WriteOperation, existingEnt: TExistingEnt, action?: Action<T, SimpleBuilder<T>, Data> | undefined);
83
+ constructor(viewer: Viewer, schema: BuilderSchema<T>, fields: Map<string, any>, operation: WriteOperation, existingEnt: TExistingEnt, action?: Action<T, SimpleBuilder<T>, Viewer, Data> | undefined);
84
+ getInput(): Data;
84
85
  updateInput(input: Data): void;
85
- build(): Promise<Changeset<T>>;
86
+ build(): Promise<Changeset>;
86
87
  editedEnt(): Promise<T | null>;
87
88
  editedEntX(): Promise<T>;
88
89
  save(): Promise<void>;
@@ -93,18 +94,18 @@ export declare class SimpleBuilder<T extends Ent, TExistingEnt extends TMaybleNu
93
94
  interface viewerEntLoadFunc {
94
95
  (data: Data): Viewer | Promise<Viewer>;
95
96
  }
96
- export declare class SimpleAction<T extends Ent, TExistingEnt extends TMaybleNullableEnt<T> = MaybeNull<T>> implements Action<T, SimpleBuilder<T, TExistingEnt>, Data, TExistingEnt> {
97
+ export declare class SimpleAction<T extends Ent, TExistingEnt extends TMaybleNullableEnt<T> = MaybeNull<T>> implements Action<T, SimpleBuilder<T, TExistingEnt>, Viewer, Data, TExistingEnt> {
97
98
  viewer: Viewer;
98
99
  private fields;
99
100
  builder: SimpleBuilder<T, TExistingEnt>;
100
- validators: Validator<T, SimpleBuilder<T>, Data>[];
101
- triggers: Trigger<T, SimpleBuilder<T>, Data>[];
102
- observers: Observer<T, SimpleBuilder<T>, Data>[];
103
101
  viewerForEntLoad: viewerEntLoadFunc | undefined;
104
102
  constructor(viewer: Viewer, schema: BuilderSchema<T>, fields: Map<string, any>, operation: WriteOperation | undefined, existingEnt: TExistingEnt);
105
- getPrivacyPolicy(): PrivacyPolicy<Ent>;
103
+ getTriggers(): Trigger<T, SimpleBuilder<T>>[];
104
+ getValidators(): Validator<T, SimpleBuilder<T>>[];
105
+ getObservers(): Observer<T, SimpleBuilder<T>>[];
106
+ getPrivacyPolicy(): PrivacyPolicy<Ent<Viewer<Ent<any> | null, ID | null>>, Viewer<Ent<any> | null, ID | null>>;
106
107
  getInput(): Data;
107
- changeset(): Promise<Changeset<T>>;
108
+ changeset(): Promise<Changeset>;
108
109
  valid(): Promise<boolean>;
109
110
  validX(): Promise<void>;
110
111
  save(): Promise<T | null>;