@kollors/deep-json-server 1.0.0-alpha.1 → 1.0.0-alpha.11

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 (244) hide show
  1. package/README.md +522 -179
  2. package/README.ru.md +525 -180
  3. package/dist/bin/deep-json-server.js +1 -1
  4. package/dist/bin/deep-json-server.js.map +1 -1
  5. package/dist/index.d.ts +13 -6
  6. package/dist/index.js +4 -1
  7. package/dist/index.js.map +1 -1
  8. package/dist/src/auth/contract.d.ts +31 -0
  9. package/dist/src/auth/contract.js +12 -0
  10. package/dist/src/auth/contract.js.map +1 -0
  11. package/dist/src/auth/input.d.ts +18 -0
  12. package/dist/src/auth/input.js +34 -0
  13. package/dist/src/auth/input.js.map +1 -0
  14. package/dist/src/auth/password.d.ts +17 -0
  15. package/dist/src/auth/password.js +41 -0
  16. package/dist/src/auth/password.js.map +1 -0
  17. package/dist/src/auth/public.d.ts +3 -0
  18. package/dist/src/auth/public.js +5 -0
  19. package/dist/src/auth/public.js.map +1 -0
  20. package/dist/src/auth/routes.d.ts +6 -0
  21. package/dist/src/auth/routes.js +18 -0
  22. package/dist/src/auth/routes.js.map +1 -0
  23. package/dist/src/auth/service.d.ts +78 -0
  24. package/dist/src/auth/service.js +218 -0
  25. package/dist/src/auth/service.js.map +1 -0
  26. package/dist/src/auth/store.d.ts +26 -0
  27. package/dist/src/auth/store.js +82 -0
  28. package/dist/src/auth/store.js.map +1 -0
  29. package/dist/src/cli/index.d.ts +7 -0
  30. package/dist/src/cli/index.js +113 -0
  31. package/dist/src/cli/index.js.map +1 -0
  32. package/dist/src/core/config-values.d.ts +28 -0
  33. package/dist/src/core/config-values.js +53 -0
  34. package/dist/src/core/config-values.js.map +1 -0
  35. package/dist/src/{constants.d.ts → core/constants.d.ts} +1 -0
  36. package/dist/src/{constants.js → core/constants.js} +1 -0
  37. package/dist/src/core/constants.js.map +1 -0
  38. package/dist/src/core/database.d.ts +48 -0
  39. package/dist/src/{database.js → core/database.js} +36 -14
  40. package/dist/src/core/database.js.map +1 -0
  41. package/dist/src/core/engine.d.ts +53 -0
  42. package/dist/src/core/engine.js +249 -0
  43. package/dist/src/core/engine.js.map +1 -0
  44. package/dist/src/core/errors.d.ts +9 -0
  45. package/dist/src/core/errors.js +12 -0
  46. package/dist/src/core/errors.js.map +1 -0
  47. package/dist/src/core/http-errors.d.ts +9 -0
  48. package/dist/src/core/http-errors.js +15 -0
  49. package/dist/src/core/http-errors.js.map +1 -0
  50. package/dist/src/core/lifecycle/mutation.d.ts +49 -0
  51. package/dist/src/core/lifecycle/mutation.js +170 -0
  52. package/dist/src/core/lifecycle/mutation.js.map +1 -0
  53. package/dist/src/core/lifecycle/options.d.ts +21 -0
  54. package/dist/src/core/lifecycle/options.js +19 -0
  55. package/dist/src/core/lifecycle/options.js.map +1 -0
  56. package/dist/src/core/model.d.ts +145 -0
  57. package/dist/src/{model.js → core/model.js} +224 -33
  58. package/dist/src/core/model.js.map +1 -0
  59. package/dist/src/core/mutations/write.d.ts +26 -0
  60. package/dist/src/core/mutations/write.js +284 -0
  61. package/dist/src/core/mutations/write.js.map +1 -0
  62. package/dist/src/core/operations.d.ts +33 -0
  63. package/dist/src/core/operations.js +10 -0
  64. package/dist/src/core/operations.js.map +1 -0
  65. package/dist/src/core/pagination.d.ts +10 -0
  66. package/dist/src/core/pagination.js +13 -0
  67. package/dist/src/core/pagination.js.map +1 -0
  68. package/dist/src/core/paths.d.ts +16 -0
  69. package/dist/src/core/paths.js +64 -0
  70. package/dist/src/core/paths.js.map +1 -0
  71. package/dist/src/core/query/contract.d.ts +6 -0
  72. package/dist/src/core/query/contract.js +22 -0
  73. package/dist/src/core/query/contract.js.map +1 -0
  74. package/dist/src/core/query/execute.d.ts +25 -0
  75. package/dist/src/core/query/execute.js +82 -0
  76. package/dist/src/core/query/execute.js.map +1 -0
  77. package/dist/src/core/query/filter.d.ts +6 -0
  78. package/dist/src/core/query/filter.js +100 -0
  79. package/dist/src/core/query/filter.js.map +1 -0
  80. package/dist/src/core/query/options.d.ts +30 -0
  81. package/dist/src/core/query/options.js +44 -0
  82. package/dist/src/core/query/options.js.map +1 -0
  83. package/dist/src/core/records.d.ts +46 -0
  84. package/dist/src/core/records.js +69 -0
  85. package/dist/src/core/records.js.map +1 -0
  86. package/dist/src/core/relation-metadata.d.ts +15 -0
  87. package/dist/src/{relation-metadata.js → core/relation-metadata.js} +7 -2
  88. package/dist/src/core/relation-metadata.js.map +1 -0
  89. package/dist/src/core/storage.d.ts +2 -0
  90. package/dist/src/core/storage.js +2 -0
  91. package/dist/src/core/storage.js.map +1 -0
  92. package/dist/src/core/types.d.ts +10 -0
  93. package/dist/src/{types.js.map → core/types.js.map} +1 -1
  94. package/dist/src/core/utils.d.ts +56 -0
  95. package/dist/src/core/utils.js +102 -0
  96. package/dist/src/core/utils.js.map +1 -0
  97. package/dist/src/files/contract.d.ts +32 -30
  98. package/dist/src/files/contract.js +29 -48
  99. package/dist/src/files/contract.js.map +1 -1
  100. package/dist/src/files/disk-metadata.d.ts +9 -0
  101. package/dist/src/files/disk-metadata.js +44 -0
  102. package/dist/src/files/disk-metadata.js.map +1 -0
  103. package/dist/src/files/disk-paths.d.ts +15 -0
  104. package/dist/src/files/disk-paths.js +100 -0
  105. package/dist/src/files/disk-paths.js.map +1 -0
  106. package/dist/src/files/disk-store.d.ts +5 -1
  107. package/dist/src/files/disk-store.js +46 -173
  108. package/dist/src/files/disk-store.js.map +1 -1
  109. package/dist/src/files/http.d.ts +36 -0
  110. package/dist/src/files/http.js +53 -0
  111. package/dist/src/files/http.js.map +1 -0
  112. package/dist/src/files/index.d.ts +5 -4
  113. package/dist/src/files/index.js +7 -2
  114. package/dist/src/files/index.js.map +1 -1
  115. package/dist/src/files/memory-store.d.ts +4 -1
  116. package/dist/src/files/memory-store.js +29 -22
  117. package/dist/src/files/memory-store.js.map +1 -1
  118. package/dist/src/files/routes.d.ts +3 -0
  119. package/dist/src/files/routes.js +27 -2
  120. package/dist/src/files/routes.js.map +1 -1
  121. package/dist/src/files/streams.d.ts +5 -0
  122. package/dist/src/files/streams.js +20 -0
  123. package/dist/src/files/streams.js.map +1 -0
  124. package/dist/src/graphql/entry.d.ts +12 -0
  125. package/dist/src/graphql/entry.js +13 -0
  126. package/dist/src/graphql/entry.js.map +1 -0
  127. package/dist/src/graphql/generate.d.ts +12 -0
  128. package/dist/src/graphql/generate.js +19 -0
  129. package/dist/src/graphql/generate.js.map +1 -0
  130. package/dist/src/graphql/preflight.d.ts +6 -0
  131. package/dist/src/graphql/preflight.js +44 -0
  132. package/dist/src/graphql/preflight.js.map +1 -0
  133. package/dist/src/graphql/resolvers.d.ts +17 -0
  134. package/dist/src/graphql/resolvers.js +44 -0
  135. package/dist/src/graphql/resolvers.js.map +1 -0
  136. package/dist/src/graphql/routes.d.ts +8 -0
  137. package/dist/src/graphql/routes.js +30 -0
  138. package/dist/src/graphql/routes.js.map +1 -0
  139. package/dist/src/graphql/schema.d.ts +6 -0
  140. package/dist/src/{graphql.js → graphql/schema.js} +59 -49
  141. package/dist/src/graphql/schema.js.map +1 -0
  142. package/dist/src/graphql/write.d.ts +4 -0
  143. package/dist/src/graphql/write.js +10 -0
  144. package/dist/src/graphql/write.js.map +1 -0
  145. package/dist/src/openapi/auth.d.ts +13 -0
  146. package/dist/src/openapi/auth.js +139 -0
  147. package/dist/src/openapi/auth.js.map +1 -0
  148. package/dist/src/openapi/document.d.ts +7 -3
  149. package/dist/src/openapi/document.js +154 -103
  150. package/dist/src/openapi/document.js.map +1 -1
  151. package/dist/src/openapi/entry.d.ts +14 -0
  152. package/dist/src/openapi/entry.js +13 -0
  153. package/dist/src/openapi/entry.js.map +1 -0
  154. package/dist/src/openapi/files.d.ts +6 -0
  155. package/dist/src/{files/openapi.js → openapi/files.js} +6 -5
  156. package/dist/src/openapi/files.js.map +1 -0
  157. package/dist/src/openapi/generate.d.ts +19 -0
  158. package/dist/src/openapi/generate.js +41 -0
  159. package/dist/src/openapi/generate.js.map +1 -0
  160. package/dist/src/openapi/helpers.d.ts +26 -0
  161. package/dist/src/openapi/helpers.js +13 -0
  162. package/dist/src/openapi/helpers.js.map +1 -0
  163. package/dist/src/openapi/options.d.ts +18 -0
  164. package/dist/src/openapi/options.js +13 -0
  165. package/dist/src/openapi/options.js.map +1 -0
  166. package/dist/src/openapi/registry.d.ts +11 -0
  167. package/dist/src/openapi/registry.js +20 -0
  168. package/dist/src/openapi/registry.js.map +1 -0
  169. package/dist/src/{types.d.ts → openapi/types.d.ts} +2 -10
  170. package/dist/src/openapi/types.js +2 -0
  171. package/dist/src/openapi/types.js.map +1 -0
  172. package/dist/src/openapi/write.d.ts +5 -0
  173. package/dist/src/openapi/write.js +12 -0
  174. package/dist/src/openapi/write.js.map +1 -0
  175. package/dist/src/rest/options.d.ts +22 -0
  176. package/dist/src/rest/options.js +65 -0
  177. package/dist/src/rest/options.js.map +1 -0
  178. package/dist/src/rest/projection.d.ts +13 -0
  179. package/dist/src/rest/projection.js +61 -0
  180. package/dist/src/rest/projection.js.map +1 -0
  181. package/dist/src/rest/routes.d.ts +7 -0
  182. package/dist/src/rest/routes.js +58 -0
  183. package/dist/src/rest/routes.js.map +1 -0
  184. package/dist/src/server/bootstrap.d.ts +7 -0
  185. package/dist/src/server/bootstrap.js +48 -0
  186. package/dist/src/server/bootstrap.js.map +1 -0
  187. package/dist/src/server/config.d.ts +74 -0
  188. package/dist/src/server/config.js +142 -0
  189. package/dist/src/server/config.js.map +1 -0
  190. package/dist/src/server/create.d.ts +16 -0
  191. package/dist/src/server/create.js +59 -0
  192. package/dist/src/server/create.js.map +1 -0
  193. package/dist/src/server/features.d.ts +4 -0
  194. package/dist/src/server/features.js +11 -0
  195. package/dist/src/server/features.js.map +1 -0
  196. package/dist/src/server/http.d.ts +12 -0
  197. package/dist/src/server/http.js +40 -0
  198. package/dist/src/server/http.js.map +1 -0
  199. package/dist/src/server/model.d.ts +6 -0
  200. package/dist/src/server/model.js +14 -0
  201. package/dist/src/server/model.js.map +1 -0
  202. package/dist/src/server/openapi-options.d.ts +6 -0
  203. package/dist/src/server/openapi-options.js +15 -0
  204. package/dist/src/server/openapi-options.js.map +1 -0
  205. package/dist/src/server/public.d.ts +2 -0
  206. package/dist/src/server/public.js +2 -0
  207. package/dist/src/server/public.js.map +1 -0
  208. package/package.json +19 -3
  209. package/dist/src/cli.d.ts +0 -4
  210. package/dist/src/cli.js +0 -67
  211. package/dist/src/cli.js.map +0 -1
  212. package/dist/src/config.d.ts +0 -68
  213. package/dist/src/config.js +0 -161
  214. package/dist/src/config.js.map +0 -1
  215. package/dist/src/constants.js.map +0 -1
  216. package/dist/src/database.d.ts +0 -21
  217. package/dist/src/database.js.map +0 -1
  218. package/dist/src/engine.d.ts +0 -47
  219. package/dist/src/engine.js +0 -438
  220. package/dist/src/engine.js.map +0 -1
  221. package/dist/src/files/openapi.d.ts +0 -3
  222. package/dist/src/files/openapi.js.map +0 -1
  223. package/dist/src/graphql.d.ts +0 -4
  224. package/dist/src/graphql.js.map +0 -1
  225. package/dist/src/model.d.ts +0 -67
  226. package/dist/src/model.js.map +0 -1
  227. package/dist/src/openapi/index.d.ts +0 -7
  228. package/dist/src/openapi/index.js +0 -26
  229. package/dist/src/openapi/index.js.map +0 -1
  230. package/dist/src/query/filter.d.ts +0 -1
  231. package/dist/src/query/filter.js +0 -84
  232. package/dist/src/query/filter.js.map +0 -1
  233. package/dist/src/query/options.d.ts +0 -31
  234. package/dist/src/query/options.js +0 -135
  235. package/dist/src/query/options.js.map +0 -1
  236. package/dist/src/relation-metadata.d.ts +0 -10
  237. package/dist/src/relation-metadata.js.map +0 -1
  238. package/dist/src/server.d.ts +0 -14
  239. package/dist/src/server.js +0 -166
  240. package/dist/src/server.js.map +0 -1
  241. package/dist/src/utils.d.ts +0 -19
  242. package/dist/src/utils.js +0 -62
  243. package/dist/src/utils.js.map +0 -1
  244. /package/dist/src/{types.js → core/types.js} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/graphql/schema.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ /** Сохраняет текст схемы в UTF-8 с завершающим переводом строки, создавая каталоги.
2
+ * @example writeGraphql('type Query { ok: Boolean }', 'out/schema.graphql') → Promise<void>; файл заканчивается переводом строки.
3
+ */
4
+ export declare function writeGraphql(sdl: string, path: string): Promise<void>;
@@ -0,0 +1,10 @@
1
+ import { mkdir, writeFile } from 'node:fs/promises';
2
+ import { dirname } from 'node:path';
3
+ /** Сохраняет текст схемы в UTF-8 с завершающим переводом строки, создавая каталоги.
4
+ * @example writeGraphql('type Query { ok: Boolean }', 'out/schema.graphql') → Promise<void>; файл заканчивается переводом строки.
5
+ */
6
+ export async function writeGraphql(sdl, path) {
7
+ await mkdir(dirname(path), { recursive: true });
8
+ await writeFile(path, `${sdl}\n`, 'utf8');
9
+ }
10
+ //# sourceMappingURL=write.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"write.js","sourceRoot":"","sources":["../../../src/graphql/write.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,GAAW,EAAE,IAAY;IAC1D,MAAM,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAChD,MAAM,SAAS,CAAC,IAAI,EAAE,GAAG,GAAG,IAAI,EAAE,MAAM,CAAC,CAAC;AAC5C,CAAC"}
@@ -0,0 +1,13 @@
1
+ import type { OpenapiDocument, OpenapiSchema } from './types.js';
2
+ export declare const AUTH_SCHEMAS: Record<string, OpenapiSchema>;
3
+ export declare const AUTH_SECURITY_SCHEMES: {
4
+ AuthBearer: {
5
+ type: string;
6
+ scheme: string;
7
+ description: string;
8
+ };
9
+ };
10
+ /** Создаёт описания управления учётными записями и сессиями с требованиями доступа.
11
+ * @example authOpenapiPaths() → маршруты входа, регистрации, выхода, текущего пользователя, смены пароля и статуса.
12
+ */
13
+ export declare function authOpenapiPaths(): OpenapiDocument['paths'];
@@ -0,0 +1,139 @@
1
+ import { AUTH_PATHS, MAX_PASSWORD_LENGTH, MAX_USERNAME_LENGTH } from '../auth/contract.js';
2
+ import { json, ref, response } from './helpers.js';
3
+ const password = { type: 'string', format: 'password', writeOnly: true, minLength: 1, maxLength: MAX_PASSWORD_LENGTH };
4
+ export const AUTH_SCHEMAS = {
5
+ AuthUser: {
6
+ type: 'object',
7
+ additionalProperties: false,
8
+ required: ['id', 'username', 'isAdmin'],
9
+ properties: { id: { type: 'string' }, username: { type: 'string' }, isAdmin: { type: 'boolean' } },
10
+ },
11
+ AuthCredentialsInput: {
12
+ type: 'object',
13
+ additionalProperties: false,
14
+ required: ['username', 'password'],
15
+ properties: {
16
+ username: { type: 'string', minLength: 1, maxLength: MAX_USERNAME_LENGTH, pattern: '\\S' },
17
+ password,
18
+ },
19
+ },
20
+ AuthPasswordInput: {
21
+ type: 'object',
22
+ additionalProperties: false,
23
+ required: ['newPassword'],
24
+ properties: { currentPassword: { ...password, description: 'Required when changing your own password, including administrators.' }, newPassword: password },
25
+ },
26
+ AuthAdminInput: {
27
+ type: 'object',
28
+ additionalProperties: false,
29
+ required: ['isAdmin'],
30
+ properties: { isAdmin: { type: 'boolean' } },
31
+ },
32
+ AuthSession: {
33
+ type: 'object',
34
+ additionalProperties: false,
35
+ required: ['accessToken', 'expiresIn', 'user'],
36
+ properties: {
37
+ accessToken: { type: 'string' },
38
+ expiresIn: { type: 'integer', minimum: 1 },
39
+ user: ref('AuthUser'),
40
+ },
41
+ },
42
+ AuthSuccess: { type: 'object', additionalProperties: false, required: ['success'], properties: { success: { type: 'boolean' } } },
43
+ };
44
+ export const AUTH_SECURITY_SCHEMES = {
45
+ AuthBearer: {
46
+ type: 'http',
47
+ scheme: 'bearer',
48
+ description: 'Session token returned by POST /auth/login. Required for record mutations and protected auth routes. Login and registration are public.',
49
+ },
50
+ };
51
+ /** Создаёт описания управления учётными записями и сессиями с требованиями доступа.
52
+ * @example authOpenapiPaths() → маршруты входа, регистрации, выхода, текущего пользователя, смены пароля и статуса.
53
+ */
54
+ export function authOpenapiPaths() {
55
+ const unauthorized = response('Invalid credentials or expired session', ref('Error'));
56
+ const invalid = response('Invalid input', ref('Error'));
57
+ const forbidden = response('Insufficient permissions', ref('Error'));
58
+ const missing = response('Auth user not found', ref('Error'));
59
+ const busy = response('Too many simultaneous password operations or sessions', ref('Error'));
60
+ const writeFailed = response('Failed to save auth users; changes were not applied', ref('Error'));
61
+ const userId = { in: 'path', name: 'id', required: true, schema: { type: 'string', minLength: 1 } };
62
+ return {
63
+ [AUTH_PATHS.login]: {
64
+ post: {
65
+ operationId: 'authLogin',
66
+ tags: ['auth'],
67
+ security: [],
68
+ requestBody: { required: true, ...json(ref('AuthCredentialsInput')) },
69
+ responses: { 200: response('Session created', ref('AuthSession')), 400: invalid, 401: unauthorized, 429: busy },
70
+ },
71
+ },
72
+ [AUTH_PATHS.register]: {
73
+ post: {
74
+ operationId: 'authRegister',
75
+ tags: ['auth'],
76
+ security: [],
77
+ description: 'Creates a user with a generated id and isAdmin: false. Does not create a session; use login afterwards. Usernames are case-sensitive and unique.',
78
+ requestBody: { required: true, ...json(ref('AuthCredentialsInput')) },
79
+ responses: { 201: response('User created', ref('AuthUser')), 400: invalid, 409: response('Username already exists', ref('Error')), 429: busy, 500: writeFailed },
80
+ },
81
+ },
82
+ [AUTH_PATHS.me]: {
83
+ get: {
84
+ operationId: 'authMe',
85
+ tags: ['auth'],
86
+ security: [{ AuthBearer: [] }],
87
+ responses: { 200: response('Current auth user', ref('AuthUser')), 401: unauthorized },
88
+ },
89
+ },
90
+ [AUTH_PATHS.logout]: {
91
+ post: {
92
+ operationId: 'authLogout',
93
+ tags: ['auth'],
94
+ security: [{ AuthBearer: [] }],
95
+ responses: { 200: response('Session revoked', ref('AuthSuccess')), 401: unauthorized },
96
+ },
97
+ },
98
+ [AUTH_PATHS.password.replace(':id', '{id}')]: {
99
+ patch: {
100
+ operationId: 'authChangePassword',
101
+ tags: ['auth'],
102
+ security: [{ AuthBearer: [] }],
103
+ parameters: [userId],
104
+ description: 'Users, including administrators, supply currentPassword to change their own password. Administrators may reset ordinary users passwords without currentPassword, but cannot change another administrator password. Success revokes all sessions of the target user.',
105
+ requestBody: { required: true, ...json(ref('AuthPasswordInput')) },
106
+ responses: {
107
+ 200: response('Password changed; user sessions revoked', ref('AuthSuccess')),
108
+ 400: invalid,
109
+ 401: unauthorized,
110
+ 403: forbidden,
111
+ 404: missing,
112
+ 409: response('Password changed during the request', ref('Error')),
113
+ 429: busy,
114
+ 500: writeFailed,
115
+ },
116
+ },
117
+ },
118
+ [AUTH_PATHS.admin.replace(':id', '{id}')]: {
119
+ patch: {
120
+ operationId: 'authChangeAdmin',
121
+ tags: ['auth'],
122
+ security: [{ AuthBearer: [] }],
123
+ parameters: [userId],
124
+ description: 'Only administrators may change isAdmin. The last administrator cannot remove their own status. Existing sessions use the new permissions immediately. An administrator may demote another administrator and then reset their password as an ordinary user.',
125
+ requestBody: { required: true, ...json(ref('AuthAdminInput')) },
126
+ responses: {
127
+ 200: response('Admin status updated', ref('AuthUser')),
128
+ 400: invalid,
129
+ 401: unauthorized,
130
+ 403: forbidden,
131
+ 404: missing,
132
+ 409: response('Cannot remove the last administrator', ref('Error')),
133
+ 500: writeFailed,
134
+ },
135
+ },
136
+ },
137
+ };
138
+ }
139
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../../src/openapi/auth.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,12 @@
1
- import { type Model } from '../model.js';
2
- import type { OpenapiDocument } from '../types.js';
3
- export declare function buildOpenapiDocument({ model, files, pageSize, maxPageSize, info, }: {
1
+ import { type Model } from '../core/model.js';
2
+ import type { OpenapiDocument } from './types.js';
3
+ /** Строит документ с маршрутами и схемами записей, включая выбранные дополнительные маршруты.
4
+ * @example { model, files: true } → документ с paths['/_files/storage'].
5
+ */
6
+ export declare function buildOpenapiDocument({ model, files, auth, pageSize, maxPageSize, info, }: {
4
7
  model: Model;
5
8
  files?: boolean;
9
+ auth?: boolean;
6
10
  pageSize?: number;
7
11
  maxPageSize?: number;
8
12
  info?: Record<string, unknown>;
@@ -1,15 +1,24 @@
1
- import { FILE_HEADERS, FILE_METADATA_SCHEMA, FILE_UPDATE_SCHEMA } from '../files/contract.js';
2
- import { createFilePaths } from '../files/openapi.js';
3
- import { assertApi, nodeName, objectSchema, operationName, valueSchema } from '../model.js';
4
- import { childrenOf, sortableFields } from '../query/options.js';
5
- import { isObject } from '../utils.js';
6
- const ref = (name) => ({ $ref: `#/components/schemas/${name}` });
7
- const json = (schema) => ({ content: { 'application/json': { schema } } });
8
- const response = (description, schema) => ({ description, ...json(schema) });
1
+ import { VERSION } from '../core/constants.js';
2
+ import { assertApi, canonicalNode, nodeName, objectSchema, operationName, relationInputSchema, valueSchema } from '../core/model.js';
3
+ import { MUTATIONS } from '../core/operations.js';
4
+ import { normalizePagination } from '../core/pagination.js';
5
+ import { operatorsFor } from '../core/query/contract.js';
6
+ import { sortableFields } from '../core/query/options.js';
7
+ import { capitalize, isObject } from '../core/utils.js';
8
+ import { FILE_HEADERS, FILE_METADATA_SCHEMA, FILE_UPDATE_SCHEMA } from '../files/http.js';
9
+ import { AUTH_SCHEMAS, AUTH_SECURITY_SCHEMES, authOpenapiPaths } from './auth.js';
10
+ import { createFilePaths } from './files.js';
11
+ import { json, ref, response } from './helpers.js';
12
+ import { OpenapiRegistry } from './registry.js';
13
+ /** Преобразует nullable-значения JSON Schema в представление OpenAPI 3.0, рекурсивно обрабатывая поля и элементы.
14
+ * @example { anyOf: [{ type: 'string' }, { type: 'null' }] } → { type: 'string', nullable: true }.
15
+ */
9
16
  function toOpenapi(schema) {
10
17
  if (Array.isArray(schema.anyOf) && schema.anyOf.some((v) => isObject(v) && v.type === 'null')) {
11
18
  const nonNull = schema.anyOf.find((v) => isObject(v) && v.type !== 'null');
12
19
  const converted = toOpenapi(nonNull);
20
+ if (!converted.type)
21
+ return { anyOf: [converted, { type: 'object', nullable: true, enum: [null] }] };
13
22
  return { ...converted, nullable: true, ...(converted.enum ? { enum: [...converted.enum.filter((value) => value !== null), null] } : {}) };
14
23
  }
15
24
  const result = { ...schema };
@@ -19,28 +28,23 @@ function toOpenapi(schema) {
19
28
  result.items = toOpenapi(schema.items);
20
29
  return result;
21
30
  }
22
- export function buildOpenapiDocument({ model, files = false, pageSize = 10, maxPageSize = 100, info = { title: 'Deep JSON Server API', version: '1.0.0-alpha.1' }, }) {
31
+ /** Строит документ с маршрутами и схемами записей, включая выбранные дополнительные маршруты.
32
+ * @example { model, files: true } → документ с paths['/_files/storage'].
33
+ */
34
+ export function buildOpenapiDocument({ model, files = false, auth = false, pageSize, maxPageSize, info = { title: 'Deep JSON Server API', version: VERSION }, }) {
23
35
  assertApi(model, 'openapi');
24
- const schemas = {
36
+ ({ pageSize, maxPageSize } = normalizePagination({ pageSize, maxPageSize }));
37
+ const registry = new OpenapiRegistry({
25
38
  Error: { type: 'object', properties: { error: { type: 'string' } }, required: ['error'] },
26
39
  Pager: {
27
40
  type: 'object',
28
41
  additionalProperties: false,
29
42
  properties: { page: { type: 'integer', minimum: 1, default: 1 }, pageSize: { type: 'integer', minimum: 1, maximum: maxPageSize, default: pageSize } },
30
43
  },
31
- };
32
- const owners = new Map();
33
- function reserve(name, node) {
34
- if (owners.get(name) === node)
35
- return false;
36
- if (schemas[name])
37
- throw new Error(`OpenAPI schema name collision: ${name}`);
38
- owners.set(name, node);
39
- schemas[name] = {};
40
- return true;
41
- }
42
- function baseField(node) {
43
- const schema = toOpenapi(valueSchema(node));
44
+ });
45
+ const { schemas } = registry;
46
+ const reserve = (name, node) => registry.reserve(name, node);
47
+ function annotate(schema, node) {
44
48
  for (const key of ['description', 'example', 'default', 'readOnly', 'writeOnly'])
45
49
  if (node[key] !== undefined)
46
50
  schema[key] = node[key];
@@ -48,6 +52,9 @@ export function buildOpenapiDocument({ model, files = false, pageSize = 10, maxP
48
52
  schema.readOnly = true;
49
53
  return schema;
50
54
  }
55
+ function baseField(node) {
56
+ return annotate(toOpenapi(valueSchema(node)), node);
57
+ }
51
58
  function annotateInput(schema, node, defaults) {
52
59
  for (const [key, property] of Object.entries(schema.properties ?? {})) {
53
60
  const child = node.children[key];
@@ -56,16 +63,30 @@ export function buildOpenapiDocument({ model, files = false, pageSize = 10, maxP
56
63
  property[attribute] = child[attribute];
57
64
  if (defaults && child.default !== undefined)
58
65
  property.default = child.default;
59
- if (child.base === 'object')
66
+ if (!child.relation && child.base === 'object')
60
67
  annotateInput(child.many ? property.items : property, child, defaults);
61
68
  }
62
69
  return schema;
63
70
  }
71
+ function writeInput(node, mode, root = false, nestedMode = mode) {
72
+ return annotateInput(toOpenapi(objectSchema(node, mode, root, (child) => relationInputSchema(child, nestedInput(child.relation, nestedMode)))), node, mode !== 'update');
73
+ }
74
+ function nestedInput(entity, mode) {
75
+ const name = `${entity.name}Nested${capitalize(mode)}`;
76
+ if (!reserve(name, entity.root))
77
+ return ref(name);
78
+ const existing = writeInput(entity.root, mode === 'replace' ? 'replace' : 'update', true, mode);
79
+ existing.properties ??= {};
80
+ existing.properties[entity.primary] = toOpenapi(valueSchema(entity.fields[entity.primary]));
81
+ existing.required = [...(existing.required ?? []), entity.primary];
82
+ const variants = [existing];
83
+ if (entity.fields[entity.primary].generated)
84
+ variants.push(writeInput(entity.root, 'create', true, mode));
85
+ schemas[name] = { anyOf: variants, description: 'An object with a primary key updates an existing record; an object without a key creates one. PUT replaces, PATCH updates supplied fields.' };
86
+ return ref(name);
87
+ }
64
88
  function output(entity, node) {
65
- if (node.relation) {
66
- entity = node.relation;
67
- node = entity.root;
68
- }
89
+ [entity, node] = canonicalNode(entity, node);
69
90
  const name = nodeName(entity, node);
70
91
  if (!reserve(name, node))
71
92
  return ref(name);
@@ -75,30 +96,53 @@ export function buildOpenapiDocument({ model, files = false, pageSize = 10, maxP
75
96
  continue;
76
97
  if (child.relation || child.base === 'object') {
77
98
  const value = child.many ? page(entity, child) : output(entity, child);
78
- properties[key] = child.nullable || (child.relation && !child.many && !child.required) ? { anyOf: [value, { type: 'object', nullable: true, enum: [null] }] } : value;
99
+ const shape = child.nullable || (child.relation && !child.many && !child.required) ? { anyOf: [value, { type: 'object', nullable: true, enum: [null] }] } : value;
100
+ const attributes = annotate({}, child);
101
+ properties[key] = Object.keys(attributes).length ? { allOf: [shape], ...attributes } : shape;
79
102
  }
80
103
  else
81
104
  properties[key] = baseField(child);
82
105
  }
83
- // scope may select any subset, so response properties are intentionally optional.
106
+ // Выбор может содержать любую часть полей, поэтому поля ответа необязательны.
84
107
  schemas[name] = { type: 'object', additionalProperties: false, properties };
85
108
  return ref(name);
86
109
  }
87
- function page(entity, node) {
88
- if (node.relation) {
89
- entity = node.relation;
90
- node = entity.root;
110
+ function scope(entity, node, list = node.many) {
111
+ [entity, node] = canonicalNode(entity, node);
112
+ const name = `${nodeName(entity, node)}${list ? 'List' : ''}Scope`;
113
+ if (!reserve(name, node))
114
+ return ref(name);
115
+ const fieldsName = `${nodeName(entity, node)}ScopeFields`;
116
+ if (reserve(fieldsName, node)) {
117
+ const included = { type: 'boolean', enum: [true] };
118
+ const properties = { '*': included };
119
+ for (const [key, child] of Object.entries(node.children)) {
120
+ if (child.writeOnly)
121
+ continue;
122
+ properties[key] = child.relation || child.base === 'object' ? scope(entity, child) : included;
123
+ }
124
+ schemas[fieldsName] = { type: 'object', additionalProperties: false, properties };
91
125
  }
126
+ schemas[name] = {
127
+ type: 'array',
128
+ minItems: 1,
129
+ maxItems: list ? 2 : 1,
130
+ items: list ? { anyOf: [ref(fieldsName), options(entity, node)] } : ref(fieldsName),
131
+ description: list
132
+ ? '[fields, arguments?]. The first object selects fields; the optional second object contains where, order and pager. OpenAPI 3.0 cannot express positional item schemas; the server validates their order.'
133
+ : '[fields]. * selects own fields without relations or writeOnly fields.',
134
+ };
135
+ return ref(name);
136
+ }
137
+ function page(entity, node) {
138
+ [entity, node] = canonicalNode(entity, node);
92
139
  const name = `${nodeName(entity, node)}Page`;
93
140
  if (reserve(name, node))
94
141
  schemas[name] = { type: 'object', required: ['data', 'total'], properties: { data: { type: 'array', items: output(entity, node) }, total: { type: 'integer', minimum: 0 } } };
95
142
  return ref(name);
96
143
  }
97
144
  function where(entity, node) {
98
- if (node.relation) {
99
- entity = node.relation;
100
- node = entity.root;
101
- }
145
+ [entity, node] = canonicalNode(entity, node);
102
146
  const name = `${nodeName(entity, node)}Where`;
103
147
  if (!reserve(name, node))
104
148
  return ref(name);
@@ -116,37 +160,31 @@ export function buildOpenapiDocument({ model, files = false, pageSize = 10, maxP
116
160
  const name = `${nodeName(entity, node)}Filter`;
117
161
  if (!reserve(name, node))
118
162
  return ref(name);
119
- const properties = { not: ref(name) };
120
- const object = node.relation || node.base === 'object';
121
- const scalar = { type: node.base, nullable: true, ...(node.enum ? { enum: node.enum } : {}) };
122
- if (node.many) {
123
- const element = object ? where(entity, node) : filter(entity, { ...node, many: false, path: `${node.path}_element` });
124
- for (const key of ['some', 'every', 'none'])
163
+ const properties = {};
164
+ const element = node.many ? (node.relation || node.base === 'object' ? where(entity, node) : filter(entity, { ...node, many: false, path: `${node.path}_element` })) : undefined;
165
+ for (const [key, operand] of Object.entries(operatorsFor(node))) {
166
+ const nullable = ['eq', 'ne', 'in'].includes(key);
167
+ const scalar = {
168
+ type: node.base,
169
+ ...(nullable ? { nullable: true } : {}),
170
+ ...(node.enum ? { enum: [...node.enum, ...(nullable && !node.enum.includes(null) ? [null] : [])] } : {}),
171
+ };
172
+ if (operand === 'condition')
173
+ properties[key] = ref(name);
174
+ else if (operand === 'element') {
175
+ if (!element)
176
+ throw new Error(`Missing element filter for ${node.path}`);
125
177
  properties[key] = element;
126
- if (!object) {
127
- properties.contains = scalar;
128
- properties.in = { type: 'array', items: scalar };
129
178
  }
130
- }
131
- else {
132
- for (const key of ['eq', 'ne'])
133
- properties[key] = scalar;
134
- properties.in = { type: 'array', items: scalar };
135
- if (node.base !== 'boolean')
136
- for (const key of ['gt', 'gte', 'lt', 'lte'])
137
- properties[key] = { type: node.base };
138
- if (node.base === 'string')
139
- for (const key of ['contains', 'startsWith', 'endsWith'])
140
- properties[key] = { type: 'string' };
179
+ else
180
+ properties[key] =
181
+ operand === 'values' ? { type: 'array', items: scalar } : operand === 'text' ? { type: 'string' } : operand === 'comparison' ? { type: node.base } : scalar;
141
182
  }
142
183
  schemas[name] = { type: 'object', additionalProperties: false, properties };
143
184
  return ref(name);
144
185
  }
145
186
  function order(entity, node) {
146
- if (node.relation) {
147
- entity = node.relation;
148
- node = entity.root;
149
- }
187
+ [entity, node] = canonicalNode(entity, node);
150
188
  const name = `${nodeName(entity, node)}Order`;
151
189
  if (reserve(name, node)) {
152
190
  const paths = sortableFields(node);
@@ -174,41 +212,24 @@ export function buildOpenapiDocument({ model, files = false, pageSize = 10, maxP
174
212
  for (const entity of model.entities.filter((e) => e.api.includes('openapi'))) {
175
213
  const name = entity.name;
176
214
  const op = operationName(entity);
177
- for (const mode of ['create', 'replace', 'update']) {
178
- const key = `${name}${mode[0].toUpperCase() + mode.slice(1)}`;
215
+ for (const { mode, hasBody } of MUTATIONS) {
216
+ if (!hasBody)
217
+ continue;
218
+ const key = `${name}${capitalize(mode)}`;
179
219
  reserve(key, entity.root);
180
- schemas[key] = annotateInput(toOpenapi(objectSchema(entity.root, mode, true)), entity.root, mode !== 'update');
220
+ schemas[key] = writeInput(entity.root, mode, true);
181
221
  }
182
- const nestedName = `${name}Nested`;
183
- reserve(nestedName, entity.root);
184
- const nestedProperties = {};
185
- const collect = (owner, node, prefix, seen) => {
186
- for (const [key, child] of Object.entries(childrenOf(node))) {
187
- if (child.writeOnly || (!child.relation && child.base !== 'object'))
188
- continue;
189
- const path = prefix + key;
190
- if (child.many)
191
- nestedProperties[path] = options(owner, child);
192
- const target = child.relation?.root ?? child;
193
- if (!seen.has(target))
194
- collect(child.relation ?? owner, target, `${path}.`, new Set([...seen, target]));
195
- }
196
- };
197
- collect(entity, entity.root, '', new Set([entity.root]));
198
- schemas[nestedName] = {
199
- type: 'object',
200
- properties: nestedProperties,
201
- additionalProperties: { type: 'object', additionalProperties: false, properties: { where: { type: 'object' }, order: { type: 'array', items: { type: 'object' } }, pager: ref('Pager') } },
202
- description: 'Path -> list options. Recursive paths are validated against the model at runtime.',
203
- };
204
- const shape = [
205
- { in: 'query', name: 'scope', schema: { type: 'string' }, description: 'Own fields and explicit relations, e.g. *,movies(id,title). * excludes relations and writeOnly fields.' },
206
- { in: 'query', name: 'nested', ...json(ref(nestedName)) },
207
- ];
208
- const list = [...shape, ...Object.entries(options(entity, entity.root).properties ?? {}).map(([key, schema]) => ({ in: 'query', name: key, ...json(schema) }))];
222
+ const selectionParameter = (list) => ({
223
+ in: 'query',
224
+ name: 'scope',
225
+ ...json(scope(entity, entity.root, list)),
226
+ description: 'JSON [fields, arguments?]. Scalars use true; objects and relations use their own scope arrays. * includes own fields without relations or writeOnly fields. Arguments are available only on lists.',
227
+ });
228
+ const shape = [selectionParameter(false)];
229
+ const list = [selectionParameter(true)];
209
230
  const key = { in: 'path', name: entity.primary, required: true, schema: baseField({ ...entity.fields[entity.primary], generated: undefined }) };
210
231
  const errors = { 400: response('Invalid request', ref('Error')), 404: response('Not found', ref('Error')), 409: response('Conflict', ref('Error')) };
211
- const make = (operationId, parameters, schema, mode) => {
232
+ const make = (operationId, parameters, schema, mutation) => {
212
233
  if (operations.has(operationId))
213
234
  throw new Error(`OpenAPI operation collision: ${operationId}`);
214
235
  operations.add(operationId);
@@ -216,17 +237,22 @@ export function buildOpenapiDocument({ model, files = false, pageSize = 10, maxP
216
237
  operationId,
217
238
  tags: [entity.collection],
218
239
  parameters,
219
- ...(mode ? { requestBody: { required: true, ...json(ref(`${name}${mode[0].toUpperCase() + mode.slice(1)}`)) } } : {}),
220
- responses: { [mode === 'create' ? 201 : 200]: response('Success', schema), ...errors },
240
+ ...(auth && mutation ? { security: [{ AuthBearer: [] }] } : {}),
241
+ ...(mutation?.hasBody ? { requestBody: { required: true, ...json(ref(`${name}${capitalize(mutation.mode)}`)) } } : {}),
242
+ responses: {
243
+ [mutation?.status ?? 200]: response('Success', schema),
244
+ ...errors,
245
+ ...(auth && mutation ? { 401: response('Authentication required', ref('Error')), 403: response('Forbidden', ref('Error')) } : {}),
246
+ },
221
247
  };
222
248
  };
223
- paths[`/${entity.collection}`] = { get: make(`${op}List`, list, page(entity, entity.root)), post: make(`${op}Create`, shape, output(entity, entity.root), 'create') };
224
- paths[`/${entity.collection}/{${entity.primary}}`] = {
225
- get: make(op, [key, ...shape], output(entity, entity.root)),
226
- put: make(`${op}Replace`, [key, ...shape], output(entity, entity.root), 'replace'),
227
- patch: make(`${op}Update`, [key, ...shape], output(entity, entity.root), 'update'),
228
- delete: make(`${op}Delete`, [key, ...shape], output(entity, entity.root)),
229
- };
249
+ const collectionPath = `/${entity.collection}`;
250
+ const itemPath = `${collectionPath}/{${entity.primary}}`;
251
+ paths[collectionPath] = { get: make(`${op}List`, list, page(entity, entity.root)) };
252
+ paths[itemPath] = { get: make(op, [key, ...shape], output(entity, entity.root)) };
253
+ for (const mutation of MUTATIONS) {
254
+ paths[mutation.hasKey ? itemPath : collectionPath][mutation.method.toLowerCase()] = make(`${op}${capitalize(mutation.mode)}`, mutation.hasKey ? [key, ...shape] : shape, output(entity, entity.root), mutation);
255
+ }
230
256
  }
231
257
  const parameters = {};
232
258
  if (files) {
@@ -244,9 +270,34 @@ export function buildOpenapiDocument({ model, files = false, pageSize = 10, maxP
244
270
  for (const [path, item] of Object.entries(createFilePaths())) {
245
271
  if (paths[path])
246
272
  throw new Error(`File path collision: ${path}`);
273
+ for (const operation of Object.values(item)) {
274
+ if (isObject(operation) && typeof operation.operationId === 'string') {
275
+ if (operations.has(operation.operationId))
276
+ throw new Error(`OpenAPI operation collision: ${operation.operationId}`);
277
+ operations.add(operation.operationId);
278
+ }
279
+ }
280
+ paths[path] = item;
281
+ }
282
+ }
283
+ if (auth) {
284
+ for (const [name, schema] of Object.entries(AUTH_SCHEMAS)) {
285
+ if (schemas[name])
286
+ throw new Error(`OpenAPI schema collision: ${name}`);
287
+ schemas[name] = structuredClone(schema);
288
+ }
289
+ for (const [path, item] of Object.entries(authOpenapiPaths())) {
290
+ if (paths[path] || model.entities.some((entity) => path.startsWith(`/${entity.collection}/`)))
291
+ throw new Error(`Auth path collision: ${path}`);
292
+ for (const operation of Object.values(item)) {
293
+ const id = operation.operationId;
294
+ if (operations.has(id))
295
+ throw new Error(`OpenAPI operation collision: ${id}`);
296
+ operations.add(id);
297
+ }
247
298
  paths[path] = item;
248
299
  }
249
300
  }
250
- return { openapi: '3.0.3', info, components: { schemas, parameters }, paths };
301
+ return { openapi: '3.0.3', info, components: { schemas, parameters, ...(auth ? { securitySchemes: structuredClone(AUTH_SECURITY_SCHEMES) } : {}) }, paths };
251
302
  }
252
303
  //# sourceMappingURL=document.js.map