@feathersjs/generators 5.0.0-pre.35

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 (169) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/LICENSE +22 -0
  3. package/README.md +23 -0
  4. package/lib/app/index.d.ts +29 -0
  5. package/lib/app/index.js +146 -0
  6. package/lib/app/index.js.map +1 -0
  7. package/lib/app/index.ts +228 -0
  8. package/lib/app/static/.gitignore +121 -0
  9. package/lib/app/templates/app.test.tpl.d.ts +2 -0
  10. package/lib/app/templates/app.test.tpl.js +49 -0
  11. package/lib/app/templates/app.test.tpl.js.map +1 -0
  12. package/lib/app/templates/app.test.tpl.ts +50 -0
  13. package/lib/app/templates/app.tpl.d.ts +2 -0
  14. package/lib/app/templates/app.tpl.js +123 -0
  15. package/lib/app/templates/app.tpl.js.map +1 -0
  16. package/lib/app/templates/app.tpl.ts +138 -0
  17. package/lib/app/templates/channels.tpl.d.ts +2 -0
  18. package/lib/app/templates/channels.tpl.js +50 -0
  19. package/lib/app/templates/channels.tpl.js.map +1 -0
  20. package/lib/app/templates/channels.tpl.ts +56 -0
  21. package/lib/app/templates/client.test.tpl.d.ts +2 -0
  22. package/lib/app/templates/client.test.tpl.js +27 -0
  23. package/lib/app/templates/client.test.tpl.js.map +1 -0
  24. package/lib/app/templates/client.test.tpl.ts +26 -0
  25. package/lib/app/templates/client.tpl.d.ts +2 -0
  26. package/lib/app/templates/client.tpl.js +38 -0
  27. package/lib/app/templates/client.tpl.js.map +1 -0
  28. package/lib/app/templates/client.tpl.ts +45 -0
  29. package/lib/app/templates/configuration.tpl.d.ts +2 -0
  30. package/lib/app/templates/configuration.tpl.js +71 -0
  31. package/lib/app/templates/configuration.tpl.js.map +1 -0
  32. package/lib/app/templates/configuration.tpl.ts +82 -0
  33. package/lib/app/templates/declarations.tpl.d.ts +2 -0
  34. package/lib/app/templates/declarations.tpl.js +28 -0
  35. package/lib/app/templates/declarations.tpl.js.map +1 -0
  36. package/lib/app/templates/declarations.tpl.ts +37 -0
  37. package/lib/app/templates/index.html.tpl.d.ts +2 -0
  38. package/lib/app/templates/index.html.tpl.js +45 -0
  39. package/lib/app/templates/index.html.tpl.js.map +1 -0
  40. package/lib/app/templates/index.html.tpl.ts +44 -0
  41. package/lib/app/templates/index.tpl.d.ts +2 -0
  42. package/lib/app/templates/index.tpl.js +22 -0
  43. package/lib/app/templates/index.tpl.js.map +1 -0
  44. package/lib/app/templates/index.tpl.ts +26 -0
  45. package/lib/app/templates/logger.tpl.d.ts +3 -0
  46. package/lib/app/templates/logger.tpl.js +45 -0
  47. package/lib/app/templates/logger.tpl.js.map +1 -0
  48. package/lib/app/templates/logger.tpl.ts +56 -0
  49. package/lib/app/templates/package.json.tpl.d.ts +2 -0
  50. package/lib/app/templates/package.json.tpl.js +58 -0
  51. package/lib/app/templates/package.json.tpl.js.map +1 -0
  52. package/lib/app/templates/package.json.tpl.ts +71 -0
  53. package/lib/app/templates/prettierrc.tpl.d.ts +2 -0
  54. package/lib/app/templates/prettierrc.tpl.js +11 -0
  55. package/lib/app/templates/prettierrc.tpl.js.map +1 -0
  56. package/lib/app/templates/prettierrc.tpl.ts +14 -0
  57. package/lib/app/templates/readme.md.tpl.d.ts +2 -0
  58. package/lib/app/templates/readme.md.tpl.js +54 -0
  59. package/lib/app/templates/readme.md.tpl.js.map +1 -0
  60. package/lib/app/templates/readme.md.tpl.ts +57 -0
  61. package/lib/app/templates/services.tpl.d.ts +2 -0
  62. package/lib/app/templates/services.tpl.js +15 -0
  63. package/lib/app/templates/services.tpl.js.map +1 -0
  64. package/lib/app/templates/services.tpl.ts +20 -0
  65. package/lib/app/templates/tsconfig.json.tpl.d.ts +2 -0
  66. package/lib/app/templates/tsconfig.json.tpl.js +22 -0
  67. package/lib/app/templates/tsconfig.json.tpl.js.map +1 -0
  68. package/lib/app/templates/tsconfig.json.tpl.ts +28 -0
  69. package/lib/app/templates/validators.tpl.d.ts +2 -0
  70. package/lib/app/templates/validators.tpl.js +36 -0
  71. package/lib/app/templates/validators.tpl.js.map +1 -0
  72. package/lib/app/templates/validators.tpl.ts +40 -0
  73. package/lib/authentication/index.d.ts +73 -0
  74. package/lib/authentication/index.js +107 -0
  75. package/lib/authentication/index.js.map +1 -0
  76. package/lib/authentication/index.ts +126 -0
  77. package/lib/authentication/templates/authentication.tpl.d.ts +2 -0
  78. package/lib/authentication/templates/authentication.tpl.js +40 -0
  79. package/lib/authentication/templates/authentication.tpl.js.map +1 -0
  80. package/lib/authentication/templates/authentication.tpl.ts +51 -0
  81. package/lib/authentication/templates/client.test.tpl.d.ts +2 -0
  82. package/lib/authentication/templates/client.test.tpl.js +62 -0
  83. package/lib/authentication/templates/client.test.tpl.js.map +1 -0
  84. package/lib/authentication/templates/client.test.tpl.ts +74 -0
  85. package/lib/authentication/templates/config.tpl.d.ts +2 -0
  86. package/lib/authentication/templates/config.tpl.js +50 -0
  87. package/lib/authentication/templates/config.tpl.js.map +1 -0
  88. package/lib/authentication/templates/config.tpl.ts +57 -0
  89. package/lib/authentication/templates/declarations.tpl.d.ts +2 -0
  90. package/lib/authentication/templates/declarations.tpl.js +19 -0
  91. package/lib/authentication/templates/declarations.tpl.js.map +1 -0
  92. package/lib/authentication/templates/declarations.tpl.ts +34 -0
  93. package/lib/authentication/templates/knex.tpl.d.ts +2 -0
  94. package/lib/authentication/templates/knex.tpl.js +45 -0
  95. package/lib/authentication/templates/knex.tpl.js.map +1 -0
  96. package/lib/authentication/templates/knex.tpl.ts +62 -0
  97. package/lib/authentication/templates/schema.json.tpl.d.ts +2 -0
  98. package/lib/authentication/templates/schema.json.tpl.js +103 -0
  99. package/lib/authentication/templates/schema.json.tpl.js.map +1 -0
  100. package/lib/authentication/templates/schema.json.tpl.ts +124 -0
  101. package/lib/authentication/templates/schema.typebox.tpl.d.ts +3 -0
  102. package/lib/authentication/templates/schema.typebox.tpl.js +86 -0
  103. package/lib/authentication/templates/schema.typebox.tpl.js.map +1 -0
  104. package/lib/authentication/templates/schema.typebox.tpl.ts +108 -0
  105. package/lib/commons.d.ts +150 -0
  106. package/lib/commons.js +198 -0
  107. package/lib/commons.js.map +1 -0
  108. package/lib/commons.ts +284 -0
  109. package/lib/connection/index.d.ts +55 -0
  110. package/lib/connection/index.js +88 -0
  111. package/lib/connection/index.js.map +1 -0
  112. package/lib/connection/index.ts +123 -0
  113. package/lib/connection/templates/knex.tpl.d.ts +2 -0
  114. package/lib/connection/templates/knex.tpl.js +48 -0
  115. package/lib/connection/templates/knex.tpl.js.map +1 -0
  116. package/lib/connection/templates/knex.tpl.ts +67 -0
  117. package/lib/connection/templates/mongodb.tpl.d.ts +2 -0
  118. package/lib/connection/templates/mongodb.tpl.js +34 -0
  119. package/lib/connection/templates/mongodb.tpl.js.map +1 -0
  120. package/lib/connection/templates/mongodb.tpl.ts +40 -0
  121. package/lib/hook/index.d.ts +22 -0
  122. package/lib/hook/index.js +43 -0
  123. package/lib/hook/index.js.map +1 -0
  124. package/lib/hook/index.ts +47 -0
  125. package/lib/hook/templates/hook.tpl.d.ts +2 -0
  126. package/lib/hook/templates/hook.tpl.js +22 -0
  127. package/lib/hook/templates/hook.tpl.js.map +1 -0
  128. package/lib/hook/templates/hook.tpl.ts +33 -0
  129. package/lib/index.d.ts +7 -0
  130. package/lib/index.js +37 -0
  131. package/lib/index.js.map +1 -0
  132. package/lib/index.ts +8 -0
  133. package/lib/service/index.d.ts +64 -0
  134. package/lib/service/index.js +116 -0
  135. package/lib/service/index.js.map +1 -0
  136. package/lib/service/index.ts +191 -0
  137. package/lib/service/templates/client.tpl.d.ts +2 -0
  138. package/lib/service/templates/client.tpl.js +30 -0
  139. package/lib/service/templates/client.tpl.js.map +1 -0
  140. package/lib/service/templates/client.tpl.ts +56 -0
  141. package/lib/service/templates/schema.json.tpl.d.ts +2 -0
  142. package/lib/service/templates/schema.json.tpl.js +83 -0
  143. package/lib/service/templates/schema.json.tpl.js.map +1 -0
  144. package/lib/service/templates/schema.json.tpl.ts +98 -0
  145. package/lib/service/templates/schema.typebox.tpl.d.ts +2 -0
  146. package/lib/service/templates/schema.typebox.tpl.js +61 -0
  147. package/lib/service/templates/schema.typebox.tpl.js.map +1 -0
  148. package/lib/service/templates/schema.typebox.tpl.ts +76 -0
  149. package/lib/service/templates/service.tpl.d.ts +3 -0
  150. package/lib/service/templates/service.tpl.js +112 -0
  151. package/lib/service/templates/service.tpl.js.map +1 -0
  152. package/lib/service/templates/service.tpl.ts +152 -0
  153. package/lib/service/templates/test.tpl.d.ts +2 -0
  154. package/lib/service/templates/test.tpl.js +25 -0
  155. package/lib/service/templates/test.tpl.js.map +1 -0
  156. package/lib/service/templates/test.tpl.ts +33 -0
  157. package/lib/service/type/custom.tpl.d.ts +3 -0
  158. package/lib/service/type/custom.tpl.js +98 -0
  159. package/lib/service/type/custom.tpl.js.map +1 -0
  160. package/lib/service/type/custom.tpl.ts +109 -0
  161. package/lib/service/type/knex.tpl.d.ts +3 -0
  162. package/lib/service/type/knex.tpl.js +71 -0
  163. package/lib/service/type/knex.tpl.js.map +1 -0
  164. package/lib/service/type/knex.tpl.ts +92 -0
  165. package/lib/service/type/mongodb.tpl.d.ts +3 -0
  166. package/lib/service/type/mongodb.tpl.js +50 -0
  167. package/lib/service/type/mongodb.tpl.js.map +1 -0
  168. package/lib/service/type/mongodb.tpl.ts +62 -0
  169. package/package.json +89 -0
@@ -0,0 +1,51 @@
1
+ import { generator, before, toFile } from '@feathershq/pinion'
2
+ import { injectSource, renderSource } from '../../commons'
3
+ import { AuthenticationGeneratorContext, localTemplate, oauthTemplate } from '../index'
4
+
5
+ const template = ({
6
+ authStrategies
7
+ }: AuthenticationGeneratorContext) => /* ts */ `// For more information about this file see https://dove.feathersjs.com/guides/cli/authentication.html
8
+ import { AuthenticationService, JWTStrategy } from '@feathersjs/authentication'
9
+ ${localTemplate(authStrategies, `import { LocalStrategy } from '@feathersjs/authentication-local'`)}
10
+ ${oauthTemplate(authStrategies, `import { oauth, OAuthStrategy } from '@feathersjs/authentication-oauth'`)}
11
+
12
+ import type { Application } from './declarations'
13
+
14
+ declare module './declarations' {
15
+ interface ServiceTypes {
16
+ 'authentication': AuthenticationService
17
+ }
18
+ }
19
+
20
+ export const authentication = (app: Application) => {
21
+ const authentication = new AuthenticationService(app)
22
+
23
+ authentication.register('jwt', new JWTStrategy())
24
+ ${authStrategies
25
+ .map(
26
+ (strategy) =>
27
+ ` authentication.register('${strategy}', ${
28
+ strategy === 'local' ? `new LocalStrategy()` : `new OAuthStrategy()`
29
+ })`
30
+ )
31
+ .join('\n')}
32
+
33
+ app.use('authentication', authentication)
34
+ ${oauthTemplate(authStrategies, `app.configure(oauth())`)}
35
+ }
36
+ `
37
+
38
+ const importTemplate = "import { authentication } from './authentication'"
39
+ const configureTemplate = 'app.configure(authentication)'
40
+ const toAppFile = toFile<AuthenticationGeneratorContext>(({ lib }) => [lib, 'app'])
41
+
42
+ export const generate = (ctx: AuthenticationGeneratorContext) =>
43
+ generator(ctx)
44
+ .then(
45
+ renderSource(
46
+ template,
47
+ toFile<AuthenticationGeneratorContext>(({ lib }) => lib, 'authentication')
48
+ )
49
+ )
50
+ .then(injectSource(importTemplate, before('import { services } from'), toAppFile))
51
+ .then(injectSource(configureTemplate, before('app.configure(services)'), toAppFile))
@@ -0,0 +1,2 @@
1
+ import { AuthenticationGeneratorContext } from '../index';
2
+ export declare const generate: (ctx: AuthenticationGeneratorContext) => Promise<AuthenticationGeneratorContext>;
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generate = void 0;
4
+ const pinion_1 = require("@feathershq/pinion");
5
+ const commons_1 = require("../../commons");
6
+ const index_1 = require("../index");
7
+ const template = ({ authStrategies, upperName, type, lib }) => /* ts */ `// For more information about this file see https://dove.feathersjs.com/guides/cli/client.test.html
8
+ import assert from 'assert'
9
+ import axios from 'axios'
10
+
11
+ import rest from '@feathersjs/rest-client'
12
+ ${(0, index_1.localTemplate)(authStrategies, `import authenticationClient from '@feathersjs/authentication-client'`)}
13
+ import { app } from '../${lib}/app'
14
+ import { createClient } from '../${lib}/client'
15
+ ${(0, index_1.localTemplate)(authStrategies, `import type { ${upperName}Data } from '../${lib}/client'`)}
16
+
17
+ const port = app.get('port')
18
+ const appUrl = \`http://\${app.get('host')}:\${port}\`
19
+
20
+ describe('application client tests', () => {
21
+ const client = createClient(rest(appUrl).axios(axios))
22
+
23
+ before(async () => {
24
+ await app.listen(port)
25
+ })
26
+
27
+ after(async () => {
28
+ await app.teardown()
29
+ })
30
+
31
+ it('initialized the client', () => {
32
+ assert.ok(client)
33
+ })
34
+
35
+ ${(0, index_1.localTemplate)(authStrategies, `
36
+ it('creates and authenticates a user with email and password', async () => {
37
+ const userData: ${upperName}Data = {
38
+ email: 'someone@example.com',
39
+ password: 'supersecret'
40
+ }
41
+
42
+ await client.service('users').create(userData)
43
+
44
+ const { user, accessToken } = await client.authenticate({
45
+ strategy: 'local',
46
+ ...userData
47
+ })
48
+
49
+ assert.ok(accessToken, 'Created access token for user')
50
+ assert.ok(user, 'Includes user in authentication data')
51
+ assert.strictEqual(user.password, undefined, 'Password is hidden to clients')
52
+
53
+ await client.logout()
54
+
55
+ // Remove the test user on the server
56
+ await app.service('users').remove(user.${type === 'mongodb' ? '_id' : 'id'})
57
+ })`)}
58
+ })
59
+ `;
60
+ const generate = (ctx) => (0, pinion_1.generator)(ctx).then((0, commons_1.renderSource)(template, (0, pinion_1.toFile)(({ test }) => test, 'client.test'), { force: true }));
61
+ exports.generate = generate;
62
+ //# sourceMappingURL=client.test.tpl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.test.tpl.js","sourceRoot":"","sources":["../../../src/authentication/templates/client.test.tpl.ts"],"names":[],"mappings":";;;AAAA,+CAAsD;AACtD,2CAA4C;AAC5C,oCAAwE;AAExE,MAAM,QAAQ,GAAG,CAAC,EAChB,cAAc,EACd,SAAS,EACT,IAAI,EACJ,GAAG,EAC4B,EAAE,EAAE,CAAC,QAAQ,CAAC;;;;;EAK7C,IAAA,qBAAa,EAAC,cAAc,EAAE,sEAAsE,CAAC;0BAC7E,GAAG;mCACM,GAAG;EACpC,IAAA,qBAAa,EAAC,cAAc,EAAE,iBAAiB,SAAS,mBAAmB,GAAG,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;IAoBvF,IAAA,qBAAa,EACb,cAAc,EACd;;sBAEkB,SAAS;;;;;;;;;;;;;;;;;;;6CAmBc,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI;KACzE,CACF;;CAEF,CAAA;AAEM,MAAM,QAAQ,GAAG,CAAC,GAAmC,EAAE,EAAE,CAC9D,IAAA,kBAAS,EAAC,GAAG,CAAC,CAAC,IAAI,CACjB,IAAA,sBAAY,EACV,QAAQ,EACR,IAAA,eAAM,EAAiC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,IAAI,EAAE,aAAa,CAAC,EACzE,EAAE,KAAK,EAAE,IAAI,EAAE,CAChB,CACF,CAAA;AAPU,QAAA,QAAQ,YAOlB"}
@@ -0,0 +1,74 @@
1
+ import { generator, toFile } from '@feathershq/pinion'
2
+ import { renderSource } from '../../commons'
3
+ import { AuthenticationGeneratorContext, localTemplate } from '../index'
4
+
5
+ const template = ({
6
+ authStrategies,
7
+ upperName,
8
+ type,
9
+ lib
10
+ }: AuthenticationGeneratorContext) => /* ts */ `// For more information about this file see https://dove.feathersjs.com/guides/cli/client.test.html
11
+ import assert from 'assert'
12
+ import axios from 'axios'
13
+
14
+ import rest from '@feathersjs/rest-client'
15
+ ${localTemplate(authStrategies, `import authenticationClient from '@feathersjs/authentication-client'`)}
16
+ import { app } from '../${lib}/app'
17
+ import { createClient } from '../${lib}/client'
18
+ ${localTemplate(authStrategies, `import type { ${upperName}Data } from '../${lib}/client'`)}
19
+
20
+ const port = app.get('port')
21
+ const appUrl = \`http://\${app.get('host')}:\${port}\`
22
+
23
+ describe('application client tests', () => {
24
+ const client = createClient(rest(appUrl).axios(axios))
25
+
26
+ before(async () => {
27
+ await app.listen(port)
28
+ })
29
+
30
+ after(async () => {
31
+ await app.teardown()
32
+ })
33
+
34
+ it('initialized the client', () => {
35
+ assert.ok(client)
36
+ })
37
+
38
+ ${localTemplate(
39
+ authStrategies,
40
+ `
41
+ it('creates and authenticates a user with email and password', async () => {
42
+ const userData: ${upperName}Data = {
43
+ email: 'someone@example.com',
44
+ password: 'supersecret'
45
+ }
46
+
47
+ await client.service('users').create(userData)
48
+
49
+ const { user, accessToken } = await client.authenticate({
50
+ strategy: 'local',
51
+ ...userData
52
+ })
53
+
54
+ assert.ok(accessToken, 'Created access token for user')
55
+ assert.ok(user, 'Includes user in authentication data')
56
+ assert.strictEqual(user.password, undefined, 'Password is hidden to clients')
57
+
58
+ await client.logout()
59
+
60
+ // Remove the test user on the server
61
+ await app.service('users').remove(user.${type === 'mongodb' ? '_id' : 'id'})
62
+ })`
63
+ )}
64
+ })
65
+ `
66
+
67
+ export const generate = (ctx: AuthenticationGeneratorContext) =>
68
+ generator(ctx).then(
69
+ renderSource(
70
+ template,
71
+ toFile<AuthenticationGeneratorContext>(({ test }) => test, 'client.test'),
72
+ { force: true }
73
+ )
74
+ )
@@ -0,0 +1,2 @@
1
+ import { AuthenticationGeneratorContext } from '../index';
2
+ export declare const generate: (ctx: AuthenticationGeneratorContext) => Promise<AuthenticationGeneratorContext>;
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.generate = void 0;
7
+ const crypto_1 = __importDefault(require("crypto"));
8
+ const pinion_1 = require("@feathershq/pinion");
9
+ const generate = (ctx) => (0, pinion_1.generator)(ctx)
10
+ .then((0, pinion_1.mergeJSON)(({ authStrategies }) => {
11
+ const authentication = {
12
+ entity: ctx.entity,
13
+ service: ctx.path,
14
+ secret: crypto_1.default.randomBytes(24).toString('base64'),
15
+ authStrategies: ['jwt'],
16
+ jwtOptions: {
17
+ header: {
18
+ typ: 'access'
19
+ },
20
+ audience: 'https://yourdomain.com',
21
+ algorithm: 'HS256',
22
+ expiresIn: '1d'
23
+ }
24
+ };
25
+ if (authStrategies.includes('local')) {
26
+ authentication.authStrategies.push('local');
27
+ authentication.local = {
28
+ usernameField: 'email',
29
+ passwordField: 'password'
30
+ };
31
+ }
32
+ const oauthStrategies = authStrategies.filter((name) => name !== 'local');
33
+ if (oauthStrategies.length) {
34
+ authentication.oauth = oauthStrategies.reduce((oauth, name) => {
35
+ oauth[name] = {
36
+ key: '<Client ID>',
37
+ secret: '<Client secret>'
38
+ };
39
+ return oauth;
40
+ }, {});
41
+ }
42
+ return { authentication };
43
+ }, (0, pinion_1.toFile)('config', 'default.json')))
44
+ .then((0, pinion_1.mergeJSON)({
45
+ authentication: {
46
+ secret: 'FEATHERS_SECRET'
47
+ }
48
+ }, (0, pinion_1.toFile)('config', 'custom-environment-variables.json')));
49
+ exports.generate = generate;
50
+ //# sourceMappingURL=config.tpl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.tpl.js","sourceRoot":"","sources":["../../../src/authentication/templates/config.tpl.ts"],"names":[],"mappings":";;;;;;AAAA,oDAA2B;AAC3B,+CAAiE;AAG1D,MAAM,QAAQ,GAAG,CAAC,GAAmC,EAAE,EAAE,CAC9D,IAAA,kBAAS,EAAC,GAAG,CAAC;KACX,IAAI,CACH,IAAA,kBAAS,EAAiC,CAAC,EAAE,cAAc,EAAE,EAAE,EAAE;IAC/D,MAAM,cAAc,GAAQ;QAC1B,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,OAAO,EAAE,GAAG,CAAC,IAAI;QACjB,MAAM,EAAE,gBAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC;QACjD,cAAc,EAAE,CAAC,KAAK,CAAC;QACvB,UAAU,EAAE;YACV,MAAM,EAAE;gBACN,GAAG,EAAE,QAAQ;aACd;YACD,QAAQ,EAAE,wBAAwB;YAClC,SAAS,EAAE,OAAO;YAClB,SAAS,EAAE,IAAI;SAChB;KACF,CAAA;IAED,IAAI,cAAc,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE;QACpC,cAAc,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QAC3C,cAAc,CAAC,KAAK,GAAG;YACrB,aAAa,EAAE,OAAO;YACtB,aAAa,EAAE,UAAU;SAC1B,CAAA;KACF;IAED,MAAM,eAAe,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,OAAO,CAAC,CAAA;IAEzE,IAAI,eAAe,CAAC,MAAM,EAAE;QAC1B,cAAc,CAAC,KAAK,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;YAC5D,KAAK,CAAC,IAAI,CAAC,GAAG;gBACZ,GAAG,EAAE,aAAa;gBAClB,MAAM,EAAE,iBAAiB;aAC1B,CAAA;YAED,OAAO,KAAK,CAAA;QACd,CAAC,EAAE,EAAS,CAAC,CAAA;KACd;IAED,OAAO,EAAE,cAAc,EAAE,CAAA;AAC3B,CAAC,EAAE,IAAA,eAAM,EAAC,QAAQ,EAAE,cAAc,CAAC,CAAC,CACrC;KACA,IAAI,CACH,IAAA,kBAAS,EACP;IACE,cAAc,EAAE;QACd,MAAM,EAAE,iBAAiB;KAC1B;CACF,EACD,IAAA,eAAM,EAAC,QAAQ,EAAE,mCAAmC,CAAC,CACtD,CACF,CAAA;AApDQ,QAAA,QAAQ,YAoDhB"}
@@ -0,0 +1,57 @@
1
+ import crypto from 'crypto'
2
+ import { generator, toFile, mergeJSON } from '@feathershq/pinion'
3
+ import { AuthenticationGeneratorContext } from '../index'
4
+
5
+ export const generate = (ctx: AuthenticationGeneratorContext) =>
6
+ generator(ctx)
7
+ .then(
8
+ mergeJSON<AuthenticationGeneratorContext>(({ authStrategies }) => {
9
+ const authentication: any = {
10
+ entity: ctx.entity,
11
+ service: ctx.path,
12
+ secret: crypto.randomBytes(24).toString('base64'),
13
+ authStrategies: ['jwt'],
14
+ jwtOptions: {
15
+ header: {
16
+ typ: 'access'
17
+ },
18
+ audience: 'https://yourdomain.com',
19
+ algorithm: 'HS256',
20
+ expiresIn: '1d'
21
+ }
22
+ }
23
+
24
+ if (authStrategies.includes('local')) {
25
+ authentication.authStrategies.push('local')
26
+ authentication.local = {
27
+ usernameField: 'email',
28
+ passwordField: 'password'
29
+ }
30
+ }
31
+
32
+ const oauthStrategies = authStrategies.filter((name) => name !== 'local')
33
+
34
+ if (oauthStrategies.length) {
35
+ authentication.oauth = oauthStrategies.reduce((oauth, name) => {
36
+ oauth[name] = {
37
+ key: '<Client ID>',
38
+ secret: '<Client secret>'
39
+ }
40
+
41
+ return oauth
42
+ }, {} as any)
43
+ }
44
+
45
+ return { authentication }
46
+ }, toFile('config', 'default.json'))
47
+ )
48
+ .then(
49
+ mergeJSON<AuthenticationGeneratorContext>(
50
+ {
51
+ authentication: {
52
+ secret: 'FEATHERS_SECRET'
53
+ }
54
+ },
55
+ toFile('config', 'custom-environment-variables.json')
56
+ )
57
+ )
@@ -0,0 +1,2 @@
1
+ import { AuthenticationGeneratorContext } from '../index';
2
+ export declare const generate: (ctx: AuthenticationGeneratorContext) => Promise<AuthenticationGeneratorContext>;
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generate = void 0;
4
+ const pinion_1 = require("@feathershq/pinion");
5
+ const importTemplate = ({ upperName, folder, fileName }) => /* ts */ `import { ${upperName} } from './services/${folder.join('/')}/${fileName}'
6
+ `;
7
+ const paramsTemplate = ({ entity, upperName }) => /* ts */ `// Add the ${entity} as an optional property to all params
8
+ declare module '@feathersjs/feathers' {
9
+ interface Params {
10
+ ${entity}?: ${upperName}
11
+ }
12
+ }
13
+ `;
14
+ const toDeclarationFile = (0, pinion_1.toFile)(({ lib }) => lib, 'declarations.ts');
15
+ const generate = (ctx) => (0, pinion_1.generator)(ctx)
16
+ .then((0, pinion_1.when)((ctx) => ctx.language === 'ts', (0, pinion_1.inject)(importTemplate, (0, pinion_1.before)('export { NextFunction }'), toDeclarationFile)))
17
+ .then((0, pinion_1.when)((ctx) => ctx.language === 'ts', (0, pinion_1.inject)(paramsTemplate, (0, pinion_1.append)(), toDeclarationFile)));
18
+ exports.generate = generate;
19
+ //# sourceMappingURL=declarations.tpl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"declarations.tpl.js","sourceRoot":"","sources":["../../../src/authentication/templates/declarations.tpl.ts"],"names":[],"mappings":";;;AAAA,+CAAoF;AAGpF,MAAM,cAAc,GAAG,CAAC,EACtB,SAAS,EACT,MAAM,EACN,QAAQ,EACuB,EAAE,EAAE,CAAC,QAAQ,CAAC,YAAY,SAAS,uBAAuB,MAAM,CAAC,IAAI,CACpG,GAAG,CACJ,IAAI,QAAQ;CACZ,CAAA;AAED,MAAM,cAAc,GAAG,CAAC,EACtB,MAAM,EACN,SAAS,EACsB,EAAE,EAAE,CAAC,QAAQ,CAAC,cAAc,MAAM;;;MAG7D,MAAM,MAAM,SAAS;;;CAG1B,CAAA;AAED,MAAM,iBAAiB,GAAG,IAAA,eAAM,EAAiC,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,GAAG,EAAE,iBAAiB,CAAC,CAAA;AAE9F,MAAM,QAAQ,GAAG,CAAC,GAAmC,EAAE,EAAE,CAC9D,IAAA,kBAAS,EAAC,GAAG,CAAC;KACX,IAAI,CACH,IAAA,aAAI,EACF,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,QAAQ,KAAK,IAAI,EAC9B,IAAA,eAAM,EAAC,cAAc,EAAE,IAAA,eAAM,EAAC,yBAAyB,CAAC,EAAE,iBAAiB,CAAC,CAC7E,CACF;KACA,IAAI,CAAC,IAAA,aAAI,EAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,QAAQ,KAAK,IAAI,EAAE,IAAA,eAAM,EAAC,cAAc,EAAE,IAAA,eAAM,GAAE,EAAE,iBAAiB,CAAC,CAAC,CAAC,CAAA;AARvF,QAAA,QAAQ,YAQ+E"}
@@ -0,0 +1,34 @@
1
+ import { generator, inject, before, toFile, when, append } from '@feathershq/pinion'
2
+ import { AuthenticationGeneratorContext } from '../index'
3
+
4
+ const importTemplate = ({
5
+ upperName,
6
+ folder,
7
+ fileName
8
+ }: AuthenticationGeneratorContext) => /* ts */ `import { ${upperName} } from './services/${folder.join(
9
+ '/'
10
+ )}/${fileName}'
11
+ `
12
+
13
+ const paramsTemplate = ({
14
+ entity,
15
+ upperName
16
+ }: AuthenticationGeneratorContext) => /* ts */ `// Add the ${entity} as an optional property to all params
17
+ declare module '@feathersjs/feathers' {
18
+ interface Params {
19
+ ${entity}?: ${upperName}
20
+ }
21
+ }
22
+ `
23
+
24
+ const toDeclarationFile = toFile<AuthenticationGeneratorContext>(({ lib }) => lib, 'declarations.ts')
25
+
26
+ export const generate = (ctx: AuthenticationGeneratorContext) =>
27
+ generator(ctx)
28
+ .then(
29
+ when(
30
+ (ctx) => ctx.language === 'ts',
31
+ inject(importTemplate, before('export { NextFunction }'), toDeclarationFile)
32
+ )
33
+ )
34
+ .then(when((ctx) => ctx.language === 'ts', inject(paramsTemplate, append(), toDeclarationFile)))
@@ -0,0 +1,2 @@
1
+ import { AuthenticationGeneratorContext } from '../index';
2
+ export declare const generate: (ctx: AuthenticationGeneratorContext) => Promise<AuthenticationGeneratorContext>;
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generate = void 0;
4
+ const pinion_1 = require("@feathershq/pinion");
5
+ const commons_1 = require("../../commons");
6
+ const migrationTemplate = ({ kebabPath, authStrategies }) => /* ts */ `import type { Knex } from 'knex'
7
+
8
+ export async function up(knex: Knex): Promise<void> {
9
+ await knex.schema.alterTable('${kebabPath}', function (table) {
10
+ table.dropColumn('text')${authStrategies
11
+ .map((name) => name === 'local'
12
+ ? `
13
+ table.string('email').unique()
14
+ table.string('password')`
15
+ : `
16
+ table.string('${name}Id')`)
17
+ .join('\n')}
18
+ })
19
+ }
20
+
21
+ export async function down(knex: Knex): Promise<void> {
22
+ await knex.schema.alterTable('${kebabPath}', function (table) {
23
+ table.string('text')${authStrategies
24
+ .map((name) => name === 'local'
25
+ ? `
26
+ table.dropColumn('email')
27
+ table.dropColumn('password')`
28
+ : `
29
+ table.dropColumn('${name}Id')
30
+ `)
31
+ .join('\n')}
32
+ })
33
+ }
34
+ `;
35
+ const generate = (ctx) => (0, pinion_1.generator)(ctx).then((0, pinion_1.when)((ctx) => { var _a; return (0, commons_1.getDatabaseAdapter)((_a = ctx.feathers) === null || _a === void 0 ? void 0 : _a.database) === 'knex'; }, (0, commons_1.renderSource)(migrationTemplate, (0, pinion_1.toFile)((0, pinion_1.toFile)('migrations', () => {
36
+ // Probably not great but it works to align with the Knex migration file format
37
+ // We add a few seconds so that the migrations run in the correct order
38
+ const migrationDate = new Date(Date.now() + 10000)
39
+ .toISOString()
40
+ .replace(/\D/g, '')
41
+ .substring(0, 14);
42
+ return `${migrationDate}_authentication`;
43
+ })))));
44
+ exports.generate = generate;
45
+ //# sourceMappingURL=knex.tpl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"knex.tpl.js","sourceRoot":"","sources":["../../../src/authentication/templates/knex.tpl.ts"],"names":[],"mappings":";;;AAAA,+CAA4D;AAC5D,2CAAgE;AAGhE,MAAM,iBAAiB,GAAG,CAAC,EACzB,SAAS,EACT,cAAc,EACiB,EAAE,EAAE,CAAC,QAAQ,CAAC;;;kCAGb,SAAS;8BACb,cAAc;KACrC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CACZ,IAAI,KAAK,OAAO;IACd,CAAC,CAAC;;6BAEiB;IACnB,CAAC,CAAC;oBACQ,IAAI,MAAM,CACvB;KACA,IAAI,CAAC,IAAI,CAAC;;;;;kCAKiB,SAAS;0BACjB,cAAc;KACjC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CACZ,IAAI,KAAK,OAAO;IACd,CAAC,CAAC;;iCAEqB;IACvB,CAAC,CAAC;wBACY,IAAI;KACvB,CACE;KACA,IAAI,CAAC,IAAI,CAAC;;;CAGhB,CAAA;AAEM,MAAM,QAAQ,GAAG,CAAC,GAAmC,EAAE,EAAE,CAC9D,IAAA,kBAAS,EAAC,GAAG,CAAC,CAAC,IAAI,CACjB,IAAA,aAAI,EACF,CAAC,GAAG,EAAE,EAAE,WAAC,OAAA,IAAA,4BAAkB,EAAC,MAAA,GAAG,CAAC,QAAQ,0CAAE,QAAQ,CAAC,KAAK,MAAM,CAAA,EAAA,EAC9D,IAAA,sBAAY,EACV,iBAAiB,EACjB,IAAA,eAAM,EACJ,IAAA,eAAM,EAAiC,YAAY,EAAE,GAAG,EAAE;IACxD,+EAA+E;IAC/E,uEAAuE;IACvE,MAAM,aAAa,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;SAC/C,WAAW,EAAE;SACb,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;SAClB,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;IAEnB,OAAO,GAAG,aAAa,iBAAiB,CAAA;AAC1C,CAAC,CAAC,CACH,CACF,CACF,CACF,CAAA;AApBU,QAAA,QAAQ,YAoBlB"}
@@ -0,0 +1,62 @@
1
+ import { generator, when, toFile } from '@feathershq/pinion'
2
+ import { getDatabaseAdapter, renderSource } from '../../commons'
3
+ import { AuthenticationGeneratorContext } from '../index'
4
+
5
+ const migrationTemplate = ({
6
+ kebabPath,
7
+ authStrategies
8
+ }: AuthenticationGeneratorContext) => /* ts */ `import type { Knex } from 'knex'
9
+
10
+ export async function up(knex: Knex): Promise<void> {
11
+ await knex.schema.alterTable('${kebabPath}', function (table) {
12
+ table.dropColumn('text')${authStrategies
13
+ .map((name) =>
14
+ name === 'local'
15
+ ? `
16
+ table.string('email').unique()
17
+ table.string('password')`
18
+ : `
19
+ table.string('${name}Id')`
20
+ )
21
+ .join('\n')}
22
+ })
23
+ }
24
+
25
+ export async function down(knex: Knex): Promise<void> {
26
+ await knex.schema.alterTable('${kebabPath}', function (table) {
27
+ table.string('text')${authStrategies
28
+ .map((name) =>
29
+ name === 'local'
30
+ ? `
31
+ table.dropColumn('email')
32
+ table.dropColumn('password')`
33
+ : `
34
+ table.dropColumn('${name}Id')
35
+ `
36
+ )
37
+ .join('\n')}
38
+ })
39
+ }
40
+ `
41
+
42
+ export const generate = (ctx: AuthenticationGeneratorContext) =>
43
+ generator(ctx).then(
44
+ when(
45
+ (ctx) => getDatabaseAdapter(ctx.feathers?.database) === 'knex',
46
+ renderSource(
47
+ migrationTemplate,
48
+ toFile(
49
+ toFile<AuthenticationGeneratorContext>('migrations', () => {
50
+ // Probably not great but it works to align with the Knex migration file format
51
+ // We add a few seconds so that the migrations run in the correct order
52
+ const migrationDate = new Date(Date.now() + 10000)
53
+ .toISOString()
54
+ .replace(/\D/g, '')
55
+ .substring(0, 14)
56
+
57
+ return `${migrationDate}_authentication`
58
+ })
59
+ )
60
+ )
61
+ )
62
+ )
@@ -0,0 +1,2 @@
1
+ import { AuthenticationGeneratorContext } from '../index';
2
+ export declare const generate: (ctx: AuthenticationGeneratorContext) => Promise<AuthenticationGeneratorContext>;
@@ -0,0 +1,103 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generate = void 0;
4
+ const pinion_1 = require("@feathershq/pinion");
5
+ const commons_1 = require("../../commons");
6
+ const index_1 = require("../index");
7
+ const template = ({ cwd, lib, camelName, upperName, authStrategies, type, relative }) => /* ts */ `// For more information about this file see https://dove.feathersjs.com/guides/cli/service.schemas.html
8
+ import { resolve, querySyntax, getValidator } from '@feathersjs/schema'
9
+ import type { FromSchema } from '@feathersjs/schema'
10
+ ${(0, index_1.localTemplate)(authStrategies, `import { passwordHash } from '@feathersjs/authentication-local'`)}
11
+
12
+ import type { HookContext } from '${relative}/declarations'
13
+ import { dataValidator, queryValidator } from '${relative}/${(0, commons_1.fileExists)(cwd, lib, 'schemas') ? 'schemas/' : '' // This is for legacy backwards compatibility
14
+ }validators'
15
+
16
+ // Main data model schema
17
+ export const ${camelName}Schema = {
18
+ $id: '${upperName}',
19
+ type: 'object',
20
+ additionalProperties: false,
21
+ required: [ '${type === 'mongodb' ? '_id' : 'id'}'${(0, index_1.localTemplate)(authStrategies, ", 'email'")} ],
22
+ properties: {
23
+ ${type === 'mongodb' ? '_id' : 'id'}: {
24
+ type: '${type === 'mongodb' ? 'string' : 'number'}'
25
+ },
26
+ ${authStrategies
27
+ .map((name) => name === 'local'
28
+ ? ` email: { type: 'string' },
29
+ password: { type: 'string' }`
30
+ : ` ${name}Id: { type: 'string' }`)
31
+ .join(',\n')}
32
+ }
33
+ } as const
34
+ export type ${upperName} = FromSchema<typeof ${camelName}Schema>
35
+ export const ${camelName}Resolver = resolve<${upperName}, HookContext>({})
36
+
37
+ export const ${camelName}ExternalResolver = resolve<${upperName}, HookContext>({
38
+ ${(0, index_1.localTemplate)(authStrategies, `// The password should never be visible externally
39
+ password: async () => undefined`)}
40
+ })
41
+
42
+ // Schema for creating new users
43
+ export const ${camelName}DataSchema = {
44
+ $id: '${upperName}Data',
45
+ type: 'object',
46
+ additionalProperties: false,
47
+ required: [ ],
48
+ properties: {
49
+ ...${camelName}Schema.properties
50
+ }
51
+ } as const
52
+ export type ${upperName}Data = FromSchema<typeof ${camelName}DataSchema>
53
+ export const ${camelName}DataValidator = getValidator(${camelName}DataSchema, dataValidator)
54
+ export const ${camelName}DataResolver = resolve<${upperName}Data, HookContext>({
55
+ ${(0, index_1.localTemplate)(authStrategies, `password: passwordHash({ strategy: 'local' })`)}
56
+ })
57
+
58
+ // Schema for updating existing users
59
+ export const ${camelName}DataSchema = {
60
+ $id: '${upperName}Patch',
61
+ type: 'object',
62
+ additionalProperties: false,
63
+ required: [],
64
+ properties: {
65
+ ...${camelName}Schema.properties
66
+ }
67
+ } as const
68
+ export type ${upperName}Patch = FromSchema<typeof ${camelName}PatchSchema>
69
+ export const ${camelName}PatchValidator = getValidator(${camelName}PatchSchema, dataValidator)
70
+ export const ${camelName}PatchResolver = resolve<${upperName}Patch, HookContext>({
71
+ ${(0, index_1.localTemplate)(authStrategies, `password: passwordHash({ strategy: 'local' })`)}
72
+ })
73
+
74
+ // Schema for allowed query properties
75
+ export const ${camelName}QuerySchema = {
76
+ $id: '${upperName}Query',
77
+ type: 'object',
78
+ additionalProperties: false,
79
+ properties: {
80
+ ...querySyntax(${camelName}Schema.properties)
81
+ }
82
+ } as const
83
+ export type ${upperName}Query = FromSchema<typeof ${camelName}QuerySchema>
84
+ export const ${camelName}QueryValidator = getValidator(${camelName}QuerySchema, queryValidator)
85
+ export const ${camelName}QueryResolver = resolve<${upperName}Query, HookContext>({
86
+ // If there is a user (e.g. with authentication), they are only allowed to see their own data
87
+ ${type === 'mongodb' ? '_id' : 'id'}: async (value, user, context) => {
88
+ if (context.params.user) {
89
+ return context.params.user.${type === 'mongodb' ? '_id' : 'id'}
90
+ }
91
+
92
+ return value
93
+ }
94
+ })
95
+ `;
96
+ const generate = (ctx) => (0, pinion_1.generator)(ctx).then((0, pinion_1.when)(({ schema }) => schema === 'json', (0, commons_1.renderSource)(template, (0, pinion_1.toFile)(({ lib, folder, fileName }) => [
97
+ lib,
98
+ 'services',
99
+ ...folder,
100
+ `${fileName}.schema`
101
+ ]), { force: true })));
102
+ exports.generate = generate;
103
+ //# sourceMappingURL=schema.json.tpl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.json.tpl.js","sourceRoot":"","sources":["../../../src/authentication/templates/schema.json.tpl.ts"],"names":[],"mappings":";;;AAAA,+CAA4D;AAC5D,2CAAwD;AACxD,oCAAwE;AAExE,MAAM,QAAQ,GAAG,CAAC,EAChB,GAAG,EACH,GAAG,EACH,SAAS,EACT,SAAS,EACT,cAAc,EACd,IAAI,EACJ,QAAQ,EACuB,EAAE,EAAE,CAAC,QAAQ,CAAC;;;EAG7C,IAAA,qBAAa,EAAC,cAAc,EAAE,iEAAiE,CAAC;;oCAE9D,QAAQ;iDACK,QAAQ,IACvD,IAAA,oBAAU,EAAC,GAAG,EAAE,GAAG,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,6CAA6C;AACjG;;;eAGe,SAAS;UACd,SAAS;;;iBAGF,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,IAAI,IAAA,qBAAa,EAAC,cAAc,EAAE,WAAW,CAAC;;MAE1F,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI;eACxB,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ;;MAEjD,cAAc;KACb,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CACZ,IAAI,KAAK,OAAO;IACd,CAAC,CAAC;iCACqB;IACvB,CAAC,CAAC,OAAO,IAAI,wBAAwB,CACxC;KACA,IAAI,CAAC,KAAK,CAAC;;;cAGJ,SAAS,wBAAwB,SAAS;eACzC,SAAS,sBAAsB,SAAS;;eAExC,SAAS,8BAA8B,SAAS;IAC3D,IAAA,qBAAa,EACb,cAAc,EACd;kCAC8B,CAC/B;;;;eAIY,SAAS;UACd,SAAS;;;;;SAKV,SAAS;;;cAGJ,SAAS,4BAA4B,SAAS;eAC7C,SAAS,gCAAgC,SAAS;eAClD,SAAS,0BAA0B,SAAS;IACvD,IAAA,qBAAa,EAAC,cAAc,EAAE,+CAA+C,CAAC;;;;eAInE,SAAS;UACd,SAAS;;;;;SAKV,SAAS;;;cAGJ,SAAS,6BAA6B,SAAS;eAC9C,SAAS,iCAAiC,SAAS;eACnD,SAAS,2BAA2B,SAAS;IACxD,IAAA,qBAAa,EAAC,cAAc,EAAE,+CAA+C,CAAC;;;;eAInE,SAAS;UACd,SAAS;;;;qBAIE,SAAS;;;cAGhB,SAAS,6BAA6B,SAAS;eAC9C,SAAS,iCAAiC,SAAS;eACnD,SAAS,2BAA2B,SAAS;;IAExD,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI;;mCAEF,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI;;;;;;CAMnE,CAAA;AAEM,MAAM,QAAQ,GAAG,CAAC,GAAmC,EAAE,EAAE,CAC9D,IAAA,kBAAS,EAAC,GAAG,CAAC,CAAC,IAAI,CACjB,IAAA,aAAI,EACF,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,MAAM,KAAK,MAAM,EACjC,IAAA,sBAAY,EACV,QAAQ,EACR,IAAA,eAAM,EAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAkC,EAAE,EAAE,CAAC;IACpE,GAAG;IACH,UAAU;IACV,GAAG,MAAM;IACT,GAAG,QAAQ,SAAS;CACrB,CAAC,EACF,EAAE,KAAK,EAAE,IAAI,EAAE,CAChB,CACF,CACF,CAAA;AAfU,QAAA,QAAQ,YAelB"}