@zenstackhq/openapi 1.0.0-alpha.99 → 1.0.0-beta.2

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.
@@ -0,0 +1,65 @@
1
+ import { DMMF } from '@prisma/generator-helper';
2
+ import { PluginOptions } from '@zenstackhq/sdk';
3
+ import { Model } from '@zenstackhq/sdk/ast';
4
+ import type { OpenAPIV3_1 as OAPI } from 'openapi-types';
5
+ export declare abstract class OpenAPIGeneratorBase {
6
+ protected model: Model;
7
+ protected options: PluginOptions;
8
+ protected dmmf: DMMF.Document;
9
+ constructor(model: Model, options: PluginOptions, dmmf: DMMF.Document);
10
+ abstract generate(): string[];
11
+ protected get includedModels(): import("@zenstackhq/sdk/ast").DataModel[];
12
+ protected wrapArray(schema: OAPI.ReferenceObject | OAPI.SchemaObject, isArray: boolean): OAPI.ReferenceObject | OAPI.SchemaObject;
13
+ protected array(itemType: OAPI.SchemaObject | OAPI.ReferenceObject): {
14
+ readonly type: "array";
15
+ readonly items: OAPI.ReferenceObject | OAPI.SchemaObject;
16
+ };
17
+ protected oneOf(...schemas: (OAPI.SchemaObject | OAPI.ReferenceObject)[]): {
18
+ oneOf: (OAPI.ReferenceObject | OAPI.SchemaObject)[];
19
+ };
20
+ protected allOf(...schemas: (OAPI.SchemaObject | OAPI.ReferenceObject)[]): {
21
+ allOf: (OAPI.ReferenceObject | OAPI.SchemaObject)[];
22
+ };
23
+ protected getOption<T = string>(name: string): T | undefined;
24
+ protected getOption<T = string, D extends T = T>(name: string, defaultValue: D): T;
25
+ protected generateSecuritySchemes(): Record<string, {
26
+ type: "http";
27
+ scheme: "basic";
28
+ } | {
29
+ bearerFormat?: string | undefined;
30
+ type: "http";
31
+ scheme: "bearer";
32
+ } | {
33
+ type: "apiKey";
34
+ in: "header" | "query" | "cookie";
35
+ name: string;
36
+ } | {
37
+ type: "oauth2";
38
+ description: string;
39
+ flows: {
40
+ authorizationCode: {
41
+ authorizationUrl: string;
42
+ tokenUrl: string;
43
+ refreshUrl: string;
44
+ scopes: Record<string, string>;
45
+ };
46
+ implicit: {
47
+ authorizationUrl: string;
48
+ refreshUrl: string;
49
+ scopes: Record<string, string>;
50
+ };
51
+ password: {
52
+ tokenUrl: string;
53
+ refreshUrl: string;
54
+ scopes: Record<string, string>;
55
+ };
56
+ clientCredentials: {
57
+ tokenUrl: string;
58
+ refreshUrl: string;
59
+ scopes: Record<string, string>;
60
+ };
61
+ };
62
+ }> | undefined;
63
+ protected pruneComponents(paths: OAPI.PathsObject, components: OAPI.ComponentsObject): void;
64
+ private collectUsedComponents;
65
+ }
@@ -0,0 +1,103 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OpenAPIGeneratorBase = void 0;
4
+ const sdk_1 = require("@zenstackhq/sdk");
5
+ const zod_validation_error_1 = require("zod-validation-error");
6
+ const schema_1 = require("./schema");
7
+ class OpenAPIGeneratorBase {
8
+ constructor(model, options, dmmf) {
9
+ this.model = model;
10
+ this.options = options;
11
+ this.dmmf = dmmf;
12
+ }
13
+ get includedModels() {
14
+ return (0, sdk_1.getDataModels)(this.model).filter((d) => !(0, sdk_1.hasAttribute)(d, '@@openapi.ignore'));
15
+ }
16
+ wrapArray(schema, isArray) {
17
+ if (isArray) {
18
+ return { type: 'array', items: schema };
19
+ }
20
+ else {
21
+ return schema;
22
+ }
23
+ }
24
+ array(itemType) {
25
+ return { type: 'array', items: itemType };
26
+ }
27
+ oneOf(...schemas) {
28
+ return { oneOf: schemas };
29
+ }
30
+ allOf(...schemas) {
31
+ return { allOf: schemas };
32
+ }
33
+ getOption(name, defaultValue) {
34
+ const value = this.options[name];
35
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
36
+ // @ts-expect-error
37
+ return value === undefined ? defaultValue : value;
38
+ }
39
+ generateSecuritySchemes() {
40
+ const securitySchemes = this.getOption('securitySchemes');
41
+ if (securitySchemes) {
42
+ const parsed = schema_1.SecuritySchemesSchema.safeParse(securitySchemes);
43
+ if (!parsed.success) {
44
+ throw new sdk_1.PluginError(this.options.name, `"securitySchemes" option is invalid: ${(0, zod_validation_error_1.fromZodError)(parsed.error)}`);
45
+ }
46
+ return parsed.data;
47
+ }
48
+ return undefined;
49
+ }
50
+ pruneComponents(paths, components) {
51
+ const schemas = components.schemas;
52
+ if (schemas) {
53
+ const roots = new Set();
54
+ for (const path of Object.values(paths)) {
55
+ this.collectUsedComponents(path, roots);
56
+ }
57
+ // build a transitive closure for all reachable schemas from roots
58
+ const allUsed = new Set(roots);
59
+ let todo = [...allUsed];
60
+ while (todo.length > 0) {
61
+ const curr = new Set(allUsed);
62
+ Object.entries(schemas)
63
+ .filter(([key]) => todo.includes(key))
64
+ .forEach(([, value]) => {
65
+ this.collectUsedComponents(value, allUsed);
66
+ });
67
+ todo = [...allUsed].filter((e) => !curr.has(e));
68
+ }
69
+ // prune unused schemas
70
+ Object.keys(schemas).forEach((key) => {
71
+ if (!allUsed.has(key)) {
72
+ delete schemas[key];
73
+ }
74
+ });
75
+ }
76
+ }
77
+ collectUsedComponents(value, allUsed) {
78
+ if (!value) {
79
+ return;
80
+ }
81
+ if (Array.isArray(value)) {
82
+ value.forEach((item) => {
83
+ this.collectUsedComponents(item, allUsed);
84
+ });
85
+ }
86
+ else if (typeof value === 'object') {
87
+ Object.entries(value).forEach(([subKey, subValue]) => {
88
+ if (subKey === '$ref') {
89
+ const ref = subValue;
90
+ const name = ref.split('/').pop();
91
+ if (name && !allUsed.has(name)) {
92
+ allUsed.add(name);
93
+ }
94
+ }
95
+ else {
96
+ this.collectUsedComponents(subValue, allUsed);
97
+ }
98
+ });
99
+ }
100
+ }
101
+ }
102
+ exports.OpenAPIGeneratorBase = OpenAPIGeneratorBase;
103
+ //# sourceMappingURL=generator-base.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generator-base.js","sourceRoot":"","sources":["../src/generator-base.ts"],"names":[],"mappings":"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"}
package/index.js CHANGED
@@ -10,11 +10,21 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.name = void 0;
13
- const generator_1 = require("./generator");
13
+ const sdk_1 = require("@zenstackhq/sdk");
14
+ const rest_generator_1 = require("./rest-generator");
15
+ const rpc_generator_1 = require("./rpc-generator");
14
16
  exports.name = 'OpenAPI';
15
17
  function run(model, options, dmmf) {
16
18
  return __awaiter(this, void 0, void 0, function* () {
17
- return new generator_1.OpenAPIGenerator(model, options, dmmf).generate();
19
+ const flavor = options.flavor ? options.flavor : 'rpc';
20
+ switch (flavor) {
21
+ case 'rest':
22
+ return new rest_generator_1.RESTfulOpenAPIGenerator(model, options, dmmf).generate();
23
+ case 'rpc':
24
+ return new rpc_generator_1.RPCOpenAPIGenerator(model, options, dmmf).generate();
25
+ default:
26
+ throw new sdk_1.PluginError(exports.name, `Unknown flavor: ${flavor}`);
27
+ }
18
28
  });
19
29
  }
20
30
  exports.default = run;
package/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;AAGA,2CAA+C;AAElC,QAAA,IAAI,GAAG,SAAS,CAAC;AAE9B,SAA8B,GAAG,CAAC,KAAY,EAAE,OAAsB,EAAE,IAAmB;;QACvF,OAAO,IAAI,4BAAgB,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC;IACjE,CAAC;CAAA;AAFD,sBAEC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;AACA,yCAA6D;AAE7D,qDAA2D;AAC3D,mDAAsD;AAEzC,QAAA,IAAI,GAAG,SAAS,CAAC;AAE9B,SAA8B,GAAG,CAAC,KAAY,EAAE,OAAsB,EAAE,IAAmB;;QACvF,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAE,OAAO,CAAC,MAAiB,CAAC,CAAC,CAAC,KAAK,CAAC;QAEnE,QAAQ,MAAM,EAAE;YACZ,KAAK,MAAM;gBACP,OAAO,IAAI,wCAAuB,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC;YACxE,KAAK,KAAK;gBACN,OAAO,IAAI,mCAAmB,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC;YACpE;gBACI,MAAM,IAAI,iBAAW,CAAC,YAAI,EAAE,mBAAmB,MAAM,EAAE,CAAC,CAAC;SAChE;IACL,CAAC;CAAA;AAXD,sBAWC"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@zenstackhq/openapi",
3
3
  "displayName": "ZenStack Plugin and Runtime for OpenAPI",
4
- "version": "1.0.0-alpha.99",
4
+ "version": "1.0.0-beta.2",
5
5
  "description": "ZenStack plugin and runtime supporting OpenAPI",
6
6
  "main": "index.js",
7
7
  "repository": {
@@ -18,30 +18,34 @@
18
18
  "dependencies": {
19
19
  "@prisma/generator-helper": "^4.7.1",
20
20
  "change-case": "^4.1.2",
21
+ "lower-case-first": "^2.0.2",
21
22
  "openapi-types": "^12.1.0",
22
23
  "tiny-invariant": "^1.3.1",
23
24
  "yaml": "^2.2.1",
24
- "zod": "^3.19.1",
25
+ "zod": "3.21.1",
25
26
  "zod-validation-error": "^0.2.1",
26
- "@zenstackhq/runtime": "1.0.0-alpha.99",
27
- "@zenstackhq/sdk": "1.0.0-alpha.99"
27
+ "@zenstackhq/sdk": "1.0.0-beta.2",
28
+ "@zenstackhq/runtime": "1.0.0-beta.2"
28
29
  },
29
30
  "devDependencies": {
30
31
  "@prisma/internals": "^4.7.1",
31
32
  "@readme/openapi-parser": "^2.4.0",
32
- "@types/jest": "^29.4.0",
33
+ "@types/jest": "^29.5.0",
34
+ "@types/lower-case-first": "^1.0.1",
35
+ "@types/pluralize": "^0.0.29",
33
36
  "@types/tmp": "^0.2.3",
34
37
  "@typescript-eslint/eslint-plugin": "^5.54.0",
35
38
  "@typescript-eslint/parser": "^5.54.0",
36
39
  "copyfiles": "^2.4.1",
37
40
  "eslint": "^8.35.0",
38
- "jest": "^29.4.3",
41
+ "jest": "^29.5.0",
42
+ "pluralize": "^8.0.0",
39
43
  "rimraf": "^3.0.2",
40
44
  "tmp": "^0.2.1",
41
45
  "ts-jest": "^29.0.5",
42
46
  "typescript": "^4.9.5",
43
- "@zenstackhq/testtools": "1.0.0-alpha.99",
44
- "zenstack": "1.0.0-alpha.99"
47
+ "@zenstackhq/testtools": "1.0.0-beta.2",
48
+ "zenstack": "1.0.0-beta.2"
45
49
  },
46
50
  "scripts": {
47
51
  "clean": "rimraf dist",
package/plugin.zmodel CHANGED
@@ -1,9 +1,9 @@
1
- /*
1
+ /**
2
2
  * Mark a data model to be ignored when generating OpenAPI specification.
3
3
  */
4
4
  attribute @@openapi.ignore()
5
5
 
6
- /*
6
+ /**
7
7
  * Provide metadata for a data model for generating OpenAPI specification.
8
8
  */
9
9
  attribute @@openapi.meta(_ meta: Object)
@@ -0,0 +1,36 @@
1
+ import { OpenAPIGeneratorBase } from './generator-base';
2
+ /**
3
+ * Generates RESTful style OpenAPI specification.
4
+ */
5
+ export declare class RESTfulOpenAPIGenerator extends OpenAPIGeneratorBase {
6
+ private warnings;
7
+ generate(): string[];
8
+ private generatePaths;
9
+ private generatePathsForModel;
10
+ private makeResourceList;
11
+ private makeResourceCreate;
12
+ private makeResourceFetch;
13
+ private makeRelatedFetch;
14
+ private makeResourceUpdate;
15
+ private makeResourceDelete;
16
+ private makeRelationshipFetch;
17
+ private makeRelationshipCreate;
18
+ private makeRelationshipUpdate;
19
+ private generateFilterParameters;
20
+ private makeFilterParameter;
21
+ private generateComponents;
22
+ private generateSharedComponents;
23
+ private generateParameters;
24
+ private generateEnumComponent;
25
+ private generateDataModelComponents;
26
+ private generateModelEntity;
27
+ private generateField;
28
+ private get specVersion();
29
+ private fieldTypeToOpenAPISchema;
30
+ private ref;
31
+ private nullable;
32
+ private parameter;
33
+ private forbidden;
34
+ private notFound;
35
+ private success;
36
+ }