@nlabs/reaktor 1.10.0 → 1.11.0

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 (41) hide show
  1. package/README.md +4 -0
  2. package/docs/GENERATION.md +86 -0
  3. package/lib/actions/contentGeneration.d.ts +22 -1
  4. package/lib/actions/contentGeneration.js +84 -16
  5. package/lib/actions/databaseAccounts.d.ts +14 -0
  6. package/lib/actions/databaseAccounts.js +211 -0
  7. package/lib/actions/databaseProvisioningLease.d.ts +6 -0
  8. package/lib/actions/databaseProvisioningLease.js +166 -0
  9. package/lib/actions/higgsfield.d.ts +2 -0
  10. package/lib/actions/higgsfield.js +7 -1
  11. package/lib/actions/imageGeneration.d.ts +5 -1
  12. package/lib/actions/imageGeneration.js +13 -2
  13. package/lib/actions/index.d.ts +2 -0
  14. package/lib/actions/index.js +3 -1
  15. package/lib/actions/videoGeneration.d.ts +5 -1
  16. package/lib/actions/videoGeneration.js +13 -2
  17. package/lib/adapters/higgsfieldAdapter.d.ts +21 -15
  18. package/lib/adapters/higgsfieldAdapter.js +24 -11
  19. package/lib/adapters/higgsfieldModelCatalog.d.ts +10 -0
  20. package/lib/adapters/higgsfieldModelCatalog.js +5363 -0
  21. package/lib/adapters/higgsfieldModels.d.ts +2 -0
  22. package/lib/adapters/higgsfieldModels.js +37 -0
  23. package/lib/index.d.ts +4 -0
  24. package/lib/index.js +4 -1
  25. package/lib/objectTypes/contentGeneration.js +26 -3
  26. package/lib/objectTypes/imageGeneration.js +3 -2
  27. package/lib/objectTypes/videoGeneration.js +2 -1
  28. package/lib/types/databaseCredentials.types.d.ts +30 -0
  29. package/lib/types/databaseCredentials.types.js +3 -0
  30. package/lib/types/index.d.ts +1 -0
  31. package/lib/types/index.js +2 -1
  32. package/lib/utils/databaseCredentials.d.ts +5 -0
  33. package/lib/utils/databaseCredentials.js +100 -0
  34. package/lib/utils/generationCallback.d.ts +23 -0
  35. package/lib/utils/generationCallback.js +49 -0
  36. package/lib/utils/index.d.ts +3 -0
  37. package/lib/utils/index.js +4 -1
  38. package/lib/utils/secretDatabase.d.ts +8 -0
  39. package/lib/utils/secretDatabase.js +153 -0
  40. package/lib/utils/testUtils.js +10 -2
  41. package/package.json +12 -10
@@ -0,0 +1,211 @@
1
+ import { Database } from 'arangojs';
2
+ import { useDb } from '../utils/arangodbUtils.js';
3
+ import { getDatabaseCredentialIdentity, parseDatabaseCredentialSecret } from '../utils/databaseCredentials.js';
4
+ const managedBy = 'reaktor';
5
+ const ownershipKeys = [
6
+ 'appId',
7
+ 'databaseName',
8
+ 'environment',
9
+ 'secretName',
10
+ 'username'
11
+ ];
12
+ // Never pass the caught error's request/body — only its message and ArangoDB error code, which never carry the password.
13
+ const logFailure = (operation, error, context)=>{
14
+ const { errorNum, message, name } = error;
15
+ // eslint-disable-next-line no-console
16
+ console.error(`${operation} failed`, {
17
+ ...context,
18
+ errorNum,
19
+ message,
20
+ name
21
+ });
22
+ };
23
+ export const inspectDatabaseAccount = async (identity)=>{
24
+ const db = useDb('_system');
25
+ try {
26
+ const user = await db.getUser(identity.username);
27
+ const managed = user.active && user.extra?.managedBy === managedBy && ownershipKeys.every((key)=>user.extra[key] === identity[key]);
28
+ const grants = await db.getUserDatabases(identity.username);
29
+ return {
30
+ grants,
31
+ identity: getDatabaseCredentialIdentity(identity),
32
+ managed
33
+ };
34
+ } catch (error) {
35
+ if (error?.errorNum === 1703) {
36
+ return undefined;
37
+ }
38
+ logFailure('inspectDatabaseAccount', error, {
39
+ username: identity.username
40
+ });
41
+ throw new Error('database_account_inspection_failed');
42
+ }
43
+ };
44
+ const requireManaged = async (identity)=>{
45
+ if (!(await inspectDatabaseAccount(identity))?.managed) {
46
+ throw new Error('database_account_conflict');
47
+ }
48
+ };
49
+ export const createManagedDatabaseAccount = async (secret, beforeWrite)=>{
50
+ parseDatabaseCredentialSecret(secret, getDatabaseCredentialIdentity(secret));
51
+ const existing = await inspectDatabaseAccount(secret);
52
+ if (existing) {
53
+ if (!existing.managed) {
54
+ throw new Error('database_account_conflict');
55
+ }
56
+ return;
57
+ }
58
+ await beforeWrite?.();
59
+ try {
60
+ await useDb('_system').createUser(secret.username, {
61
+ active: true,
62
+ extra: Object.fromEntries([
63
+ [
64
+ 'managedBy',
65
+ managedBy
66
+ ],
67
+ ...ownershipKeys.map((key)=>[
68
+ key,
69
+ secret[key]
70
+ ])
71
+ ]),
72
+ passwd: secret.password
73
+ });
74
+ } catch (error) {
75
+ // A lost response or concurrent create is safe only when ownership still matches.
76
+ if (!(await inspectDatabaseAccount(secret))?.managed) {
77
+ logFailure('createManagedDatabaseAccount', error, {
78
+ username: secret.username
79
+ });
80
+ throw new Error('database_account_conflict');
81
+ }
82
+ }
83
+ };
84
+ export const rotateManagedDatabaseAccountPassword = async (secret, beforeWrite)=>{
85
+ parseDatabaseCredentialSecret(secret, getDatabaseCredentialIdentity(secret));
86
+ await requireManaged(secret);
87
+ await beforeWrite?.();
88
+ try {
89
+ await useDb('_system').updateUser(secret.username, secret.password);
90
+ } catch (error) {
91
+ logFailure('rotateManagedDatabaseAccountPassword', error, {
92
+ username: secret.username
93
+ });
94
+ throw new Error('database_account_grants_failed');
95
+ }
96
+ };
97
+ export const restrictDatabaseAccount = async (secret, beforeWrite)=>{
98
+ parseDatabaseCredentialSecret(secret, getDatabaseCredentialIdentity(secret));
99
+ await requireManaged(secret);
100
+ const db = useDb('_system');
101
+ let permissions;
102
+ let databases;
103
+ let collections;
104
+ try {
105
+ permissions = await db.getUserDatabases(secret.username, true);
106
+ databases = await db.listDatabases();
107
+ collections = await useDb(secret.databaseName).listCollections();
108
+ } catch (error) {
109
+ logFailure('restrictDatabaseAccount:read', error, {
110
+ databaseName: secret.databaseName,
111
+ username: secret.username
112
+ });
113
+ throw new Error('database_account_grants_failed');
114
+ }
115
+ const writeGrant = async (database, grant, collection)=>{
116
+ await beforeWrite?.();
117
+ try {
118
+ await db.setUserAccessLevel(secret.username, {
119
+ collection,
120
+ database
121
+ }, grant);
122
+ } catch (error) {
123
+ logFailure('restrictDatabaseAccount:writeGrant', error, {
124
+ collection,
125
+ database,
126
+ username: secret.username
127
+ });
128
+ throw new Error('database_account_grants_failed');
129
+ }
130
+ };
131
+ // Explicitly deny old grants as well as current databases. Never inherit foreign privileges.
132
+ for (const database of new Set([
133
+ '*',
134
+ '_system',
135
+ ...Object.keys(permissions),
136
+ ...databases
137
+ ])){
138
+ if (database === secret.databaseName) {
139
+ continue;
140
+ }
141
+ // eslint-disable-next-line no-await-in-loop
142
+ await writeGrant(database, 'none');
143
+ // ArangoDB refuses any rights change on a system collection (e.g. `_users`), even to deny it.
144
+ for (const collection of new Set([
145
+ '*',
146
+ ...Object.keys(permissions[database]?.collections ?? {}).filter((name)=>!name.startsWith('_'))
147
+ ])){
148
+ // eslint-disable-next-line no-await-in-loop
149
+ await writeGrant(database, 'none', collection);
150
+ }
151
+ }
152
+ await writeGrant(secret.databaseName, 'rw');
153
+ await writeGrant(secret.databaseName, 'none', '*');
154
+ for (const collection of collections){
155
+ // eslint-disable-next-line no-await-in-loop
156
+ await writeGrant(secret.databaseName, 'rw', collection.name);
157
+ }
158
+ };
159
+ export const verifyDatabaseAccount = async (secret)=>{
160
+ await requireManaged(secret);
161
+ parseDatabaseCredentialSecret(secret, getDatabaseCredentialIdentity(secret));
162
+ const db = useDb('_system');
163
+ const client = new Database({
164
+ auth: {
165
+ password: secret.password,
166
+ username: secret.username
167
+ },
168
+ databaseName: secret.databaseName,
169
+ url: `${secret.host}:${secret.port}`
170
+ });
171
+ try {
172
+ const permissions = await db.getUserDatabases(secret.username, true);
173
+ const databases = await db.listDatabases();
174
+ for (const database of new Set([
175
+ '*',
176
+ '_system',
177
+ secret.databaseName,
178
+ ...Object.keys(permissions),
179
+ ...databases
180
+ ])){
181
+ // GET permission endpoints resolve effective access, unlike the raw full grant listing.
182
+ // eslint-disable-next-line no-await-in-loop
183
+ const access = await db.getUserAccessLevel(secret.username, {
184
+ database
185
+ });
186
+ if (access !== (database === secret.databaseName ? 'rw' : 'none')) {
187
+ throw new Error();
188
+ }
189
+ }
190
+ for (const collection of (await useDb(secret.databaseName).listCollections())){
191
+ // eslint-disable-next-line no-await-in-loop
192
+ if (await db.getUserAccessLevel(secret.username, {
193
+ collection: collection.name,
194
+ database: secret.databaseName
195
+ }) !== 'rw') {
196
+ throw new Error();
197
+ }
198
+ }
199
+ await (await client.query('RETURN 1')).all();
200
+ } catch (error) {
201
+ logFailure('verifyDatabaseAccount', error, {
202
+ databaseName: secret.databaseName,
203
+ username: secret.username
204
+ });
205
+ throw new Error('database_account_verification_failed');
206
+ } finally{
207
+ client.close();
208
+ }
209
+ };
210
+
211
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9Vc2Vycy9uaXRyb2c3L0RldmVsb3BtZW50L3JlYWt0b3IvcGFja2FnZXMvcmVha3Rvci9zcmMvYWN0aW9ucy9kYXRhYmFzZUFjY291bnRzLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7RGF0YWJhc2V9IGZyb20gJ2FyYW5nb2pzJztcblxuaW1wb3J0IHt1c2VEYn0gZnJvbSAnLi4vdXRpbHMvYXJhbmdvZGJVdGlscy5qcyc7XG5pbXBvcnQge2dldERhdGFiYXNlQ3JlZGVudGlhbElkZW50aXR5LCBwYXJzZURhdGFiYXNlQ3JlZGVudGlhbFNlY3JldH0gZnJvbSAnLi4vdXRpbHMvZGF0YWJhc2VDcmVkZW50aWFscy5qcyc7XG5cbmltcG9ydCB0eXBlIHtEYXRhYmFzZUNyZWRlbnRpYWxJZGVudGl0eSwgRGF0YWJhc2VDcmVkZW50aWFsU2VjcmV0fSBmcm9tICcuLi90eXBlcy9kYXRhYmFzZUNyZWRlbnRpYWxzLnR5cGVzLmpzJztcblxudHlwZSBBY2Nlc3MgPSAnbm9uZScgfCAncm8nIHwgJ3J3JztcbnR5cGUgQmVmb3JlV3JpdGUgPSAoKSA9PiBQcm9taXNlPHZvaWQ+O1xudHlwZSBBY2NvdW50ID0ge2dyYW50czogUmVhZG9ubHk8UmVjb3JkPHN0cmluZywgQWNjZXNzPj47IGlkZW50aXR5OiBEYXRhYmFzZUNyZWRlbnRpYWxJZGVudGl0eTsgbWFuYWdlZDogYm9vbGVhbn07XG5jb25zdCBtYW5hZ2VkQnkgPSAncmVha3Rvcic7XG5jb25zdCBvd25lcnNoaXBLZXlzID0gWydhcHBJZCcsICdkYXRhYmFzZU5hbWUnLCAnZW52aXJvbm1lbnQnLCAnc2VjcmV0TmFtZScsICd1c2VybmFtZSddIGFzIGNvbnN0O1xuXG4vLyBOZXZlciBwYXNzIHRoZSBjYXVnaHQgZXJyb3IncyByZXF1ZXN0L2JvZHkg4oCUIG9ubHkgaXRzIG1lc3NhZ2UgYW5kIEFyYW5nb0RCIGVycm9yIGNvZGUsIHdoaWNoIG5ldmVyIGNhcnJ5IHRoZSBwYXNzd29yZC5cbmNvbnN0IGxvZ0ZhaWx1cmUgPSAob3BlcmF0aW9uOiBzdHJpbmcsIGVycm9yOiB1bmtub3duLCBjb250ZXh0OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPik6IHZvaWQgPT4ge1xuICBjb25zdCB7ZXJyb3JOdW0sIG1lc3NhZ2UsIG5hbWV9ID0gZXJyb3IgYXMge2Vycm9yTnVtPzogdW5rbm93bjsgbWVzc2FnZT86IHVua25vd247IG5hbWU/OiB1bmtub3dufTtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcbiAgY29uc29sZS5lcnJvcihgJHtvcGVyYXRpb259IGZhaWxlZGAsIHsuLi5jb250ZXh0LCBlcnJvck51bSwgbWVzc2FnZSwgbmFtZX0pO1xufTtcblxuZXhwb3J0IGNvbnN0IGluc3BlY3REYXRhYmFzZUFjY291bnQgPSBhc3luYyAoaWRlbnRpdHk6IERhdGFiYXNlQ3JlZGVudGlhbElkZW50aXR5KTogUHJvbWlzZTxBY2NvdW50IHwgdW5kZWZpbmVkPiA9PiB7XG4gIGNvbnN0IGRiID0gdXNlRGIoJ19zeXN0ZW0nKTtcbiAgdHJ5IHtcbiAgICBjb25zdCB1c2VyID0gYXdhaXQgZGIuZ2V0VXNlcihpZGVudGl0eS51c2VybmFtZSk7XG4gICAgY29uc3QgbWFuYWdlZCA9IHVzZXIuYWN0aXZlICYmIHVzZXIuZXh0cmE/Lm1hbmFnZWRCeSA9PT0gbWFuYWdlZEJ5XG4gICAgICAmJiBvd25lcnNoaXBLZXlzLmV2ZXJ5KChrZXkpID0+IHVzZXIuZXh0cmFba2V5XSA9PT0gaWRlbnRpdHlba2V5XSk7XG4gICAgY29uc3QgZ3JhbnRzID0gYXdhaXQgZGIuZ2V0VXNlckRhdGFiYXNlcyhpZGVudGl0eS51c2VybmFtZSk7XG4gICAgcmV0dXJuIHtncmFudHMsIGlkZW50aXR5OiBnZXREYXRhYmFzZUNyZWRlbnRpYWxJZGVudGl0eShpZGVudGl0eSksIG1hbmFnZWR9O1xuICB9IGNhdGNoKGVycm9yKSB7XG4gICAgaWYoKGVycm9yIGFzIHtlcnJvck51bT86IG51bWJlcn0pPy5lcnJvck51bSA9PT0gMTcwMykge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gICAgbG9nRmFpbHVyZSgnaW5zcGVjdERhdGFiYXNlQWNjb3VudCcsIGVycm9yLCB7dXNlcm5hbWU6IGlkZW50aXR5LnVzZXJuYW1lfSk7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdkYXRhYmFzZV9hY2NvdW50X2luc3BlY3Rpb25fZmFpbGVkJyk7XG4gIH1cbn07XG5cbmNvbnN0IHJlcXVpcmVNYW5hZ2VkID0gYXN5bmMgKGlkZW50aXR5OiBEYXRhYmFzZUNyZWRlbnRpYWxJZGVudGl0eSk6IFByb21pc2U8dm9pZD4gPT4ge1xuICBpZighKGF3YWl0IGluc3BlY3REYXRhYmFzZUFjY291bnQoaWRlbnRpdHkpKT8ubWFuYWdlZCkge1xuICAgIHRocm93IG5ldyBFcnJvcignZGF0YWJhc2VfYWNjb3VudF9jb25mbGljdCcpO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgY3JlYXRlTWFuYWdlZERhdGFiYXNlQWNjb3VudCA9IGFzeW5jIChcbiAgc2VjcmV0OiBEYXRhYmFzZUNyZWRlbnRpYWxTZWNyZXQsIGJlZm9yZVdyaXRlPzogQmVmb3JlV3JpdGVcbik6IFByb21pc2U8dm9pZD4gPT4ge1xuICBwYXJzZURhdGFiYXNlQ3JlZGVudGlhbFNlY3JldChzZWNyZXQsIGdldERhdGFiYXNlQ3JlZGVudGlhbElkZW50aXR5KHNlY3JldCkpO1xuICBjb25zdCBleGlzdGluZyA9IGF3YWl0IGluc3BlY3REYXRhYmFzZUFjY291bnQoc2VjcmV0KTtcbiAgaWYoZXhpc3RpbmcpIHtcbiAgICBpZighZXhpc3RpbmcubWFuYWdlZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdkYXRhYmFzZV9hY2NvdW50X2NvbmZsaWN0Jyk7XG4gICAgfVxuICAgIHJldHVybjtcbiAgfVxuICBhd2FpdCBiZWZvcmVXcml0ZT8uKCk7XG4gIHRyeSB7XG4gICAgYXdhaXQgdXNlRGIoJ19zeXN0ZW0nKS5jcmVhdGVVc2VyKHNlY3JldC51c2VybmFtZSwge1xuICAgICAgYWN0aXZlOiB0cnVlLFxuICAgICAgZXh0cmE6IE9iamVjdC5mcm9tRW50cmllcyhbWydtYW5hZ2VkQnknLCBtYW5hZ2VkQnldLCAuLi5vd25lcnNoaXBLZXlzLm1hcCgoa2V5KSA9PiBba2V5LCBzZWNyZXRba2V5XV0pXSksXG4gICAgICBwYXNzd2Q6IHNlY3JldC5wYXNzd29yZFxuICAgIH0pO1xuICB9IGNhdGNoKGVycm9yKSB7XG4gICAgLy8gQSBsb3N0IHJlc3BvbnNlIG9yIGNvbmN1cnJlbnQgY3JlYXRlIGlzIHNhZmUgb25seSB3aGVuIG93bmVyc2hpcCBzdGlsbCBtYXRjaGVzLlxuICAgIGlmKCEoYXdhaXQgaW5zcGVjdERhdGFiYXNlQWNjb3VudChzZWNyZXQpKT8ubWFuYWdlZCkge1xuICAgICAgbG9nRmFpbHVyZSgnY3JlYXRlTWFuYWdlZERhdGFiYXNlQWNjb3VudCcsIGVycm9yLCB7dXNlcm5hbWU6IHNlY3JldC51c2VybmFtZX0pO1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdkYXRhYmFzZV9hY2NvdW50X2NvbmZsaWN0Jyk7XG4gICAgfVxuICB9XG59O1xuXG5leHBvcnQgY29uc3Qgcm90YXRlTWFuYWdlZERhdGFiYXNlQWNjb3VudFBhc3N3b3JkID0gYXN5bmMgKFxuICBzZWNyZXQ6IERhdGFiYXNlQ3JlZGVudGlhbFNlY3JldCwgYmVmb3JlV3JpdGU/OiBCZWZvcmVXcml0ZVxuKTogUHJvbWlzZTx2b2lkPiA9PiB7XG4gIHBhcnNlRGF0YWJhc2VDcmVkZW50aWFsU2VjcmV0KHNlY3JldCwgZ2V0RGF0YWJhc2VDcmVkZW50aWFsSWRlbnRpdHkoc2VjcmV0KSk7XG4gIGF3YWl0IHJlcXVpcmVNYW5hZ2VkKHNlY3JldCk7XG4gIGF3YWl0IGJlZm9yZVdyaXRlPy4oKTtcbiAgdHJ5IHtcbiAgICBhd2FpdCB1c2VEYignX3N5c3RlbScpLnVwZGF0ZVVzZXIoc2VjcmV0LnVzZXJuYW1lLCBzZWNyZXQucGFzc3dvcmQpO1xuICB9IGNhdGNoKGVycm9yKSB7XG4gICAgbG9nRmFpbHVyZSgncm90YXRlTWFuYWdlZERhdGFiYXNlQWNjb3VudFBhc3N3b3JkJywgZXJyb3IsIHt1c2VybmFtZTogc2VjcmV0LnVzZXJuYW1lfSk7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdkYXRhYmFzZV9hY2NvdW50X2dyYW50c19mYWlsZWQnKTtcbiAgfVxufTtcblxuZXhwb3J0IGNvbnN0IHJlc3RyaWN0RGF0YWJhc2VBY2NvdW50ID0gYXN5bmMgKFxuICBzZWNyZXQ6IERhdGFiYXNlQ3JlZGVudGlhbFNlY3JldCwgYmVmb3JlV3JpdGU/OiBCZWZvcmVXcml0ZVxuKTogUHJvbWlzZTx2b2lkPiA9PiB7XG4gIHBhcnNlRGF0YWJhc2VDcmVkZW50aWFsU2VjcmV0KHNlY3JldCwgZ2V0RGF0YWJhc2VDcmVkZW50aWFsSWRlbnRpdHkoc2VjcmV0KSk7XG4gIGF3YWl0IHJlcXVpcmVNYW5hZ2VkKHNlY3JldCk7XG4gIGNvbnN0IGRiID0gdXNlRGIoJ19zeXN0ZW0nKTtcbiAgbGV0IHBlcm1pc3Npb25zOiBBd2FpdGVkPFJldHVyblR5cGU8dHlwZW9mIGRiLmdldFVzZXJEYXRhYmFzZXM+PjtcbiAgbGV0IGRhdGFiYXNlczogc3RyaW5nW107XG4gIGxldCBjb2xsZWN0aW9uczoge25hbWU6IHN0cmluZ31bXTtcbiAgdHJ5IHtcbiAgICBwZXJtaXNzaW9ucyA9IGF3YWl0IGRiLmdldFVzZXJEYXRhYmFzZXMoc2VjcmV0LnVzZXJuYW1lLCB0cnVlKTtcbiAgICBkYXRhYmFzZXMgPSBhd2FpdCBkYi5saXN0RGF0YWJhc2VzKCk7XG4gICAgY29sbGVjdGlvbnMgPSBhd2FpdCB1c2VEYihzZWNyZXQuZGF0YWJhc2VOYW1lKS5saXN0Q29sbGVjdGlvbnMoKTtcbiAgfSBjYXRjaChlcnJvcikge1xuICAgIGxvZ0ZhaWx1cmUoJ3Jlc3RyaWN0RGF0YWJhc2VBY2NvdW50OnJlYWQnLCBlcnJvciwge2RhdGFiYXNlTmFtZTogc2VjcmV0LmRhdGFiYXNlTmFtZSwgdXNlcm5hbWU6IHNlY3JldC51c2VybmFtZX0pO1xuICAgIHRocm93IG5ldyBFcnJvcignZGF0YWJhc2VfYWNjb3VudF9ncmFudHNfZmFpbGVkJyk7XG4gIH1cbiAgY29uc3Qgd3JpdGVHcmFudCA9IGFzeW5jIChkYXRhYmFzZTogc3RyaW5nLCBncmFudDogQWNjZXNzLCBjb2xsZWN0aW9uPzogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiA9PiB7XG4gICAgYXdhaXQgYmVmb3JlV3JpdGU/LigpO1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCBkYi5zZXRVc2VyQWNjZXNzTGV2ZWwoc2VjcmV0LnVzZXJuYW1lLCB7Y29sbGVjdGlvbiwgZGF0YWJhc2V9LCBncmFudCk7XG4gICAgfSBjYXRjaChlcnJvcikge1xuICAgICAgbG9nRmFpbHVyZSgncmVzdHJpY3REYXRhYmFzZUFjY291bnQ6d3JpdGVHcmFudCcsIGVycm9yLCB7Y29sbGVjdGlvbiwgZGF0YWJhc2UsIHVzZXJuYW1lOiBzZWNyZXQudXNlcm5hbWV9KTtcbiAgICAgIHRocm93IG5ldyBFcnJvcignZGF0YWJhc2VfYWNjb3VudF9ncmFudHNfZmFpbGVkJyk7XG4gICAgfVxuICB9O1xuICAvLyBFeHBsaWNpdGx5IGRlbnkgb2xkIGdyYW50cyBhcyB3ZWxsIGFzIGN1cnJlbnQgZGF0YWJhc2VzLiBOZXZlciBpbmhlcml0IGZvcmVpZ24gcHJpdmlsZWdlcy5cbiAgZm9yKGNvbnN0IGRhdGFiYXNlIG9mIG5ldyBTZXQoWycqJywgJ19zeXN0ZW0nLCAuLi5PYmplY3Qua2V5cyhwZXJtaXNzaW9ucyksIC4uLmRhdGFiYXNlc10pKSB7XG4gICAgaWYoZGF0YWJhc2UgPT09IHNlY3JldC5kYXRhYmFzZU5hbWUpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tYXdhaXQtaW4tbG9vcFxuICAgIGF3YWl0IHdyaXRlR3JhbnQoZGF0YWJhc2UsICdub25lJyk7XG4gICAgLy8gQXJhbmdvREIgcmVmdXNlcyBhbnkgcmlnaHRzIGNoYW5nZSBvbiBhIHN5c3RlbSBjb2xsZWN0aW9uIChlLmcuIGBfdXNlcnNgKSwgZXZlbiB0byBkZW55IGl0LlxuICAgIGZvcihjb25zdCBjb2xsZWN0aW9uIG9mIG5ldyBTZXQoWycqJywgLi4uT2JqZWN0LmtleXMocGVybWlzc2lvbnNbZGF0YWJhc2VdPy5jb2xsZWN0aW9ucyA/PyB7fSkuZmlsdGVyKChuYW1lKSA9PiAhbmFtZS5zdGFydHNXaXRoKCdfJykpXSkpIHtcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1hd2FpdC1pbi1sb29wXG4gICAgICBhd2FpdCB3cml0ZUdyYW50KGRhdGFiYXNlLCAnbm9uZScsIGNvbGxlY3Rpb24pO1xuICAgIH1cbiAgfVxuICBhd2FpdCB3cml0ZUdyYW50KHNlY3JldC5kYXRhYmFzZU5hbWUsICdydycpO1xuICBhd2FpdCB3cml0ZUdyYW50KHNlY3JldC5kYXRhYmFzZU5hbWUsICdub25lJywgJyonKTtcbiAgZm9yKGNvbnN0IGNvbGxlY3Rpb24gb2YgY29sbGVjdGlvbnMpIHtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tYXdhaXQtaW4tbG9vcFxuICAgIGF3YWl0IHdyaXRlR3JhbnQoc2VjcmV0LmRhdGFiYXNlTmFtZSwgJ3J3JywgY29sbGVjdGlvbi5uYW1lKTtcbiAgfVxufTtcblxuZXhwb3J0IGNvbnN0IHZlcmlmeURhdGFiYXNlQWNjb3VudCA9IGFzeW5jIChzZWNyZXQ6IERhdGFiYXNlQ3JlZGVudGlhbFNlY3JldCk6IFByb21pc2U8dm9pZD4gPT4ge1xuICBhd2FpdCByZXF1aXJlTWFuYWdlZChzZWNyZXQpO1xuICBwYXJzZURhdGFiYXNlQ3JlZGVudGlhbFNlY3JldChzZWNyZXQsIGdldERhdGFiYXNlQ3JlZGVudGlhbElkZW50aXR5KHNlY3JldCkpO1xuICBjb25zdCBkYiA9IHVzZURiKCdfc3lzdGVtJyk7XG4gIGNvbnN0IGNsaWVudCA9IG5ldyBEYXRhYmFzZSh7XG4gICAgYXV0aDoge3Bhc3N3b3JkOiBzZWNyZXQucGFzc3dvcmQsIHVzZXJuYW1lOiBzZWNyZXQudXNlcm5hbWV9LFxuICAgIGRhdGFiYXNlTmFtZTogc2VjcmV0LmRhdGFiYXNlTmFtZSxcbiAgICB1cmw6IGAke3NlY3JldC5ob3N0fToke3NlY3JldC5wb3J0fWBcbiAgfSk7XG4gIHRyeSB7XG4gICAgY29uc3QgcGVybWlzc2lvbnMgPSBhd2FpdCBkYi5nZXRVc2VyRGF0YWJhc2VzKHNlY3JldC51c2VybmFtZSwgdHJ1ZSk7XG4gICAgY29uc3QgZGF0YWJhc2VzID0gYXdhaXQgZGIubGlzdERhdGFiYXNlcygpO1xuICAgIGZvcihjb25zdCBkYXRhYmFzZSBvZiBuZXcgU2V0KFsnKicsICdfc3lzdGVtJywgc2VjcmV0LmRhdGFiYXNlTmFtZSwgLi4uT2JqZWN0LmtleXMocGVybWlzc2lvbnMpLCAuLi5kYXRhYmFzZXNdKSkge1xuICAgICAgLy8gR0VUIHBlcm1pc3Npb24gZW5kcG9pbnRzIHJlc29sdmUgZWZmZWN0aXZlIGFjY2VzcywgdW5saWtlIHRoZSByYXcgZnVsbCBncmFudCBsaXN0aW5nLlxuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWF3YWl0LWluLWxvb3BcbiAgICAgIGNvbnN0IGFjY2VzcyA9IGF3YWl0IGRiLmdldFVzZXJBY2Nlc3NMZXZlbChzZWNyZXQudXNlcm5hbWUsIHtkYXRhYmFzZX0pO1xuICAgICAgaWYoYWNjZXNzICE9PSAoZGF0YWJhc2UgPT09IHNlY3JldC5kYXRhYmFzZU5hbWUgPyAncncnIDogJ25vbmUnKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoKTtcbiAgICAgIH1cbiAgICB9XG4gICAgZm9yKGNvbnN0IGNvbGxlY3Rpb24gb2YgYXdhaXQgdXNlRGIoc2VjcmV0LmRhdGFiYXNlTmFtZSkubGlzdENvbGxlY3Rpb25zKCkpIHtcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1hd2FpdC1pbi1sb29wXG4gICAgICBpZihhd2FpdCBkYi5nZXRVc2VyQWNjZXNzTGV2ZWwoc2VjcmV0LnVzZXJuYW1lLCB7Y29sbGVjdGlvbjogY29sbGVjdGlvbi5uYW1lLCBkYXRhYmFzZTogc2VjcmV0LmRhdGFiYXNlTmFtZX0pICE9PSAncncnKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcigpO1xuICAgICAgfVxuICAgIH1cbiAgICBhd2FpdCAoYXdhaXQgY2xpZW50LnF1ZXJ5KCdSRVRVUk4gMScpKS5hbGwoKTtcbiAgfSBjYXRjaChlcnJvcikge1xuICAgIGxvZ0ZhaWx1cmUoJ3ZlcmlmeURhdGFiYXNlQWNjb3VudCcsIGVycm9yLCB7ZGF0YWJhc2VOYW1lOiBzZWNyZXQuZGF0YWJhc2VOYW1lLCB1c2VybmFtZTogc2VjcmV0LnVzZXJuYW1lfSk7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdkYXRhYmFzZV9hY2NvdW50X3ZlcmlmaWNhdGlvbl9mYWlsZWQnKTtcbiAgfSBmaW5hbGx5IHtcbiAgICBjbGllbnQuY2xvc2UoKTtcbiAgfVxufTtcbiJdLCJuYW1lcyI6WyJEYXRhYmFzZSIsInVzZURiIiwiZ2V0RGF0YWJhc2VDcmVkZW50aWFsSWRlbnRpdHkiLCJwYXJzZURhdGFiYXNlQ3JlZGVudGlhbFNlY3JldCIsIm1hbmFnZWRCeSIsIm93bmVyc2hpcEtleXMiLCJsb2dGYWlsdXJlIiwib3BlcmF0aW9uIiwiZXJyb3IiLCJjb250ZXh0IiwiZXJyb3JOdW0iLCJtZXNzYWdlIiwibmFtZSIsImNvbnNvbGUiLCJpbnNwZWN0RGF0YWJhc2VBY2NvdW50IiwiaWRlbnRpdHkiLCJkYiIsInVzZXIiLCJnZXRVc2VyIiwidXNlcm5hbWUiLCJtYW5hZ2VkIiwiYWN0aXZlIiwiZXh0cmEiLCJldmVyeSIsImtleSIsImdyYW50cyIsImdldFVzZXJEYXRhYmFzZXMiLCJ1bmRlZmluZWQiLCJFcnJvciIsInJlcXVpcmVNYW5hZ2VkIiwiY3JlYXRlTWFuYWdlZERhdGFiYXNlQWNjb3VudCIsInNlY3JldCIsImJlZm9yZVdyaXRlIiwiZXhpc3RpbmciLCJjcmVhdGVVc2VyIiwiT2JqZWN0IiwiZnJvbUVudHJpZXMiLCJtYXAiLCJwYXNzd2QiLCJwYXNzd29yZCIsInJvdGF0ZU1hbmFnZWREYXRhYmFzZUFjY291bnRQYXNzd29yZCIsInVwZGF0ZVVzZXIiLCJyZXN0cmljdERhdGFiYXNlQWNjb3VudCIsInBlcm1pc3Npb25zIiwiZGF0YWJhc2VzIiwiY29sbGVjdGlvbnMiLCJsaXN0RGF0YWJhc2VzIiwiZGF0YWJhc2VOYW1lIiwibGlzdENvbGxlY3Rpb25zIiwid3JpdGVHcmFudCIsImRhdGFiYXNlIiwiZ3JhbnQiLCJjb2xsZWN0aW9uIiwic2V0VXNlckFjY2Vzc0xldmVsIiwiU2V0Iiwia2V5cyIsImZpbHRlciIsInN0YXJ0c1dpdGgiLCJ2ZXJpZnlEYXRhYmFzZUFjY291bnQiLCJjbGllbnQiLCJhdXRoIiwidXJsIiwiaG9zdCIsInBvcnQiLCJhY2Nlc3MiLCJnZXRVc2VyQWNjZXNzTGV2ZWwiLCJxdWVyeSIsImFsbCIsImNsb3NlIl0sIm1hcHBpbmdzIjoiQUFBQSxTQUFRQSxRQUFRLFFBQU8sV0FBVztBQUVsQyxTQUFRQyxLQUFLLFFBQU8sNEJBQTRCO0FBQ2hELFNBQVFDLDZCQUE2QixFQUFFQyw2QkFBNkIsUUFBTyxrQ0FBa0M7QUFPN0csTUFBTUMsWUFBWTtBQUNsQixNQUFNQyxnQkFBZ0I7SUFBQztJQUFTO0lBQWdCO0lBQWU7SUFBYztDQUFXO0FBRXhGLHlIQUF5SDtBQUN6SCxNQUFNQyxhQUFhLENBQUNDLFdBQW1CQyxPQUFnQkM7SUFDckQsTUFBTSxFQUFDQyxRQUFRLEVBQUVDLE9BQU8sRUFBRUMsSUFBSSxFQUFDLEdBQUdKO0lBQ2xDLHNDQUFzQztJQUN0Q0ssUUFBUUwsS0FBSyxDQUFDLEdBQUdELFVBQVUsT0FBTyxDQUFDLEVBQUU7UUFBQyxHQUFHRSxPQUFPO1FBQUVDO1FBQVVDO1FBQVNDO0lBQUk7QUFDM0U7QUFFQSxPQUFPLE1BQU1FLHlCQUF5QixPQUFPQztJQUMzQyxNQUFNQyxLQUFLZixNQUFNO0lBQ2pCLElBQUk7UUFDRixNQUFNZ0IsT0FBTyxNQUFNRCxHQUFHRSxPQUFP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
@@ -0,0 +1,6 @@
1
+ import type { ApiContext } from '../types/auth.types.js';
2
+ import type { DatabaseConnectionMetadata, DatabaseCredentialIdentity, DatabaseProvisioningLease } from '../types/databaseCredentials.types.js';
3
+ export declare const acquireDatabaseProvisioningLease: (context: ApiContext, identity: DatabaseCredentialIdentity) => Promise<DatabaseProvisioningLease>;
4
+ export declare const renewDatabaseProvisioningLease: (context: ApiContext, lease: DatabaseProvisioningLease) => Promise<DatabaseProvisioningLease>;
5
+ export declare const releaseDatabaseProvisioningLease: (context: ApiContext, lease: DatabaseProvisioningLease) => Promise<void>;
6
+ export declare const saveDatabaseProvisioningState: (context: ApiContext, lease: DatabaseProvisioningLease, metadata: DatabaseConnectionMetadata) => Promise<void>;
@@ -0,0 +1,166 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { useDb } from '../utils/arangodbUtils.js';
3
+ const collectionName = 'databaseProvisioningLeases';
4
+ const ttlMs = 120_000;
5
+ const collectionBind = {
6
+ '@collection': collectionName
7
+ };
8
+ const getControlDb = (context)=>{
9
+ if (!context.databaseName) {
10
+ throw new Error('database_provisioning_control_database_required');
11
+ }
12
+ return useDb(context.databaseName);
13
+ };
14
+ const isErrorNumber = (error, ...codes)=>codes.includes(error?.errorNum ?? -1);
15
+ const toLease = (row)=>({
16
+ expiresAt: row.expiresAt,
17
+ // eslint-disable-next-line no-underscore-dangle
18
+ key: row._key,
19
+ owner: row.owner
20
+ });
21
+ const runQuery = async (context, query, bindVars)=>{
22
+ const cursor = await getControlDb(context).query({
23
+ bindVars: {
24
+ ...collectionBind,
25
+ ...bindVars
26
+ },
27
+ query
28
+ });
29
+ return cursor.all();
30
+ };
31
+ const fencedQuery = `
32
+ FOR doc IN @@collection
33
+ FILTER doc._key == @key AND doc.owner == @owner AND doc.expiresAt > DATE_NOW()
34
+ UPDATE {_key: doc._key, _rev: doc._rev} WITH `;
35
+ export const acquireDatabaseProvisioningLease = async (context, identity)=>{
36
+ const key = `${identity.appId}-${identity.environment}`;
37
+ const owner = randomUUID();
38
+ if (!context.databaseName) {
39
+ throw new Error('database_provisioning_control_database_required');
40
+ }
41
+ try {
42
+ await getControlDb(context).collection(collectionName).create();
43
+ } catch (error) {
44
+ if (!isErrorNumber(error, 1207)) {
45
+ throw new Error('database_provisioning_error');
46
+ }
47
+ }
48
+ try {
49
+ const rows = await runQuery(context, `
50
+ INSERT {_key: @key, owner: @owner, expiresAt: DATE_NOW() + @ttlMs}
51
+ INTO @@collection RETURN NEW
52
+ `, {
53
+ key,
54
+ owner,
55
+ ttlMs
56
+ });
57
+ return toLease(rows[0]);
58
+ } catch (error) {
59
+ if (!isErrorNumber(error, 1210)) {
60
+ throw new Error('database_provisioning_error');
61
+ }
62
+ }
63
+ for(let attempt = 0; attempt < 3; attempt++){
64
+ try {
65
+ // A write conflict means another owner may have taken over; retry the fenced update.
66
+ // eslint-disable-next-line no-await-in-loop
67
+ const rows = await runQuery(context, `
68
+ FOR doc IN @@collection
69
+ FILTER doc._key == @key AND doc.expiresAt <= DATE_NOW()
70
+ UPDATE {_key: doc._key, _rev: doc._rev} WITH
71
+ {owner: @owner, expiresAt: DATE_NOW() + @ttlMs}
72
+ IN @@collection OPTIONS {ignoreRevs: false}
73
+ RETURN NEW
74
+ `, {
75
+ key,
76
+ owner,
77
+ ttlMs
78
+ });
79
+ if (rows[0]) {
80
+ return toLease(rows[0]);
81
+ }
82
+ throw new Error('database_provisioning_busy');
83
+ } catch (error) {
84
+ if (isErrorNumber(error, 1200) && attempt < 2) {
85
+ continue;
86
+ }
87
+ if (error instanceof Error && error.message === 'database_provisioning_busy') {
88
+ throw error;
89
+ }
90
+ throw new Error('database_provisioning_error');
91
+ }
92
+ }
93
+ throw new Error('database_provisioning_busy');
94
+ };
95
+ export const renewDatabaseProvisioningLease = async (context, lease)=>{
96
+ try {
97
+ const rows = await runQuery(context, `${fencedQuery}
98
+ {expiresAt: DATE_NOW() + @ttlMs}
99
+ IN @@collection OPTIONS {ignoreRevs: false} RETURN NEW
100
+ `, {
101
+ key: lease.key,
102
+ owner: lease.owner,
103
+ ttlMs
104
+ });
105
+ if (!rows[0]) {
106
+ throw new Error('database_provisioning_lease_lost');
107
+ }
108
+ return toLease(rows[0]);
109
+ } catch (error) {
110
+ if (error instanceof Error && error.message === 'database_provisioning_lease_lost') {
111
+ throw error;
112
+ }
113
+ throw new Error('database_provisioning_error');
114
+ }
115
+ };
116
+ export const releaseDatabaseProvisioningLease = async (context, lease)=>{
117
+ try {
118
+ const rows = await runQuery(context, `${fencedQuery}
119
+ {owner: null, expiresAt: 0}
120
+ IN @@collection OPTIONS {ignoreRevs: false} RETURN NEW
121
+ `, {
122
+ key: lease.key,
123
+ owner: lease.owner
124
+ });
125
+ if (!rows[0]) {
126
+ throw new Error('database_provisioning_lease_lost');
127
+ }
128
+ } catch (error) {
129
+ if (error instanceof Error && error.message === 'database_provisioning_lease_lost') {
130
+ throw error;
131
+ }
132
+ throw new Error('database_provisioning_error');
133
+ }
134
+ };
135
+ export const saveDatabaseProvisioningState = async (context, lease, metadata)=>{
136
+ const safeMetadata = {
137
+ appId: metadata.appId,
138
+ databaseName: metadata.databaseName,
139
+ environment: metadata.environment,
140
+ host: metadata.host,
141
+ port: metadata.port,
142
+ secretArn: metadata.secretArn,
143
+ secretName: metadata.secretName,
144
+ status: metadata.status,
145
+ username: metadata.username
146
+ };
147
+ try {
148
+ const rows = await runQuery(context, `${fencedQuery}
149
+ @metadata IN @@collection OPTIONS {ignoreRevs: false} RETURN NEW
150
+ `, {
151
+ key: lease.key,
152
+ metadata: safeMetadata,
153
+ owner: lease.owner
154
+ });
155
+ if (!rows[0]) {
156
+ throw new Error('database_provisioning_lease_lost');
157
+ }
158
+ } catch (error) {
159
+ if (error instanceof Error && error.message === 'database_provisioning_lease_lost') {
160
+ throw error;
161
+ }
162
+ throw new Error('database_provisioning_error');
163
+ }
164
+ };
165
+
166
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9Vc2Vycy9uaXRyb2c3L0RldmVsb3BtZW50L3JlYWt0b3IvcGFja2FnZXMvcmVha3Rvci9zcmMvYWN0aW9ucy9kYXRhYmFzZVByb3Zpc2lvbmluZ0xlYXNlLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7cmFuZG9tVVVJRH0gZnJvbSAnbm9kZTpjcnlwdG8nO1xuXG5pbXBvcnQge3VzZURifSBmcm9tICcuLi91dGlscy9hcmFuZ29kYlV0aWxzLmpzJztcblxuaW1wb3J0IHR5cGUge0FwaUNvbnRleHR9IGZyb20gJy4uL3R5cGVzL2F1dGgudHlwZXMuanMnO1xuaW1wb3J0IHR5cGUge0RhdGFiYXNlQ29ubmVjdGlvbk1ldGFkYXRhLCBEYXRhYmFzZUNyZWRlbnRpYWxJZGVudGl0eSwgRGF0YWJhc2VQcm92aXNpb25pbmdMZWFzZX0gZnJvbSAnLi4vdHlwZXMvZGF0YWJhc2VDcmVkZW50aWFscy50eXBlcy5qcyc7XG5cbmNvbnN0IGNvbGxlY3Rpb25OYW1lID0gJ2RhdGFiYXNlUHJvdmlzaW9uaW5nTGVhc2VzJztcbmNvbnN0IHR0bE1zID0gMTIwXzAwMDtcbmNvbnN0IGNvbGxlY3Rpb25CaW5kID0geydAY29sbGVjdGlvbic6IGNvbGxlY3Rpb25OYW1lfTtcblxudHlwZSBMZWFzZVJvdyA9IHtfa2V5OiBzdHJpbmc7IG93bmVyOiBzdHJpbmc7IGV4cGlyZXNBdDogbnVtYmVyfTtcbnR5cGUgRGF0YWJhc2VFcnJvciA9IHtlcnJvck51bT86IG51bWJlcn07XG5cbmNvbnN0IGdldENvbnRyb2xEYiA9IChjb250ZXh0OiBBcGlDb250ZXh0KSA9PiB7XG4gIGlmKCFjb250ZXh0LmRhdGFiYXNlTmFtZSkge1xuICAgIHRocm93IG5ldyBFcnJvcignZGF0YWJhc2VfcHJvdmlzaW9uaW5nX2NvbnRyb2xfZGF0YWJhc2VfcmVxdWlyZWQnKTtcbiAgfVxuICByZXR1cm4gdXNlRGIoY29udGV4dC5kYXRhYmFzZU5hbWUpO1xufTtcblxuY29uc3QgaXNFcnJvck51bWJlciA9IChlcnJvcjogdW5rbm93biwgLi4uY29kZXM6IG51bWJlcltdKTogYm9vbGVhbiA9PlxuICBjb2Rlcy5pbmNsdWRlcygoZXJyb3IgYXMgRGF0YWJhc2VFcnJvciB8IG51bGwpPy5lcnJvck51bSA/PyAtMSk7XG5cbmNvbnN0IHRvTGVhc2UgPSAocm93OiBMZWFzZVJvdyk6IERhdGFiYXNlUHJvdmlzaW9uaW5nTGVhc2UgPT4gKHtcbiAgZXhwaXJlc0F0OiByb3cuZXhwaXJlc0F0LFxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW5kZXJzY29yZS1kYW5nbGVcbiAga2V5OiByb3cuX2tleSxcbiAgb3duZXI6IHJvdy5vd25lclxufSk7XG5cbmNvbnN0IHJ1blF1ZXJ5ID0gYXN5bmMgKGNvbnRleHQ6IEFwaUNvbnRleHQsIHF1ZXJ5OiBzdHJpbmcsIGJpbmRWYXJzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPik6IFByb21pc2U8TGVhc2VSb3dbXT4gPT4ge1xuICBjb25zdCBjdXJzb3IgPSBhd2FpdCBnZXRDb250cm9sRGIoY29udGV4dCkucXVlcnk8TGVhc2VSb3c+KHtiaW5kVmFyczogey4uLmNvbGxlY3Rpb25CaW5kLCAuLi5iaW5kVmFyc30sIHF1ZXJ5fSk7XG4gIHJldHVybiBjdXJzb3IuYWxsKCk7XG59O1xuXG5jb25zdCBmZW5jZWRRdWVyeSA9IGBcbiAgRk9SIGRvYyBJTiBAQGNvbGxlY3Rpb25cbiAgICBGSUxURVIgZG9jLl9rZXkgPT0gQGtleSBBTkQgZG9jLm93bmVyID09IEBvd25lciBBTkQgZG9jLmV4cGlyZXNBdCA+IERBVEVfTk9XKClcbiAgICBVUERBVEUge19rZXk6IGRvYy5fa2V5LCBfcmV2OiBkb2MuX3Jldn0gV0lUSCBgO1xuXG5leHBvcnQgY29uc3QgYWNxdWlyZURhdGFiYXNlUHJvdmlzaW9uaW5nTGVhc2UgPSBhc3luYyAoXG4gIGNvbnRleHQ6IEFwaUNvbnRleHQsXG4gIGlkZW50aXR5OiBEYXRhYmFzZUNyZWRlbnRpYWxJZGVudGl0eVxuKTogUHJvbWlzZTxEYXRhYmFzZVByb3Zpc2lvbmluZ0xlYXNlPiA9PiB7XG4gIGNvbnN0IGtleSA9IGAke2lkZW50aXR5LmFwcElkfS0ke2lkZW50aXR5LmVudmlyb25tZW50fWA7XG4gIGNvbnN0IG93bmVyID0gcmFuZG9tVVVJRCgpO1xuICBpZighY29udGV4dC5kYXRhYmFzZU5hbWUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2RhdGFiYXNlX3Byb3Zpc2lvbmluZ19jb250cm9sX2RhdGFiYXNlX3JlcXVpcmVkJyk7XG4gIH1cbiAgdHJ5IHtcbiAgICBhd2FpdCBnZXRDb250cm9sRGIoY29udGV4dCkuY29sbGVjdGlvbihjb2xsZWN0aW9uTmFtZSkuY3JlYXRlKCk7XG4gIH0gY2F0Y2goZXJyb3IpIHtcbiAgICBpZighaXNFcnJvck51bWJlcihlcnJvciwgMTIwNykpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignZGF0YWJhc2VfcHJvdmlzaW9uaW5nX2Vycm9yJyk7XG4gICAgfVxuICB9XG4gIHRyeSB7XG4gICAgY29uc3Qgcm93cyA9IGF3YWl0IHJ1blF1ZXJ5KGNvbnRleHQsIGBcbiAgICAgIElOU0VSVCB7X2tleTogQGtleSwgb3duZXI6IEBvd25lciwgZXhwaXJlc0F0OiBEQVRFX05PVygpICsgQHR0bE1zfVxuICAgICAgSU5UTyBAQGNvbGxlY3Rpb24gUkVUVVJOIE5FV1xuICAgIGAsIHtrZXksIG93bmVyLCB0dGxNc30pO1xuICAgIHJldHVybiB0b0xlYXNlKHJvd3NbMF0pO1xuICB9IGNhdGNoKGVycm9yKSB7XG4gICAgaWYoIWlzRXJyb3JOdW1iZXIoZXJyb3IsIDEyMTApKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2RhdGFiYXNlX3Byb3Zpc2lvbmluZ19lcnJvcicpO1xuICAgIH1cbiAgfVxuICBmb3IobGV0IGF0dGVtcHQgPSAwOyBhdHRlbXB0IDwgMzsgYXR0ZW1wdCsrKSB7XG4gICAgdHJ5IHtcbiAgICAgIC8vIEEgd3JpdGUgY29uZmxpY3QgbWVhbnMgYW5vdGhlciBvd25lciBtYXkgaGF2ZSB0YWtlbiBvdmVyOyByZXRyeSB0aGUgZmVuY2VkIHVwZGF0ZS5cbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1hd2FpdC1pbi1sb29wXG4gICAgICBjb25zdCByb3dzID0gYXdhaXQgcnVuUXVlcnkoY29udGV4dCwgYFxuICAgICAgICBGT1IgZG9jIElOIEBAY29sbGVjdGlvblxuICAgICAgICAgIEZJTFRFUiBkb2MuX2tleSA9PSBAa2V5IEFORCBkb2MuZXhwaXJlc0F0IDw9IERBVEVfTk9XKClcbiAgICAgICAgICBVUERBVEUge19rZXk6IGRvYy5fa2V5LCBfcmV2OiBkb2MuX3Jldn0gV0lUSFxuICAgICAgICAgICAge293bmVyOiBAb3duZXIsIGV4cGlyZXNBdDogREFURV9OT1coKSArIEB0dGxNc31cbiAgICAgICAgICBJTiBAQGNvbGxlY3Rpb24gT1BUSU9OUyB7aWdub3JlUmV2czogZmFsc2V9XG4gICAgICAgICAgUkVUVVJOIE5FV1xuICAgICAgYCwge2tleSwgb3duZXIsIHR0bE1zfSk7XG4gICAgICBpZihyb3dzWzBdKSB7XG4gICAgICAgIHJldHVybiB0b0xlYXNlKHJvd3NbMF0pO1xuICAgICAgfVxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdkYXRhYmFzZV9wcm92aXNpb25pbmdfYnVzeScpO1xuICAgIH0gY2F0Y2goZXJyb3IpIHtcbiAgICAgIGlmKGlzRXJyb3JOdW1iZXIoZXJyb3IsIDEyMDApICYmIGF0dGVtcHQgPCAyKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgaWYoZXJyb3IgaW5zdGFuY2VvZiBFcnJvciAmJiBlcnJvci5tZXNzYWdlID09PSAnZGF0YWJhc2VfcHJvdmlzaW9uaW5nX2J1c3knKSB7XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfVxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdkYXRhYmFzZV9wcm92aXNpb25pbmdfZXJyb3InKTtcbiAgICB9XG4gIH1cbiAgdGhyb3cgbmV3IEVycm9yKCdkYXRhYmFzZV9wcm92aXNpb25pbmdfYnVzeScpO1xufTtcblxuZXhwb3J0IGNvbnN0IHJlbmV3RGF0YWJhc2VQcm92aXNpb25pbmdMZWFzZSA9IGFzeW5jIChcbiAgY29udGV4dDogQXBpQ29udGV4dCxcbiAgbGVhc2U6IERhdGFiYXNlUHJvdmlzaW9uaW5nTGVhc2Vcbik6IFByb21pc2U8RGF0YWJhc2VQcm92aXNpb25pbmdMZWFzZT4gPT4ge1xuICB0cnkge1xuICAgIGNvbnN0IHJvd3MgPSBhd2FpdCBydW5RdWVyeShjb250ZXh0LCBgJHtmZW5jZWRRdWVyeX1cbiAgICAgIHtleHBpcmVzQXQ6IERBVEVfTk9XKCkgKyBAdHRsTXN9XG4gICAgICBJTiBAQGNvbGxlY3Rpb24gT1BUSU9OUyB7aWdub3JlUmV2czogZmFsc2V9IFJFVFVSTiBORVdcbiAgICBgLCB7a2V5OiBsZWFzZS5rZXksIG93bmVyOiBsZWFzZS5vd25lciwgdHRsTXN9KTtcbiAgICBpZighcm93c1swXSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdkYXRhYmFzZV9wcm92aXNpb25pbmdfbGVhc2VfbG9zdCcpO1xuICAgIH1cbiAgICByZXR1cm4gdG9MZWFzZShyb3dzWzBdKTtcbiAgfSBjYXRjaChlcnJvcikge1xuICAgIGlmKGVycm9yIGluc3RhbmNlb2YgRXJyb3IgJiYgZXJyb3IubWVzc2FnZSA9PT0gJ2RhdGFiYXNlX3Byb3Zpc2lvbmluZ19sZWFzZV9sb3N0Jykge1xuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfVxuICAgIHRocm93IG5ldyBFcnJvcignZGF0YWJhc2VfcHJvdmlzaW9uaW5nX2Vycm9yJyk7XG4gIH1cbn07XG5cbmV4cG9ydCBjb25zdCByZWxlYXNlRGF0YWJhc2VQcm92aXNpb25pbmdMZWFzZSA9IGFzeW5jIChcbiAgY29udGV4dDogQXBpQ29udGV4dCxcbiAgbGVhc2U6IERhdGFiYXNlUHJvdmlzaW9uaW5nTGVhc2Vcbik6IFByb21pc2U8dm9pZD4gPT4ge1xuICB0cnkge1xuICAgIGNvbnN0IHJvd3MgPSBhd2FpdCBydW5RdWVyeShjb250ZXh0LCBgJHtmZW5jZWRRdWVyeX1cbiAgICAgIHtvd25lcjogbnVsbCwgZXhwaXJlc0F0OiAwfVxuICAgICAgSU4gQEBjb2xsZWN0aW9uIE9QVElPTlMge2lnbm9yZVJldnM6IGZhbHNlfSBSRVRVUk4gTkVXXG4gICAgYCwge2tleTogbGVhc2Uua2V5LCBvd25lcjogbGVhc2Uub3duZXJ9KTtcbiAgICBpZighcm93c1swXSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdkYXRhYmFzZV9wcm92aXNpb25pbmdfbGVhc2VfbG9zdCcpO1xuICAgIH1cbiAgfSBjYXRjaChlcnJvcikge1xuICAgIGlmKGVycm9yIGluc3RhbmNlb2YgRXJyb3IgJiYgZXJyb3IubWVzc2FnZSA9PT0gJ2RhdGFiYXNlX3Byb3Zpc2lvbmluZ19sZWFzZV9sb3N0Jykge1xuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfVxuICAgIHRocm93IG5ldyBFcnJvcignZGF0YWJhc2VfcHJvdmlzaW9uaW5nX2Vycm9yJyk7XG4gIH1cbn07XG5cbmV4cG9ydCBjb25zdCBzYXZlRGF0YWJhc2VQcm92aXNpb25pbmdTdGF0ZSA9IGFzeW5jIChcbiAgY29udGV4dDogQXBpQ29udGV4dCxcbiAgbGVhc2U6IERhdGFiYXNlUHJvdmlzaW9uaW5nTGVhc2UsXG4gIG1ldGFkYXRhOiBEYXRhYmFzZUNvbm5lY3Rpb25NZXRhZGF0YVxuKTogUHJvbWlzZTx2b2lkPiA9PiB7XG4gIGNvbnN0IHNhZmVNZXRhZGF0YSA9IHtcbiAgICBhcHBJZDogbWV0YWRhdGEuYXBwSWQsXG4gICAgZGF0YWJhc2VOYW1lOiBtZXRhZGF0YS5kYXRhYmFzZU5hbWUsXG4gICAgZW52aXJvbm1lbnQ6IG1ldGFkYXRhLmVudmlyb25tZW50LFxuICAgIGhvc3Q6IG1ldGFkYXRhLmhvc3QsXG4gICAgcG9ydDogbWV0YWRhdGEucG9ydCxcbiAgICBzZWNyZXRBcm46IG1ldGFkYXRhLnNlY3JldEFybixcbiAgICBzZWNyZXROYW1lOiBtZXRhZGF0YS5zZWNyZXROYW1lLFxuICAgIHN0YXR1czogbWV0YWRhdGEuc3RhdHVzLFxuICAgIHVzZXJuYW1lOiBtZXRhZGF0YS51c2VybmFtZVxuICB9O1xuICB0cnkge1xuICAgIGNvbnN0IHJvd3MgPSBhd2FpdCBydW5RdWVyeShjb250ZXh0LCBgJHtmZW5jZWRRdWVyeX1cbiAgICAgIEBtZXRhZGF0YSBJTiBAQGNvbGxlY3Rpb24gT1BUSU9OUyB7aWdub3JlUmV2czogZmFsc2V9IFJFVFVSTiBORVdcbiAgICBgLCB7a2V5OiBsZWFzZS5rZXksIG1ldGFkYXRhOiBzYWZlTWV0YWRhdGEsIG93bmVyOiBsZWFzZS5vd25lcn0pO1xuICAgIGlmKCFyb3dzWzBdKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2RhdGFiYXNlX3Byb3Zpc2lvbmluZ19sZWFzZV9sb3N0Jyk7XG4gICAgfVxuICB9IGNhdGNoKGVycm9yKSB7XG4gICAgaWYoZXJyb3IgaW5zdGFuY2VvZiBFcnJvciAmJiBlcnJvci5tZXNzYWdlID09PSAnZGF0YWJhc2VfcHJvdmlzaW9uaW5nX2xlYXNlX2xvc3QnKSB7XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG4gICAgdGhyb3cgbmV3IEVycm9yKCdkYXRhYmFzZV9wcm92aXNpb25pbmdfZXJyb3InKTtcbiAgfVxufTtcbiJdLCJuYW1lcyI6WyJyYW5kb21VVUlEIiwidXNlRGIiLCJjb2xsZWN0aW9uTmFtZSIsInR0bE1zIiwiY29sbGVjdGlvbkJpbmQiLCJnZXRDb250cm9sRGIiLCJjb250ZXh0IiwiZGF0YWJhc2VOYW1lIiwiRXJyb3IiLCJpc0Vycm9yTnVtYmVyIiwiZXJyb3IiLCJjb2RlcyIsImluY2x1ZGVzIiwiZXJyb3JOdW0iLCJ0b0xlYXNlIiwicm93IiwiZXhwaXJlc0F0Iiwia2V5IiwiX2tleSIsIm93bmVyIiwicnVuUXVlcnkiLCJxdWVyeSIsImJpbmRWYXJzIiwiY3Vyc29yIiwiYWxsIiwiZmVuY2VkUXVlcnkiLCJhY3F1aXJlRGF0YWJhc2VQcm92aXNpb25pbmdMZWFzZSIsImlkZW50aXR5IiwiYXBwSWQiLCJlbnZpcm9ubWVudCIsImNvbGxlY3Rpb24iLCJjcmVhdGUiLCJyb3dzIiwiYXR0ZW1wdCIsIm1lc3NhZ2UiLCJyZW5ld0RhdGFiYXNlUHJvdmlzaW9uaW5nTGVhc2UiLCJsZWFzZSIsInJlbGVhc2VEYXRhYmFzZVByb3Zpc2lvbmluZ0xlYXNlIiwic2F2ZURhdGFiYXNlUHJvdmlzaW9uaW5nU3RhdGUiLCJtZXRhZGF0YSIsInNhZmVNZXRhZGF0YSIsImhvc3QiLCJwb3J0Iiwic2VjcmV0QXJuIiwic2VjcmV0TmFtZSIsInN0YXR1cyIsInVzZXJuYW1lIl0sIm1hcHBpbmdzIjoiQUFBQSxTQUFRQSxVQUFVLFFBQU8sY0FBYztBQUV2QyxTQUFRQyxLQUFLLFFBQU8sNEJBQTRCO0FBS2hELE1BQU1DLGlCQUFpQjtBQUN2QixNQUFNQyxRQUFRO0FBQ2QsTUFBTUMsaUJBQWlCO0lBQUMsZUFBZUY7QUFBYztBQUtyRCxNQUFNRyxlQUFlLENBQUNDO0lBQ3BCLElBQUcsQ0FBQ0EsUUFBUUMsWUFBWSxFQUFFO1FBQ3hCLE1BQU0sSUFBSUMsTUFBTTtJQUNsQjtJQUNBLE9BQU9QLE1BQU1LLFFBQVFDLFlBQVk7QUFDbkM7QUFFQSxNQUFNRSxnQkFBZ0IsQ0FBQ0MsT0FBZ0IsR0FBR0MsUUFDeENBLE1BQU1DLFFBQVEsQ0FBQyxBQUFDRixPQUFnQ0csWUFBWSxDQUFDO0FBRS9ELE1BQU1DLFVBQVUsQ0FBQ0MsTUFBOEMsQ0FBQTtRQUM3REMsV0FBV0QsSUFBSUMsU0FBUztRQUN4QixnREFBZ0Q7UUFDaERDLEtBQUtGLElBQUlHLElBQUk7UUFDYkMsT0FBT0osSUFBSUksS0FBSztJQUNsQixDQUFBO0FBRUEsTUFBTUMsV0FBVyxPQUFPZCxTQUFxQmUsT0FBZUM7SUFDMUQsTUFBTUMsU0FBUyxNQUFNbEIsYUFBYUMsU0FBU2UsS0FBSyxDQUFXO1FBQUNDLFVBQVU7WUFBQyxHQUFHbEIsY0FBYztZQUFFLEdBQUdrQixRQUFRO1FBQUE7UUFBR0Q7SUFBSztJQUM3RyxPQUFPRSxP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
@@ -18,3 +18,5 @@ export declare const generateSeedanceReferenceVideo: (context: ApiContext, input
18
18
  export declare const generateMarketingStudioImage: (context: ApiContext, input: MarketingStudioImageInput, webhookUrl?: string) => Promise<HiggsfieldRequestResult>;
19
19
  export declare const getHiggsfieldRequestStatus: (context: ApiContext, requestId: string) => Promise<HiggsfieldStatusResult>;
20
20
  export declare const cancelHiggsfieldRequest: (context: ApiContext, requestId: string) => Promise<boolean>;
21
+ /** Submit one allowlisted catalog model; never retry a submission with an unknown outcome. */
22
+ export declare const generateHiggsfieldModel: (context: ApiContext, modelId: string, input: Record<string, unknown>, webhookUrl?: string) => Promise<HiggsfieldRequestResult>;
@@ -3,6 +3,8 @@
3
3
  * All rights reserved. Use is subject to the accompanying commercial LICENSE.
4
4
  */ import { get, post } from '@nlabs/rip-hunter';
5
5
  import { validateMarketingStudioImageInput, validateSeedanceReferenceVideoInput, validateSeedanceVideoInput, validateSoulImageInput } from '../adapters/higgsfieldAdapter.js';
6
+ import { getHiggsfieldModel } from '../adapters/higgsfieldModelCatalog.js';
7
+ import { validateHiggsfieldModelInput } from '../adapters/higgsfieldModels.js';
6
8
  import { Config } from '../config.js';
7
9
  import { ErrorTypes } from '../types/error.types.js';
8
10
  import { logError } from '../utils/analyticsUtils.js';
@@ -144,5 +146,9 @@ export const cancelHiggsfieldRequest = async (context, requestId)=>{
144
146
  }, error, context);
145
147
  }
146
148
  };
149
+ /** Submit one allowlisted catalog model; never retry a submission with an unknown outcome. */ export const generateHiggsfieldModel = (context, modelId, input, webhookUrl)=>{
150
+ const model = getHiggsfieldModel(modelId);
151
+ return submit(context, 'generateHiggsfieldModel', withWebhook(`${HIGGSFIELD_ORIGIN}/${model.id}`, webhookUrl), validateHiggsfieldModelInput(modelId, input));
152
+ };
147
153
 
148
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9Vc2Vycy9uaXRyb2c3L0RldmVsb3BtZW50L3JlYWt0b3IvcGFja2FnZXMvcmVha3Rvci9zcmMvYWN0aW9ucy9oaWdnc2ZpZWxkLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQ29weXJpZ2h0IChjKSAyMDI2LVByZXNlbnQsIE5pdHJvZ2VuIExhYnMsIEluYy5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuIFVzZSBpcyBzdWJqZWN0IHRvIHRoZSBhY2NvbXBhbnlpbmcgY29tbWVyY2lhbCBMSUNFTlNFLlxuICovXG5pbXBvcnQge2dldCwgcG9zdH0gZnJvbSAnQG5sYWJzL3JpcC1odW50ZXInO1xuXG5pbXBvcnQge1xuICB2YWxpZGF0ZU1hcmtldGluZ1N0dWRpb0ltYWdlSW5wdXQsXG4gIHZhbGlkYXRlU2VlZGFuY2VSZWZlcmVuY2VWaWRlb0lucHV0LFxuICB2YWxpZGF0ZVNlZWRhbmNlVmlkZW9JbnB1dCxcbiAgdmFsaWRhdGVTb3VsSW1hZ2VJbnB1dFxufSBmcm9tICcuLi9hZGFwdGVycy9oaWdnc2ZpZWxkQWRhcHRlci5qcyc7XG5pbXBvcnQge0NvbmZpZ30gZnJvbSAnLi4vY29uZmlnLmpzJztcbmltcG9ydCB7RXJyb3JUeXBlc30gZnJvbSAnLi4vdHlwZXMvZXJyb3IudHlwZXMuanMnO1xuaW1wb3J0IHtsb2dFcnJvcn0gZnJvbSAnLi4vdXRpbHMvYW5hbHl0aWNzVXRpbHMuanMnO1xuXG5pbXBvcnQgdHlwZSB7XG4gIE1hcmtldGluZ1N0dWRpb0ltYWdlSW5wdXQsXG4gIFNlZWRhbmNlUmVmZXJlbmNlVmlkZW9JbnB1dCxcbiAgU2VlZGFuY2VWaWRlb0lucHV0LFxuICBTb3VsSW1hZ2VJbnB1dFxufSBmcm9tICcuLi9hZGFwdGVycy9oaWdnc2ZpZWxkQWRhcHRlci5qcyc7XG5pbXBvcnQgdHlwZSB7QXBpQ29udGV4dH0gZnJvbSAnLi4vdHlwZXMvYXV0aC50eXBlcy5qcyc7XG5cbmNvbnN0IGV2ZW50Q2F0ZWdvcnkgPSAnaGlnZ3NmaWVsZCc7XG5jb25zdCBISUdHU0ZJRUxEX09SSUdJTiA9ICdodHRwczovL2FwaS5oaWdnc2ZpZWxkLmFpJztcbmNvbnN0IFNPVUxfSU1BR0VfRU5EUE9JTlQgPSBgJHtISUdHU0ZJRUxEX09SSUdJTn0vaGlnZ3NmaWVsZC1haS9zb3VsL3YyL3N0YW5kYXJkYDtcbmNvbnN0IFNFRURBTkNFX1ZJREVPX0VORFBPSU5UID0gYCR7SElHR1NGSUVMRF9PUklHSU59L2J5dGVkYW5jZS9zZWVkYW5jZS0yLjUvaW1hZ2UtdG8tdmlkZW9gO1xuY29uc3QgU0VFREFOQ0VfUkVGRVJFTkNFX1ZJREVPX0VORFBPSU5UID0gYCR7SElHR1NGSUVMRF9PUklHSU59L2J5dGVkYW5jZS9zZWVkYW5jZS0yLjUvcmVmZXJlbmNlLXRvLXZpZGVvYDtcbmNvbnN0IE1BUktFVElOR19TVFVESU9fSU1BR0VfRU5EUE9JTlQgPSBgJHtISUdHU0ZJRUxEX09SSUdJTn0vbWFya2V0aW5nLXN0dWRpby9pbWFnZWA7XG5cbmV4cG9ydCBpbnRlcmZhY2UgSGlnZ3NmaWVsZFJlcXVlc3RSZXN1bHQge1xuICBjYW5jZWxVcmw/OiBzdHJpbmc7XG4gIHJlcXVlc3RJZDogc3RyaW5nO1xuICBzdGF0dXNVcmw6IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBIaWdnc2ZpZWxkU3RhdHVzUmVzdWx0IHtcbiAgZXJyb3I/OiBzdHJpbmc7XG4gIG1lZGlhVXJsPzogc3RyaW5nO1xuICBtZWRpYVVybHM/OiBzdHJpbmdbXTtcbiAgcmVxdWVzdElkOiBzdHJpbmc7XG4gIHN0YXR1czogc3RyaW5nO1xufVxuXG5pbnRlcmZhY2UgSGlnZ3NmaWVsZFJlc3BvbnNlQm9keSB7XG4gIGNhbmNlbF91cmw/OiBzdHJpbmc7XG4gIGRldGFpbD86IHVua25vd247XG4gIGVycm9yPzogc3RyaW5nO1xuICBpbWFnZXM/OiB7dXJsPzogc3RyaW5nfVtdO1xuICByZXF1ZXN0X2lkPzogc3RyaW5nO1xuICBzdGF0dXM/OiBzdHJpbmc7XG4gIHN0YXR1c191cmw/OiBzdHJpbmc7XG4gIHZpZGVvPzoge3VybD86IHN0cmluZ307XG59XG5cbi8qKiBOZXZlciBzZW5kIEFQSSBjcmVkZW50aWFscyB0byBhIHByb3ZpZGVyLXN1cHBsaWVkIHRoaXJkLXBhcnR5IHBvbGxpbmcvY2FuY2VsIFVSTC4gKi9cbmNvbnN0IHZhbGlkYXRlSGlnZ3NmaWVsZFVybCA9ICh2YWx1ZTogc3RyaW5nLCByZXF1ZXN0SWQ6IHN0cmluZywgYWN0aW9uOiAnc3RhdHVzJyB8ICdjYW5jZWwnKTogc3RyaW5nID0+IHtcbiAgY29uc3QgdXJsID0gbmV3IFVSTCh2YWx1ZSk7XG5cbiAgaWYodXJsLm9yaWdpbiAhPT0gSElHR1NGSUVMRF9PUklHSU4gfHwgdXJsLnVzZXJuYW1lIHx8IHVybC5wYXNzd29yZCB8fFxuICAgIHVybC5wYXRobmFtZSAhPT0gYC9yZXF1ZXN0cy8ke3JlcXVlc3RJZH0vJHthY3Rpb259YCB8fCB1cmwuc2VhcmNoIHx8IHVybC5oYXNoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBIaWdnc2ZpZWxkIHJldHVybmVkIGFuIGludmFsaWQgJHthY3Rpb259IFVSTC4gUmVjb25jaWxlIHRoZSByZXF1ZXN0IG1hbnVhbGx5LmApO1xuICB9XG5cbiAgcmV0dXJuIHVybC5ocmVmO1xufTtcblxuY29uc3QgYXV0aEhlYWRlcnMgPSAoKTogSGVhZGVycyA9PiB7XG4gIGNvbnN0IGtleUlkID0gQ29uZmlnLmdldDxzdHJpbmc+KCdoaWdnc2ZpZWxkLmtleUlkJyk7XG4gIGNvbnN0IGtleVNlY3JldCA9IENvbmZpZy5nZXQ8c3RyaW5nPignaGlnZ3NmaWVsZC5rZXlTZWNyZXQnKTtcblxuICBpZigha2V5SWQgfHwgIWtleVNlY3JldCkge1xuICAgIHRocm93IG5ldyBFcnJvcignSGlnZ3NmaWVsZCBpcyBub3QgY29uZmlndXJlZC4gU2V0IEhJR0dTRklFTERfS0VZX0lEIGFuZCBISUdHU0ZJRUxEX0tFWV9TRUNSRVQuJyk7XG4gIH1cblxuICByZXR1cm4gbmV3IEhlYWRlcnMoe1xuICAgIEF1dGhvcml6YXRpb246IGBLZXkgJHtrZXlJZH06JHtrZXlTZWNyZXR9YCxcbiAgICAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nXG4gIH0pO1xufTtcblxuY29uc3Qgd2l0aFdlYmhvb2sgPSAoZW5kcG9pbnQ6IHN0cmluZywgd2ViaG9va1VybD86IHN0cmluZyk6IHN0cmluZyA9PlxuICAod2ViaG9va1VybCA/IGAke2VuZHBvaW50fT9oZl93ZWJob29rPSR7ZW5jb2RlVVJJQ29tcG9uZW50KHdlYmhvb2tVcmwpfWAgOiBlbmRwb2ludCk7XG5cbmNvbnN0IHN1Ym1pdCA9IGFzeW5jIChcbiAgY29udGV4dDogQXBpQ29udGV4dCwgYWN0aW9uOiBzdHJpbmcsIGVuZHBvaW50OiBzdHJpbmcsIGJvZHk6IFJlY29yZDxzdHJpbmcsIHVua25vd24+XG4pOiBQcm9taXNlPEhpZ2dzZmllbGRSZXF1ZXN0UmVzdWx0PiA9PiB7XG4gIHRyeSB7XG4gICAgY29uc3QgZGF0YSA9IGF3YWl0IHBvc3QoZW5kcG9pbnQsIGJvZHksIHtjYWNoZTogZmFsc2UsIGhlYWRlcnM6IGF1dGhIZWFkZXJzKCl9KSBhcyBIaWdnc2ZpZWxkUmVzcG9uc2VCb2R5O1xuXG4gICAgaWYoIWRhdGEucmVxdWVzdF9pZCB8fCAhZGF0YS5zdGF0dXNfdXJsKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0hpZ2dzZmllbGQgc3VibWlzc2lvbiBvdXRjb21lIGlzIHVua25vd246IG1pc3NpbmcgcmVxdWVzdF9pZCBvciBzdGF0dXNfdXJsLicpO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICBjYW5jZWxVcmw6IGRhdGEuY2FuY2VsX3VybCA/IHZhbGlkYXRlSGlnZ3NmaWVsZFVybChkYXRhLmNhbmNlbF91cmwsIGRhdGEucmVxdWVzdF9pZCwgJ2NhbmNlbCcpIDogdW5kZWZpbmVkLFxuICAgICAgcmVxdWVzdElkOiBkYXRhLnJlcXVlc3RfaWQsXG4gICAgICBzdGF0dXNVcmw6IHZhbGlkYXRlSGlnZ3NmaWVsZFVybChkYXRhLnN0YXR1c191cmwsIGRhdGEucmVxdWVzdF9pZCwgJ3N0YXR1cycpXG4gICAgfTtcbiAgfSBjYXRjaChlcnJvcikge1xuICAgIHJldHVybiBsb2dFcnJvcihcbiAgICAgIHthY3Rpb24sIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LCB2YWx1ZTogRXJyb3JUeXBlcy5FWFRFUk5BTF9BUElfRVJST1J9LCBlcnJvciBhcyBFcnJvciwgY29udGV4dFxuICAgICkgYXMgUHJvbWlzZTxuZXZlcj47XG4gIH1cbn07XG5cbmV4cG9ydCBjb25zdCBnZW5lcmF0ZVNvdWxJbWFnZSA9IChcbiAgY29udGV4dDogQXBpQ29udGV4dCwgaW5wdXQ6IFNvdWxJbWFnZUlucHV0LCB3ZWJob29rVXJsPzogc3RyaW5nXG4pOiBQcm9taXNlPEhpZ2dzZmllbGRSZXF1ZXN0UmVzdWx0PiA9PiB7XG4gIGNvbnN0IHZhbGlkYXRlZCA9IHZhbGlkYXRlU291bEltYWdlSW5wdXQoaW5wdXQpO1xuXG4gIHJldHVybiBzdWJtaXQoY29udGV4dCwgJ2dlbmVyYXRlU291bEltYWdlJywgd2l0aFdlYmhvb2soU09VTF9JTUFHRV9FTkRQT0lOVCwgd2ViaG9va1VybCksIHtcbiAgICBhc3BlY3RfcmF0aW86IHZhbGlkYXRlZC5hc3BlY3RSYXRpbyxcbiAgICBiYXRjaF9zaXplOiB2YWxpZGF0ZWQuYmF0Y2hTaXplLFxuICAgIGVuaGFuY2VfcHJvbXB0OiB2YWxpZGF0ZWQuZW5oYW5jZVByb21wdCxcbiAgICBwcm9tcHQ6IHZhbGlkYXRlZC5wcm9tcHQsXG4gICAgcmVzb2x1dGlvbjogdmFsaWRhdGVkLnJlc29sdXRpb24sXG4gICAgc2VlZDogdmFsaWRhdGVkLnNlZWQsXG4gICAgc3R5bGVfaWQ6IHZhbGlkYXRlZC5zdHlsZUlkXG4gIH0pO1xufTtcblxuZXhwb3J0IGNvbnN0IGdlbmVyYXRlU2VlZGFuY2VWaWRlbyA9IChcbiAgY29udGV4dDogQXBpQ29udGV4dCwgaW5wdXQ6IFNlZWRhbmNlVmlkZW9JbnB1dCwgd2ViaG9va1VybD86IHN0cmluZ1xuKTogUHJvbWlzZTxIaWdnc2ZpZWxkUmVxdWVzdFJlc3VsdD4gPT4ge1xuICBjb25zdCB2YWxpZGF0ZWQgPSB2YWxpZGF0ZVNlZWRhbmNlVmlkZW9JbnB1dChpbnB1dCk7XG5cbiAgcmV0dXJuIHN1Ym1pdChjb250ZXh0LCAnZ2VuZXJhdGVTZWVkYW5jZVZpZGVvJywgd2l0aFdlYmhvb2soU0VFREFOQ0VfVklERU9fRU5EUE9JTlQsIHdlYmhvb2tVcmwpLCB7XG4gICAgZHVyYXRpb246IHZhbGlkYXRlZC5kdXJhdGlvbixcbiAgICBlbmRfaW1hZ2VfdXJsOiB2YWxpZGF0ZWQuZW5kSW1hZ2VVcmwsXG4gICAgZ2VuZXJhdGVfYXVkaW86IHZhbGlkYXRlZC5nZW5lcmF0ZUF1ZGlvLFxuICAgIGltYWdlX3VybDogdmFsaWRhdGVkLmltYWdlVXJsLFxuICAgIG91dHB1dF9mb3JtYXQ6IHZhbGlkYXRlZC5vdXRwdXRGb3JtYXQsXG4gICAgcHJvbXB0OiB2YWxpZGF0ZWQucHJvbXB0LFxuICAgIHJlc29sdXRpb246IHZhbGlkYXRlZC5yZXNvbHV0aW9uXG4gIH0pO1xufTtcblxuZXhwb3J0IGNvbnN0IGdlbmVyYXRlU2VlZGFuY2VSZWZlcmVuY2VWaWRlbyA9IChcbiAgY29udGV4dDogQXBpQ29udGV4dCwgaW5wdXQ6IFNlZWRhbmNlUmVmZXJlbmNlVmlkZW9JbnB1dCwgd2ViaG9va1VybD86IHN0cmluZ1xuKTogUHJvbWlzZTxIaWdnc2ZpZWxkUmVxdWVzdFJlc3VsdD4gPT4ge1xuICBjb25zdCB2YWxpZGF0ZWQgPSB2YWxpZGF0ZVNlZWRhbmNlUmVmZXJlbmNlVmlkZW9JbnB1dChpbnB1dCk7XG5cbiAgcmV0dXJuIHN1Ym1pdChjb250ZXh0LCAnZ2VuZXJhdGVTZWVkYW5jZVJlZmVyZW5jZVZpZGVvJywgd2l0aFdlYmhvb2soU0VFREFOQ0VfUkVGRVJFTkNFX1ZJREVPX0VORFBPSU5ULCB3ZWJob29rVXJsKSwge1xuICAgIGFzcGVjdF9yYXRpbzogdmFsaWRhdGVkLmFzcGVjdFJhdGlvLFxuICAgIGF1ZGlvX3VybHM6IHZhbGlkYXRlZC5hdWRpb1VybHMsXG4gICAgZHVyYXRpb246IHZhbGlkYXRlZC5kdXJhdGlvbixcbiAgICBnZW5lcmF0ZV9hdWRpbzogdmFsaWRhdGVkLmdlbmVyYXRlQXVkaW8sXG4gICAgaW1hZ2VfdXJsczogdmFsaWRhdGVkLmltYWdlVXJscyxcbiAgICBvdXRwdXRfZm9ybWF0OiB2YWxpZGF0ZWQub3V0cHV0Rm9ybWF0LFxuICAgIHByb21wdDogdmFsaWRhdGVkLnByb21wdCxcbiAgICByZXNvbHV0aW9uOiB2YWxpZGF0ZWQucmVzb2x1dGlvbixcbiAgICB2aWRlb191cmxzOiB2YWxpZGF0ZWQudmlkZW9VcmxzXG4gIH0pO1xufTtcblxuZXhwb3J0IGNvbnN0IGdlbmVyYXRlTWFya2V0aW5nU3R1ZGlvSW1hZ2UgPSAoXG4gIGNvbnRleHQ6IEFwaUNvbnRleHQsIGlucHV0OiBNYXJrZXRpbmdTdHVkaW9JbWFnZUlucHV0LCB3ZWJob29rVXJsPzogc3RyaW5nXG4pOiBQcm9taXNlPEhpZ2dzZmllbGRSZXF1ZXN0UmVzdWx0PiA9PiB7XG4gIGNvbnN0IHZhbGlkYXRlZCA9IHZhbGlkYXRlTWFya2V0aW5nU3R1ZGlvSW1hZ2VJbnB1dChpbnB1dCk7XG5cbiAgcmV0dXJuIHN1Ym1pdChjb250ZXh0LCAnZ2VuZXJhdGVNYXJrZXRpbmdTdHVkaW9JbWFnZScsIHdpdGhXZWJob29rKE1BUktFVElOR19TVFVESU9fSU1BR0VfRU5EUE9JTlQsIHdlYmhvb2tVcmwpLCB7XG4gICAgYXNwZWN0X3JhdGlvOiB2YWxpZGF0ZWQuYXNwZWN0UmF0aW8sXG4gICAgZW5oYW5jZV9wcm9tcHQ6IHZhbGlkYXRlZC5lbmhhbmNlUHJvbXB0LFxuICAgIGltYWdlX3VybHM6IHZhbGlkYXRlZC5pbWFnZVVybHMsXG4gICAgcHJlc2V0X2lkOiB2YWxpZGF0ZWQucHJlc2V0SWQsXG4gICAgcHJvbXB0OiB2YWxpZGF0ZWQucHJvbXB0LFxuICAgIHF1YWxpdHk6IHZhbGlkYXRlZC5xdWFsaXR5LFxuICAgIHJlc29sdXRpb246IHZhbGlkYXRlZC5yZXNvbHV0aW9uXG4gIH0pO1xufTtcblxuZXhwb3J0IGNvbnN0IGdldEhpZ2dzZmllbGRSZXF1ZXN0U3RhdHVzID0gYXN5bmMgKFxuICBjb250ZXh0OiBBcGlDb250ZXh0LCByZXF1ZXN0SWQ6IHN0cmluZ1xuKTogUHJvbWlzZTxIaWdnc2ZpZWxkU3RhdHVzUmVzdWx0PiA9PiB7XG4gIHRyeSB7XG4gICAgY29uc3Qgc3RhdHVzVXJsID0gdmFsaWRhdGVIaWdnc2ZpZWxkVXJsKGAke0hJR0dTRklFTERfT1JJR0lOfS9yZXF1ZXN0cy8ke3JlcXVlc3RJZH0vc3RhdHVzYCwgcmVxdWVzdElkLCAnc3RhdHVzJyk7XG4gICAgY29uc3QgZGF0YSA9IGF3YWl0IGdldChzdGF0dXNVcmwsIHt9LCB7Y2FjaGU6IGZhbHNlLCBoZWFkZXJzOiBhdXRoSGVhZGVycygpfSkgYXMgSGlnZ3NmaWVsZFJlc3BvbnNlQm9keTtcblxuICAgIGlmKGRhdGEucmVxdWVzdF9pZCAhPT0gcmVxdWVzdElkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0hpZ2dzZmllbGQgc3RhdHVzIHJlc3BvbnNlIHJldHVybmVkIGFuIHVuZXhwZWN0ZWQgcmVxdWVzdCBpZGVudGlmaWVyLicpO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICBlcnJvcjogZGF0YS5lcnJvcixcbiAgICAgIG1lZGlhVXJsOiBkYXRhLnZpZGVvPy51cmwgfHwgZGF0YS5pbWFnZXM/LlswXT8udXJsLFxuICAgICAgbWVkaWFVcmxzOiBkYXRhLmltYWdlcz8ubWFwKChpbWFnZSkgPT4gaW1hZ2UudXJsKS5maWx0ZXIoKHVybCk6IHVybCBpcyBzdHJpbmcgPT4gQm9vbGVhbih1cmwpKSxcbiAgICAgIHJlcXVlc3RJZCxcbiAgICAgIHN0YXR1czogZGF0YS5zdGF0dXMgfHwgJ3Vua25vd24nXG4gICAgfTtcbiAgfSBjYXRjaChlcnJvcikge1xuICAgIHJldHVybiBsb2dFcnJvcihcbiAgICAgIHthY3Rpb246ICdnZXRIaWdnc2ZpZWxkUmVxdWVzdFN0YXR1cycsIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LCB2YWx1ZTogRXJyb3JUeXBlcy5FWFRFUk5BTF9BUElfRVJST1J9LCBlcnJvciBhcyBFcnJvciwgY29udGV4dFxuICAgICkgYXMgUHJvbWlzZTxuZXZlcj47XG4gIH1cbn07XG5cbmV4cG9ydCBjb25zdCBjYW5jZWxIaWdnc2ZpZWxkUmVxdWVzdCA9IGFzeW5jIChjb250ZXh0OiBBcGlDb250ZXh0LCByZXF1ZXN0SWQ6IHN0cmluZyk6IFByb21pc2U8Ym9vbGVhbj4gPT4ge1xuICB0cnkge1xuICAgIGNvbnN0IGNhbmNlbFVybCA9IHZhbGlkYXRlSGlnZ3NmaWVsZFVybChgJHtISUdHU0ZJRUxEX09SSUdJTn0vcmVxdWVzdHMvJHtyZXF1ZXN0SWR9L2NhbmNlbGAsIHJlcXVlc3RJZCwgJ2NhbmNlbCcpO1xuICAgIGF3YWl0IHBvc3QoY2FuY2VsVXJsLCB7fSwge2NhY2hlOiBmYWxzZSwgaGVhZGVyczogYXV0aEhlYWRlcnMoKX0pO1xuXG4gICAgcmV0dXJuIChhd2FpdCBnZXRIaWdnc2ZpZWxkUmVxdWVzdFN0YXR1cyhjb250ZXh0LCByZXF1ZXN0SWQpKS5zdGF0dXMgPT09ICdjYW5jZWxlZCc7XG4gIH0gY2F0Y2goZXJyb3IpIHtcbiAgICByZXR1cm4gbG9nRXJyb3IoXG4gICAgICB7YWN0aW9uOiAnY2FuY2VsSGlnZ3NmaWVsZFJlcXVlc3QnLCBjYXRlZ29yeTogZXZlbnRDYXRlZ29yeSwgdmFsdWU6IEVycm9yVHlwZXMuRVhURVJOQUxfQVBJX0VSUk9SfSwgZXJyb3IgYXMgRXJyb3IsIGNvbnRleHRcbiAgICApIGFzIFByb21pc2U8bmV2ZXI+O1xuICB9XG59O1xuIl0sIm5hbWVzIjpbImdldCIsInBvc3QiLCJ2YWxpZGF0ZU1hcmtldGluZ1N0dWRpb0ltYWdlSW5wdXQiLCJ2YWxpZGF0ZVNlZWRhbmNlUmVmZXJlbmNlVmlkZW9JbnB1dCIsInZhbGlkYXRlU2VlZGFuY2VWaWRlb0lucHV0IiwidmFsaWRhdGVTb3VsSW1hZ2VJbnB1dCIsIkNvbmZpZyIsIkVycm9yVHlwZXMiLCJsb2dFcnJvciIsImV2ZW50Q2F0ZWdvcnkiLCJISUdHU0ZJRUxEX09SSUdJTiIsIlNPVUxfSU1BR0VfRU5EUE9JTlQiLCJTRUVEQU5DRV9WSURFT19FTkRQT0lOVCIsIlNFRURBTkNFX1JFRkVSRU5DRV9WSURFT19FTkRQT0lOVCIsIk1BUktFVElOR19TVFVESU9fSU1BR0VfRU5EUE9JTlQiLCJ2YWxpZGF0ZUhpZ2dzZmllbGRVcmwiLCJ2YWx1ZSIsInJlcXVlc3RJZCIsImFjdGlvbiIsInVybCIsIlVSTCIsIm9yaWdpbiIsInVzZXJuYW1lIiwicGFzc3dvcmQiLCJwYXRobmFtZSIsInNlYXJjaCIsImhhc2giLCJFcnJvciIsImhyZWYiLCJhdXRoSGVhZGVycyIsImtleUlkIiwia2V5U2VjcmV0IiwiSGVhZGVycyIsIkF1dGhvcml6YXRpb24iLCJ3aXRoV2ViaG9vayIsImVuZHBvaW50Iiwid2ViaG9va1VybCIsImVuY29kZVVSSUNvbXBvbmVudCIsInN1Ym1pdCIsImNvbnRleHQiLCJib2R5IiwiZGF0YSIsImNhY2hlIiwiaGVhZGVycyIsInJlcXVlc3RfaWQiLCJzdGF0dXNfdXJsIiwiY2FuY2VsVXJsIiwiY2FuY2VsX3VybCIsInVuZGVmaW5lZCIsInN0YXR1c1VybCIsImVycm9yIiwiY2F0ZWdvcnkiLCJFWFRFUk5BTF9BUElfRVJST1IiLCJnZW5lcmF0ZVNvdWxJbWFnZSIsImlucHV0IiwidmFsaWRhdGVkIiwiYXNwZWN0X3JhdGlvIiwiYXNwZWN0UmF0aW8iLCJiYXRjaF9zaXplIiwiYmF0Y2hTaXplIiwiZW5oYW5jZV9wcm9tcHQiLCJlbmhhbmNlUHJvbXB0IiwicHJvbXB0IiwicmVzb2x1dGlvbiIsInNlZWQiLCJzdHlsZV9pZCIsInN0eWxlSWQiLCJnZW5lcmF0ZVNlZWRhbmNlVmlkZW8iLCJkdXJhdGlvbiIsImVuZF9pbWFnZV91cmwiLCJlbmRJbWFnZVVybCIsImdlbmVyYXRlX2F1ZGlvIiwiZ2VuZXJhdGVBdWRpbyIsImltYWdlX3VybCIsImltYWdlVXJsIiwib3V0cHV0X2Zvcm1hdCIsIm91dHB1dEZvcm1hdCIsImdlbmVyYXRlU2VlZGFuY2VSZWZlcmVuY2VWaWRlbyIsImF1ZGlvX3VybHMiLCJhdWRpb1VybHMiLCJpbWFnZV91cmxzIiwiaW1hZ2VVcmxzIiwidmlkZW9fdXJscyIsInZpZGVvVXJscyIsImdlbmVyYXRlTWFya2V0aW5nU3R1ZGlvSW1hZ2UiLCJwcmVzZXRfaWQiLCJwcmVzZXRJZCIsInF1YWxpdHkiLCJnZXRIaWdnc2ZpZWxkUmVxdWVzdFN0YXR1cyIsIm1lZGlhVXJsIiwidmlkZW8iLCJpbWFnZXMiLCJtZWRpYVVybHMiLCJtYXAiLCJpbWFnZSIsImZpbHRlciIsIkJvb2xlYW4iLCJzdGF0dXMiLCJjYW5jZWxIaWdnc2ZpZWxkUmVxdWVzdCJdLCJtYXBwaW5ncyI6IkFBQUE7OztDQUdDLEdBQ0QsU0FBUUEsR0FBRyxFQUFFQyxJQUFJLFFBQU8sb0JBQW9CO0FBRTVDLFNBQ0VDLGlDQUFpQyxFQUNqQ0MsbUNBQW1DLEVBQ25DQywwQkFBMEIsRUFDMUJDLHNCQUFzQixRQUNqQixtQ0FBbUM7QUFDMUMsU0FBUUMsTUFBTSxRQUFPLGVBQWU7QUFDcEMsU0FBUUMsVUFBVSxRQUFPLDBCQUEwQjtBQUNuRCxTQUFRQyxRQUFRLFFBQU8sNkJBQTZCO0FBVXBELE1BQU1DLGdCQUFnQjtBQUN0QixNQUFNQyxvQkFBb0I7QUFDMUIsTUFBTUMsc0JBQXNCLEdBQUdELGtCQUFrQiwrQkFBK0IsQ0FBQztBQUNqRixNQUFNRSwwQkFBMEIsR0FBR0Ysa0JBQWtCLHNDQUFzQyxDQUFDO0FBQzVGLE1BQU1HLG9DQUFvQyxHQUFHSCxrQkFBa0IsMENBQTBDLENBQUM7QUFDMUcsTUFBTUksa0NBQWtDLEdBQUdKLGtCQUFrQix1QkFBdUIsQ0FBQztBQTJCckYsc0ZBQXNGLEdBQ3RGLE1BQU1LLHdCQUF3QixDQUFDQyxPQUFlQyxXQUFtQkM7SUFDL0QsTUFBTUMsTUFBTSxJQUFJQyxJQUFJSjtJQUVwQixJQUFHRyxJQUFJ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
154
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9Vc2Vycy9uaXRyb2c3L0RldmVsb3BtZW50L3JlYWt0b3IvcGFja2FnZXMvcmVha3Rvci9zcmMvYWN0aW9ucy9oaWdnc2ZpZWxkLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQ29weXJpZ2h0IChjKSAyMDI2LVByZXNlbnQsIE5pdHJvZ2VuIExhYnMsIEluYy5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuIFVzZSBpcyBzdWJqZWN0IHRvIHRoZSBhY2NvbXBhbnlpbmcgY29tbWVyY2lhbCBMSUNFTlNFLlxuICovXG5pbXBvcnQge2dldCwgcG9zdH0gZnJvbSAnQG5sYWJzL3JpcC1odW50ZXInO1xuXG5pbXBvcnQge1xuICB2YWxpZGF0ZU1hcmtldGluZ1N0dWRpb0ltYWdlSW5wdXQsXG4gIHZhbGlkYXRlU2VlZGFuY2VSZWZlcmVuY2VWaWRlb0lucHV0LFxuICB2YWxpZGF0ZVNlZWRhbmNlVmlkZW9JbnB1dCxcbiAgdmFsaWRhdGVTb3VsSW1hZ2VJbnB1dFxufSBmcm9tICcuLi9hZGFwdGVycy9oaWdnc2ZpZWxkQWRhcHRlci5qcyc7XG5pbXBvcnQge2dldEhpZ2dzZmllbGRNb2RlbH0gZnJvbSAnLi4vYWRhcHRlcnMvaGlnZ3NmaWVsZE1vZGVsQ2F0YWxvZy5qcyc7XG5pbXBvcnQge3ZhbGlkYXRlSGlnZ3NmaWVsZE1vZGVsSW5wdXR9IGZyb20gJy4uL2FkYXB0ZXJzL2hpZ2dzZmllbGRNb2RlbHMuanMnO1xuaW1wb3J0IHtDb25maWd9IGZyb20gJy4uL2NvbmZpZy5qcyc7XG5pbXBvcnQge0Vycm9yVHlwZXN9IGZyb20gJy4uL3R5cGVzL2Vycm9yLnR5cGVzLmpzJztcbmltcG9ydCB7bG9nRXJyb3J9IGZyb20gJy4uL3V0aWxzL2FuYWx5dGljc1V0aWxzLmpzJztcblxuaW1wb3J0IHR5cGUge1xuICBNYXJrZXRpbmdTdHVkaW9JbWFnZUlucHV0LFxuICBTZWVkYW5jZVJlZmVyZW5jZVZpZGVvSW5wdXQsXG4gIFNlZWRhbmNlVmlkZW9JbnB1dCxcbiAgU291bEltYWdlSW5wdXRcbn0gZnJvbSAnLi4vYWRhcHRlcnMvaGlnZ3NmaWVsZEFkYXB0ZXIuanMnO1xuaW1wb3J0IHR5cGUge0FwaUNvbnRleHR9IGZyb20gJy4uL3R5cGVzL2F1dGgudHlwZXMuanMnO1xuXG5jb25zdCBldmVudENhdGVnb3J5ID0gJ2hpZ2dzZmllbGQnO1xuY29uc3QgSElHR1NGSUVMRF9PUklHSU4gPSAnaHR0cHM6Ly9hcGkuaGlnZ3NmaWVsZC5haSc7XG5jb25zdCBTT1VMX0lNQUdFX0VORFBPSU5UID0gYCR7SElHR1NGSUVMRF9PUklHSU59L2hpZ2dzZmllbGQtYWkvc291bC92Mi9zdGFuZGFyZGA7XG5jb25zdCBTRUVEQU5DRV9WSURFT19FTkRQT0lOVCA9IGAke0hJR0dTRklFTERfT1JJR0lOfS9ieXRlZGFuY2Uvc2VlZGFuY2UtMi41L2ltYWdlLXRvLXZpZGVvYDtcbmNvbnN0IFNFRURBTkNFX1JFRkVSRU5DRV9WSURFT19FTkRQT0lOVCA9IGAke0hJR0dTRklFTERfT1JJR0lOfS9ieXRlZGFuY2Uvc2VlZGFuY2UtMi41L3JlZmVyZW5jZS10by12aWRlb2A7XG5jb25zdCBNQVJLRVRJTkdfU1RVRElPX0lNQUdFX0VORFBPSU5UID0gYCR7SElHR1NGSUVMRF9PUklHSU59L21hcmtldGluZy1zdHVkaW8vaW1hZ2VgO1xuXG5leHBvcnQgaW50ZXJmYWNlIEhpZ2dzZmllbGRSZXF1ZXN0UmVzdWx0IHtcbiAgY2FuY2VsVXJsPzogc3RyaW5nO1xuICByZXF1ZXN0SWQ6IHN0cmluZztcbiAgc3RhdHVzVXJsOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSGlnZ3NmaWVsZFN0YXR1c1Jlc3VsdCB7XG4gIGVycm9yPzogc3RyaW5nO1xuICBtZWRpYVVybD86IHN0cmluZztcbiAgbWVkaWFVcmxzPzogc3RyaW5nW107XG4gIHJlcXVlc3RJZDogc3RyaW5nO1xuICBzdGF0dXM6IHN0cmluZztcbn1cblxuaW50ZXJmYWNlIEhpZ2dzZmllbGRSZXNwb25zZUJvZHkge1xuICBjYW5jZWxfdXJsPzogc3RyaW5nO1xuICBkZXRhaWw/OiB1bmtub3duO1xuICBlcnJvcj86IHN0cmluZztcbiAgaW1hZ2VzPzoge3VybD86IHN0cmluZ31bXTtcbiAgcmVxdWVzdF9pZD86IHN0cmluZztcbiAgc3RhdHVzPzogc3RyaW5nO1xuICBzdGF0dXNfdXJsPzogc3RyaW5nO1xuICB2aWRlbz86IHt1cmw/OiBzdHJpbmd9O1xufVxuXG4vKiogTmV2ZXIgc2VuZCBBUEkgY3JlZGVudGlhbHMgdG8gYSBwcm92aWRlci1zdXBwbGllZCB0aGlyZC1wYXJ0eSBwb2xsaW5nL2NhbmNlbCBVUkwuICovXG5jb25zdCB2YWxpZGF0ZUhpZ2dzZmllbGRVcmwgPSAodmFsdWU6IHN0cmluZywgcmVxdWVzdElkOiBzdHJpbmcsIGFjdGlvbjogJ3N0YXR1cycgfCAnY2FuY2VsJyk6IHN0cmluZyA9PiB7XG4gIGNvbnN0IHVybCA9IG5ldyBVUkwodmFsdWUpO1xuXG4gIGlmKHVybC5vcmlnaW4gIT09IEhJR0dTRklFTERfT1JJR0lOIHx8IHVybC51c2VybmFtZSB8fCB1cmwucGFzc3dvcmQgfHxcbiAgICB1cmwucGF0aG5hbWUgIT09IGAvcmVxdWVzdHMvJHtyZXF1ZXN0SWR9LyR7YWN0aW9ufWAgfHwgdXJsLnNlYXJjaCB8fCB1cmwuaGFzaCkge1xuICAgIHRocm93IG5ldyBFcnJvcihgSGlnZ3NmaWVsZCByZXR1cm5lZCBhbiBpbnZhbGlkICR7YWN0aW9ufSBVUkwuIFJlY29uY2lsZSB0aGUgcmVxdWVzdCBtYW51YWxseS5gKTtcbiAgfVxuXG4gIHJldHVybiB1cmwuaHJlZjtcbn07XG5cbmNvbnN0IGF1dGhIZWFkZXJzID0gKCk6IEhlYWRlcnMgPT4ge1xuICBjb25zdCBrZXlJZCA9IENvbmZpZy5nZXQ8c3RyaW5nPignaGlnZ3NmaWVsZC5rZXlJZCcpO1xuICBjb25zdCBrZXlTZWNyZXQgPSBDb25maWcuZ2V0PHN0cmluZz4oJ2hpZ2dzZmllbGQua2V5U2VjcmV0Jyk7XG5cbiAgaWYoIWtleUlkIHx8ICFrZXlTZWNyZXQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0hpZ2dzZmllbGQgaXMgbm90IGNvbmZpZ3VyZWQuIFNldCBISUdHU0ZJRUxEX0tFWV9JRCBhbmQgSElHR1NGSUVMRF9LRVlfU0VDUkVULicpO1xuICB9XG5cbiAgcmV0dXJuIG5ldyBIZWFkZXJzKHtcbiAgICBBdXRob3JpemF0aW9uOiBgS2V5ICR7a2V5SWR9OiR7a2V5U2VjcmV0fWAsXG4gICAgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJ1xuICB9KTtcbn07XG5cbmNvbnN0IHdpdGhXZWJob29rID0gKGVuZHBvaW50OiBzdHJpbmcsIHdlYmhvb2tVcmw/OiBzdHJpbmcpOiBzdHJpbmcgPT5cbiAgKHdlYmhvb2tVcmwgPyBgJHtlbmRwb2ludH0/aGZfd2ViaG9vaz0ke2VuY29kZVVSSUNvbXBvbmVudCh3ZWJob29rVXJsKX1gIDogZW5kcG9pbnQpO1xuXG5jb25zdCBzdWJtaXQgPSBhc3luYyAoXG4gIGNvbnRleHQ6IEFwaUNvbnRleHQsIGFjdGlvbjogc3RyaW5nLCBlbmRwb2ludDogc3RyaW5nLCBib2R5OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPlxuKTogUHJvbWlzZTxIaWdnc2ZpZWxkUmVxdWVzdFJlc3VsdD4gPT4ge1xuICB0cnkge1xuICAgIGNvbnN0IGRhdGEgPSBhd2FpdCBwb3N0KGVuZHBvaW50LCBib2R5LCB7Y2FjaGU6IGZhbHNlLCBoZWFkZXJzOiBhdXRoSGVhZGVycygpfSkgYXMgSGlnZ3NmaWVsZFJlc3BvbnNlQm9keTtcblxuICAgIGlmKCFkYXRhLnJlcXVlc3RfaWQgfHwgIWRhdGEuc3RhdHVzX3VybCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdIaWdnc2ZpZWxkIHN1Ym1pc3Npb24gb3V0Y29tZSBpcyB1bmtub3duOiBtaXNzaW5nIHJlcXVlc3RfaWQgb3Igc3RhdHVzX3VybC4nKTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgY2FuY2VsVXJsOiBkYXRhLmNhbmNlbF91cmwgPyB2YWxpZGF0ZUhpZ2dzZmllbGRVcmwoZGF0YS5jYW5jZWxfdXJsLCBkYXRhLnJlcXVlc3RfaWQsICdjYW5jZWwnKSA6IHVuZGVmaW5lZCxcbiAgICAgIHJlcXVlc3RJZDogZGF0YS5yZXF1ZXN0X2lkLFxuICAgICAgc3RhdHVzVXJsOiB2YWxpZGF0ZUhpZ2dzZmllbGRVcmwoZGF0YS5zdGF0dXNfdXJsLCBkYXRhLnJlcXVlc3RfaWQsICdzdGF0dXMnKVxuICAgIH07XG4gIH0gY2F0Y2goZXJyb3IpIHtcbiAgICByZXR1cm4gbG9nRXJyb3IoXG4gICAgICB7YWN0aW9uLCBjYXRlZ29yeTogZXZlbnRDYXRlZ29yeSwgdmFsdWU6IEVycm9yVHlwZXMuRVhURVJOQUxfQVBJX0VSUk9SfSwgZXJyb3IgYXMgRXJyb3IsIGNvbnRleHRcbiAgICApIGFzIFByb21pc2U8bmV2ZXI+O1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgZ2VuZXJhdGVTb3VsSW1hZ2UgPSAoXG4gIGNvbnRleHQ6IEFwaUNvbnRleHQsIGlucHV0OiBTb3VsSW1hZ2VJbnB1dCwgd2ViaG9va1VybD86IHN0cmluZ1xuKTogUHJvbWlzZTxIaWdnc2ZpZWxkUmVxdWVzdFJlc3VsdD4gPT4ge1xuICBjb25zdCB2YWxpZGF0ZWQgPSB2YWxpZGF0ZVNvdWxJbWFnZUlucHV0KGlucHV0KTtcblxuICByZXR1cm4gc3VibWl0KGNvbnRleHQsICdnZW5lcmF0ZVNvdWxJbWFnZScsIHdpdGhXZWJob29rKFNPVUxfSU1BR0VfRU5EUE9JTlQsIHdlYmhvb2tVcmwpLCB7XG4gICAgYXNwZWN0X3JhdGlvOiB2YWxpZGF0ZWQuYXNwZWN0UmF0aW8sXG4gICAgYmF0Y2hfc2l6ZTogdmFsaWRhdGVkLmJhdGNoU2l6ZSxcbiAgICBlbmhhbmNlX3Byb21wdDogdmFsaWRhdGVkLmVuaGFuY2VQcm9tcHQsXG4gICAgcHJvbXB0OiB2YWxpZGF0ZWQucHJvbXB0LFxuICAgIHJlc29sdXRpb246IHZhbGlkYXRlZC5yZXNvbHV0aW9uLFxuICAgIHNlZWQ6IHZhbGlkYXRlZC5zZWVkLFxuICAgIHN0eWxlX2lkOiB2YWxpZGF0ZWQuc3R5bGVJZFxuICB9KTtcbn07XG5cbmV4cG9ydCBjb25zdCBnZW5lcmF0ZVNlZWRhbmNlVmlkZW8gPSAoXG4gIGNvbnRleHQ6IEFwaUNvbnRleHQsIGlucHV0OiBTZWVkYW5jZVZpZGVvSW5wdXQsIHdlYmhvb2tVcmw/OiBzdHJpbmdcbik6IFByb21pc2U8SGlnZ3NmaWVsZFJlcXVlc3RSZXN1bHQ+ID0+IHtcbiAgY29uc3QgdmFsaWRhdGVkID0gdmFsaWRhdGVTZWVkYW5jZVZpZGVvSW5wdXQoaW5wdXQpO1xuXG4gIHJldHVybiBzdWJtaXQoY29udGV4dCwgJ2dlbmVyYXRlU2VlZGFuY2VWaWRlbycsIHdpdGhXZWJob29rKFNFRURBTkNFX1ZJREVPX0VORFBPSU5ULCB3ZWJob29rVXJsKSwge1xuICAgIGR1cmF0aW9uOiB2YWxpZGF0ZWQuZHVyYXRpb24sXG4gICAgZW5kX2ltYWdlX3VybDogdmFsaWRhdGVkLmVuZEltYWdlVXJsLFxuICAgIGdlbmVyYXRlX2F1ZGlvOiB2YWxpZGF0ZWQuZ2VuZXJhdGVBdWRpbyxcbiAgICBpbWFnZV91cmw6IHZhbGlkYXRlZC5pbWFnZVVybCxcbiAgICBvdXRwdXRfZm9ybWF0OiB2YWxpZGF0ZWQub3V0cHV0Rm9ybWF0LFxuICAgIHByb21wdDogdmFsaWRhdGVkLnByb21wdCxcbiAgICByZXNvbHV0aW9uOiB2YWxpZGF0ZWQucmVzb2x1dGlvblxuICB9KTtcbn07XG5cbmV4cG9ydCBjb25zdCBnZW5lcmF0ZVNlZWRhbmNlUmVmZXJlbmNlVmlkZW8gPSAoXG4gIGNvbnRleHQ6IEFwaUNvbnRleHQsIGlucHV0OiBTZWVkYW5jZVJlZmVyZW5jZVZpZGVvSW5wdXQsIHdlYmhvb2tVcmw/OiBzdHJpbmdcbik6IFByb21pc2U8SGlnZ3NmaWVsZFJlcXVlc3RSZXN1bHQ+ID0+IHtcbiAgY29uc3QgdmFsaWRhdGVkID0gdmFsaWRhdGVTZWVkYW5jZVJlZmVyZW5jZVZpZGVvSW5wdXQoaW5wdXQpO1xuXG4gIHJldHVybiBzdWJtaXQoY29udGV4dCwgJ2dlbmVyYXRlU2VlZGFuY2VSZWZlcmVuY2VWaWRlbycsIHdpdGhXZWJob29rKFNFRURBTkNFX1JFRkVSRU5DRV9WSURFT19FTkRQT0lOVCwgd2ViaG9va1VybCksIHtcbiAgICBhc3BlY3RfcmF0aW86IHZhbGlkYXRlZC5hc3BlY3RSYXRpbyxcbiAgICBhdWRpb191cmxzOiB2YWxpZGF0ZWQuYXVkaW9VcmxzLFxuICAgIGR1cmF0aW9uOiB2YWxpZGF0ZWQuZHVyYXRpb24sXG4gICAgZ2VuZXJhdGVfYXVkaW86IHZhbGlkYXRlZC5nZW5lcmF0ZUF1ZGlvLFxuICAgIGltYWdlX3VybHM6IHZhbGlkYXRlZC5pbWFnZVVybHMsXG4gICAgb3V0cHV0X2Zvcm1hdDogdmFsaWRhdGVkLm91dHB1dEZvcm1hdCxcbiAgICBwcm9tcHQ6IHZhbGlkYXRlZC5wcm9tcHQsXG4gICAgcmVzb2x1dGlvbjogdmFsaWRhdGVkLnJlc29sdXRpb24sXG4gICAgdmlkZW9fdXJsczogdmFsaWRhdGVkLnZpZGVvVXJsc1xuICB9KTtcbn07XG5cbmV4cG9ydCBjb25zdCBnZW5lcmF0ZU1hcmtldGluZ1N0dWRpb0ltYWdlID0gKFxuICBjb250ZXh0OiBBcGlDb250ZXh0LCBpbnB1dDogTWFya2V0aW5nU3R1ZGlvSW1hZ2VJbnB1dCwgd2ViaG9va1VybD86IHN0cmluZ1xuKTogUHJvbWlzZTxIaWdnc2ZpZWxkUmVxdWVzdFJlc3VsdD4gPT4ge1xuICBjb25zdCB2YWxpZGF0ZWQgPSB2YWxpZGF0ZU1hcmtldGluZ1N0dWRpb0ltYWdlSW5wdXQoaW5wdXQpO1xuXG4gIHJldHVybiBzdWJtaXQoY29udGV4dCwgJ2dlbmVyYXRlTWFya2V0aW5nU3R1ZGlvSW1hZ2UnLCB3aXRoV2ViaG9vayhNQVJLRVRJTkdfU1RVRElPX0lNQUdFX0VORFBPSU5ULCB3ZWJob29rVXJsKSwge1xuICAgIGFzcGVjdF9yYXRpbzogdmFsaWRhdGVkLmFzcGVjdFJhdGlvLFxuICAgIGVuaGFuY2VfcHJvbXB0OiB2YWxpZGF0ZWQuZW5oYW5jZVByb21wdCxcbiAgICBpbWFnZV91cmxzOiB2YWxpZGF0ZWQuaW1hZ2VVcmxzLFxuICAgIHByZXNldF9pZDogdmFsaWRhdGVkLnByZXNldElkLFxuICAgIHByb21wdDogdmFsaWRhdGVkLnByb21wdCxcbiAgICBxdWFsaXR5OiB2YWxpZGF0ZWQucXVhbGl0eSxcbiAgICByZXNvbHV0aW9uOiB2YWxpZGF0ZWQucmVzb2x1dGlvblxuICB9KTtcbn07XG5cbmV4cG9ydCBjb25zdCBnZXRIaWdnc2ZpZWxkUmVxdWVzdFN0YXR1cyA9IGFzeW5jIChcbiAgY29udGV4dDogQXBpQ29udGV4dCwgcmVxdWVzdElkOiBzdHJpbmdcbik6IFByb21pc2U8SGlnZ3NmaWVsZFN0YXR1c1Jlc3VsdD4gPT4ge1xuICB0cnkge1xuICAgIGNvbnN0IHN0YXR1c1VybCA9IHZhbGlkYXRlSGlnZ3NmaWVsZFVybChgJHtISUdHU0ZJRUxEX09SSUdJTn0vcmVxdWVzdHMvJHtyZXF1ZXN0SWR9L3N0YXR1c2AsIHJlcXVlc3RJZCwgJ3N0YXR1cycpO1xuICAgIGNvbnN0IGRhdGEgPSBhd2FpdCBnZXQoc3RhdHVzVXJsLCB7fSwge2NhY2hlOiBmYWxzZSwgaGVhZGVyczogYXV0aEhlYWRlcnMoKX0pIGFzIEhpZ2dzZmllbGRSZXNwb25zZUJvZHk7XG5cbiAgICBpZihkYXRhLnJlcXVlc3RfaWQgIT09IHJlcXVlc3RJZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdIaWdnc2ZpZWxkIHN0YXR1cyByZXNwb25zZSByZXR1cm5lZCBhbiB1bmV4cGVjdGVkIHJlcXVlc3QgaWRlbnRpZmllci4nKTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgZXJyb3I6IGRhdGEuZXJyb3IsXG4gICAgICBtZWRpYVVybDogZGF0YS52aWRlbz8udXJsIHx8IGRhdGEuaW1hZ2VzPy5bMF0/LnVybCxcbiAgICAgIG1lZGlhVXJsczogZGF0YS5pbWFnZXM/Lm1hcCgoaW1hZ2UpID0+IGltYWdlLnVybCkuZmlsdGVyKCh1cmwpOiB1cmwgaXMgc3RyaW5nID0+IEJvb2xlYW4odXJsKSksXG4gICAgICByZXF1ZXN0SWQsXG4gICAgICBzdGF0dXM6IGRhdGEuc3RhdHVzIHx8ICd1bmtub3duJ1xuICAgIH07XG4gIH0gY2F0Y2goZXJyb3IpIHtcbiAgICByZXR1cm4gbG9nRXJyb3IoXG4gICAgICB7YWN0aW9uOiAnZ2V0SGlnZ3NmaWVsZFJlcXVlc3RTdGF0dXMnLCBjYXRlZ29yeTogZXZlbnRDYXRlZ29yeSwgdmFsdWU6IEVycm9yVHlwZXMuRVhURVJOQUxfQVBJX0VSUk9SfSwgZXJyb3IgYXMgRXJyb3IsIGNvbnRleHRcbiAgICApIGFzIFByb21pc2U8bmV2ZXI+O1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgY2FuY2VsSGlnZ3NmaWVsZFJlcXVlc3QgPSBhc3luYyAoY29udGV4dDogQXBpQ29udGV4dCwgcmVxdWVzdElkOiBzdHJpbmcpOiBQcm9taXNlPGJvb2xlYW4+ID0+IHtcbiAgdHJ5IHtcbiAgICBjb25zdCBjYW5jZWxVcmwgPSB2YWxpZGF0ZUhpZ2dzZmllbGRVcmwoYCR7SElHR1NGSUVMRF9PUklHSU59L3JlcXVlc3RzLyR7cmVxdWVzdElkfS9jYW5jZWxgLCByZXF1ZXN0SWQsICdjYW5jZWwnKTtcbiAgICBhd2FpdCBwb3N0KGNhbmNlbFVybCwge30sIHtjYWNoZTogZmFsc2UsIGhlYWRlcnM6IGF1dGhIZWFkZXJzKCl9KTtcblxuICAgIHJldHVybiAoYXdhaXQgZ2V0SGlnZ3NmaWVsZFJlcXVlc3RTdGF0dXMoY29udGV4dCwgcmVxdWVzdElkKSkuc3RhdHVzID09PSAnY2FuY2VsZWQnO1xuICB9IGNhdGNoKGVycm9yKSB7XG4gICAgcmV0dXJuIGxvZ0Vycm9yKFxuICAgICAge2FjdGlvbjogJ2NhbmNlbEhpZ2dzZmllbGRSZXF1ZXN0JywgY2F0ZWdvcnk6IGV2ZW50Q2F0ZWdvcnksIHZhbHVlOiBFcnJvclR5cGVzLkVYVEVSTkFMX0FQSV9FUlJPUn0sIGVycm9yIGFzIEVycm9yLCBjb250ZXh0XG4gICAgKSBhcyBQcm9taXNlPG5ldmVyPjtcbiAgfVxufTtcblxuLyoqIFN1Ym1pdCBvbmUgYWxsb3dsaXN0ZWQgY2F0YWxvZyBtb2RlbDsgbmV2ZXIgcmV0cnkgYSBzdWJtaXNzaW9uIHdpdGggYW4gdW5rbm93biBvdXRjb21lLiAqL1xuZXhwb3J0IGNvbnN0IGdlbmVyYXRlSGlnZ3NmaWVsZE1vZGVsID0gKFxuICBjb250ZXh0OiBBcGlDb250ZXh0LCBtb2RlbElkOiBzdHJpbmcsIGlucHV0OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiwgd2ViaG9va1VybD86IHN0cmluZ1xuKTogUHJvbWlzZTxIaWdnc2ZpZWxkUmVxdWVzdFJlc3VsdD4gPT4ge1xuICBjb25zdCBtb2RlbCA9IGdldEhpZ2dzZmllbGRNb2RlbChtb2RlbElkKTtcbiAgcmV0dXJuIHN1Ym1pdChjb250ZXh0LCAnZ2VuZXJhdGVIaWdnc2ZpZWxkTW9kZWwnLCB3aXRoV2ViaG9vayhgJHtISUdHU0ZJRUxEX09SSUdJTn0vJHttb2RlbC5pZH1gLCB3ZWJob29rVXJsKSxcbiAgICB2YWxpZGF0ZUhpZ2dzZmllbGRNb2RlbElucHV0KG1vZGVsSWQsIGlucHV0KSk7XG59O1xuIl0sIm5hbWVzIjpbImdldCIsInBvc3QiLCJ2YWxpZGF0ZU1hcmtldGluZ1N0dWRpb0ltYWdlSW5wdXQiLCJ2YWxpZGF0ZVNlZWRhbmNlUmVmZXJlbmNlVmlkZW9JbnB1dCIsInZhbGlkYXRlU2VlZGFuY2VWaWRlb0lucHV0IiwidmFsaWRhdGVTb3VsSW1hZ2VJbnB1dCIsImdldEhpZ2dzZmllbGRNb2RlbCIsInZhbGlkYXRlSGlnZ3NmaWVsZE1vZGVsSW5wdXQiLCJDb25maWciLCJFcnJvclR5cGVzIiwibG9nRXJyb3IiLCJldmVudENhdGVnb3J5IiwiSElHR1NGSUVMRF9PUklHSU4iLCJTT1VMX0lNQUdFX0VORFBPSU5UIiwiU0VFREFOQ0VfVklERU9fRU5EUE9JTlQiLCJTRUVEQU5DRV9SRUZFUkVOQ0VfVklERU9fRU5EUE9JTlQiLCJNQVJLRVRJTkdfU1RVRElPX0lNQUdFX0VORFBPSU5UIiwidmFsaWRhdGVIaWdnc2ZpZWxkVXJsIiwidmFsdWUiLCJyZXF1ZXN0SWQiLCJhY3Rpb24iLCJ1cmwiLCJVUkwiLCJvcmlnaW4iLCJ1c2VybmFtZSIsInBhc3N3b3JkIiwicGF0aG5hbWUiLCJzZWFyY2giLCJoYXNoIiwiRXJyb3IiLCJocmVmIiwiYXV0aEhlYWRlcnMiLCJrZXlJZCIsImtleVNlY3JldCIsIkhlYWRlcnMiLCJBdXRob3JpemF0aW9uIiwid2l0aFdlYmhvb2siLCJlbmRwb2ludCIsIndlYmhvb2tVcmwiLCJlbmNvZGVVUklDb21wb25lbnQiLCJzdWJtaXQiLCJjb250ZXh0IiwiYm9keSIsImRhdGEiLCJjYWNoZSIsImhlYWRlcnMiLCJyZXF1ZXN0X2lkIiwic3RhdHVzX3VybCIsImNhbmNlbFVybCIsImNhbmNlbF91cmwiLCJ1bmRlZmluZWQiLCJzdGF0dXNVcmwiLCJlcnJvciIsImNhdGVnb3J5IiwiRVhURVJOQUxfQVBJX0VSUk9SIiwiZ2VuZXJhdGVTb3VsSW1hZ2UiLCJpbnB1dCIsInZhbGlkYXRlZCIsImFzcGVjdF9yYXRpbyIsImFzcGVjdFJhdGlvIiwiYmF0Y2hfc2l6ZSIsImJhdGNoU2l6ZSIsImVuaGFuY2VfcHJvbXB0IiwiZW5oYW5jZVByb21wdCIsInByb21wdCIsInJlc29sdXRpb24iLCJzZWVkIiwic3R5bGVfaWQiLCJzdHlsZUlkIiwiZ2VuZXJhdGVTZWVkYW5jZVZpZGVvIiwiZHVyYXRpb24iLCJlbmRfaW1hZ2VfdXJsIiwiZW5kSW1hZ2VVcmwiLCJnZW5lcmF0ZV9hdWRpbyIsImdlbmVyYXRlQXVkaW8iLCJpbWFnZV91cmwiLCJpbWFnZVVybCIsIm91dHB1dF9mb3JtYXQiLCJvdXRwdXRGb3JtYXQiLCJnZW5lcmF0ZVNlZWRhbmNlUmVmZXJlbmNlVmlkZW8iLCJhdWRpb191cmxzIiwiYXVkaW9VcmxzIiwiaW1hZ2VfdXJscyIsImltYWdlVXJscyIsInZpZGVvX3VybHMiLCJ2aWRlb1VybHMiLCJnZW5lcmF0ZU1hcmtldGluZ1N0dWRpb0ltYWdlIiwicHJlc2V0X2lkIiwicHJlc2V0SWQiLCJxdWFsaXR5IiwiZ2V0SGlnZ3NmaWVsZFJlcXVlc3RTdGF0dXMiLCJtZWRpYVVybCIsInZpZGVvIiwiaW1hZ2VzIiwibWVkaWFVcmxzIiwibWFwIiwiaW1hZ2UiLCJmaWx0ZXIiLCJCb29sZWFuIiwic3RhdHVzIiwiY2FuY2VsSGlnZ3NmaWVsZFJlcXVlc3QiLCJnZW5lcmF0ZUhpZ2dzZmllbGRNb2RlbCIsIm1vZGVsSWQiLCJtb2RlbCIsImlkIl0sIm1hcHBpbmdzIjoiQUFBQTs7O0NBR0MsR0FDRCxTQUFRQSxHQUFHLEVBQUVDLElBQUksUUFBTyxvQkFBb0I7QUFFNUMsU0FDRUMsaUNBQWlDLEVBQ2pDQyxtQ0FBbUMsRUFDbkNDLDBCQUEwQixFQUMxQkMsc0JBQXNCLFFBQ2pCLG1DQUFtQztBQUMxQyxTQUFRQyxrQkFBa0IsUUFBTyx3Q0FBd0M7QUFDekUsU0FBUUMsNEJBQTRCLFFBQU8sa0NBQWtDO0FBQzdFLFNBQVFDLE1BQU0sUUFBTyxlQUFlO0FBQ3BDLFNBQVFDLFVBQVUsUUFBTywwQkFBMEI7QUFDbkQsU0FBUUMsUUFBUSxRQUFPLDZCQUE2QjtBQVVwRCxNQUFNQyxnQkFBZ0I7QUFDdEIsTUFBTUMsb0JBQW9CO0FBQzFCLE1BQU1DLHNCQUFzQixHQUFHRCxrQkFBa0IsK0JBQStCLENBQUM7QUFDakYsTUFBTUUsMEJBQTBCLEdBQUdGLGtCQUFrQixzQ0FBc0MsQ0FBQztBQUM1RixNQUFNRyxvQ0FBb0MsR0FBR0gsa0JBQWtCLDBDQUEwQyxDQUFDO0FBQzFHLE1BQU1JLGtDQUFrQyxHQUFHSixrQkFBa0IsdUJBQXVCLENBQUM7QUEyQnJGLHNGQUFzRixHQUN0RixNQUFNSyx3QkFBd0IsQ0FBQ0MsT0FBZUMsV0FBbUJDO0lBQy9ELE1BQU1DLE1BQU0sSUFBSUMsSUFBSUo7SUFFcEIsSUFBR0csSUFBSUUsTUFBTSxLQUFLWCxxQkFBcUJTLElBQUlHLFFBQVEsSUFBSUgsSUFBSUksUUFBUSxJQUNqRUosSUFBSUssUUFBUSxLQUFLLENBQUMsVUFBVSxFQUFFUCxVQUFV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
@@ -5,7 +5,11 @@ import type { ApiContext } from '../types/auth.types.js';
5
5
  /** Only an explicit provider rejection proves it is safe to release a reservation. */
6
6
  export declare class ImageGenerationRejectedError extends Error {
7
7
  }
8
- export type GenerateImageInput = (GeminiImageInput & {
8
+ export type GenerateImageInput = {
9
+ model: string;
10
+ modelInput: Record<string, unknown>;
11
+ provider: 'higgsfield';
12
+ } | (GeminiImageInput & {
9
13
  provider: 'gemini';
10
14
  }) | (OpenAIImageInput & {
11
15
  provider: 'openai';