@reventlessdev/reventless-aws 3.0.0-alpha.208 → 3.0.0-alpha.210

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.
@@ -146,97 +146,6 @@ let deploySchemaWithRetry = (
146
146
  () => startSchemaCreation(client, {apiId, definition})->Promise.then(_ => Promise.resolve()),
147
147
  )->Effect.retry(AppSync_Error.retrySchedule)
148
148
 
149
- // ── Schema-push serialization lock ──────────────────────────────────────────
150
- //
151
- // Plugin/service stacks share one AppSync API, and StartSchemaCreation REPLACES
152
- // the whole schema. When two stacks scan the deploy-schema table, stitch, and
153
- // push concurrently, a push built from a stale scan (missing a peer's not-yet-
154
- // written fragment) clobbers the peer's fields — orphaning their resolvers
155
- // (NotFoundException: No field named X). The shrink guard only catches
156
- // catastrophic (>threshold) drops, not a single dropped field.
157
- //
158
- // This lease serialises scan→stitch→push across stacks via a conditional-write
159
- // lock row in the shared PluginSchemaPersistence table. A push that holds the
160
- // lease always scans a table already containing every prior push's fragment, so
161
- // the last push is complete and nothing is clobbered. The lease carries a TTL so
162
- // a crashed holder cannot deadlock the table; if the lock cannot be acquired
163
- // within maxWaitMs we proceed best-effort rather than fail the deploy.
164
-
165
- @val external schemaLockSetTimeout: (unit => unit, int) => unit = "setTimeout"
166
- let schemaLockSleep = (ms: int): promise<unit> =>
167
- Promise.make((resolve, _) => schemaLockSetTimeout(() => resolve(), ms))
168
- let _schemaLockCounter = ref(0)
169
-
170
- let withSchemaPushLock = async (
171
- ~tableName: string,
172
- ~apiId: string,
173
- ~leaseMs: int=120000,
174
- ~maxWaitMs: int=180000,
175
- fn: unit => promise<'a>,
176
- ): 'a => {
177
- open AwsSdk.DynamoDb.DocumentClient
178
- let lockId = `schema-push-lock:${apiId}`
179
- _schemaLockCounter := _schemaLockCounter.contents + 1
180
- let holder = `${apiId}#${Date.now()->Float.toString}#${_schemaLockCounter.contents->Int.toString}`
181
-
182
- let acquire = async () => {
183
- let deadline = Date.now() +. maxWaitMs->Int.toFloat
184
- let acquired = ref(false)
185
- while !acquired.contents {
186
- let now = Date.now()
187
- let ok =
188
- await PutCommand.make({
189
- PutCommand.tableName,
190
- item: Dict.fromArray([
191
- ("id", lockId->JSON.Encode.string),
192
- ("holder", holder->JSON.Encode.string),
193
- ("expiresAt", (now +. leaseMs->Int.toFloat)->JSON.Encode.float),
194
- ])->JSON.Encode.object,
195
- conditionExpression: "attribute_not_exists(id) OR expiresAt < :now",
196
- expressionAttributeValues: Dict.fromArray([(":now", now->JSON.Encode.float)]),
197
- })
198
- ->PutCommand.send
199
- ->Promise.thenResolve(_ => true)
200
- ->Promise.catch(_ => Promise.resolve(false))
201
- if ok {
202
- acquired := true
203
- } else if Date.now() > deadline {
204
- log.warn(
205
- ~comp="AppSync_Adapter",
206
- `schema-push lock for ${apiId} not acquired within ${maxWaitMs->Int.toString}ms — proceeding best-effort`,
207
- )
208
- acquired := true
209
- } else {
210
- await schemaLockSleep(1000)
211
- }
212
- }
213
- }
214
-
215
- let release = async () => {
216
- let _ =
217
- await DeleteCommand.make({
218
- DeleteCommand.tableName,
219
- key: Dict.fromArray([("id", lockId->JSON.Encode.string)]),
220
- conditionExpression: "holder = :holder",
221
- expressionAttributeValues: Dict.fromArray([(":holder", holder->JSON.Encode.string)]),
222
- })
223
- ->DeleteCommand.send
224
- ->Promise.thenResolve(_ => ())
225
- ->Promise.catch(_ => Promise.resolve()) // expired lease stolen by a peer — leave theirs intact
226
- }
227
-
228
- await acquire()
229
- try {
230
- let r = await fn()
231
- let _ = await release()
232
- r
233
- } catch {
234
- | exn =>
235
- let _ = await release()
236
- throw(exn)
237
- }
238
- }
239
-
240
149
  // Lazy singleton AppSync client (runtime only)
241
150
  let _client: ref<option<appSyncClient>> = ref(None)
242
151
  let getClient = () =>
@@ -248,6 +157,77 @@ let getClient = () =>
248
157
  c
249
158
  }
250
159
 
160
+ // ── GetSourceApiAssociation — merged-API association status poll ──────────
161
+ // Merged-API deploys must fail loudly on MERGE_FAILED (plan
162
+ // merged-api-push-free-composition, Phase 0 finding: a failed merge silently
163
+ // keeps the last-good merged schema serving). After creating a
164
+ // SourceApiAssociation, poll until the initial merge lands.
165
+ type getSourceApiAssociationInput = {
166
+ associationId: string,
167
+ mergedApiIdentifier: string,
168
+ }
169
+ type getSourceApiAssociationCommand
170
+ type sourceApiAssociationSummary = {
171
+ sourceApiAssociationStatus: option<string>,
172
+ sourceApiAssociationStatusDetail: option<string>,
173
+ }
174
+ type getSourceApiAssociationResult = {sourceApiAssociation: option<sourceApiAssociationSummary>}
175
+
176
+ @module("@aws-sdk/client-appsync") @new
177
+ external makeGetSourceApiAssociationCommand: getSourceApiAssociationInput => getSourceApiAssociationCommand =
178
+ "GetSourceApiAssociationCommand"
179
+
180
+ @send
181
+ external sendGetSourceApiAssociation: (
182
+ appSyncClient,
183
+ getSourceApiAssociationCommand,
184
+ ) => promise<getSourceApiAssociationResult> = "send"
185
+
186
+ // Poll until the association reports MERGE_SUCCESS; throw with the AWS status
187
+ // detail on MERGE_FAILED / AUTO_MERGE_SCHEDULE_FAILED. Auto-merge lands in
188
+ // ~12 s (spike-measured), so 60 × 2 s bounds the wait at two minutes.
189
+ let rec waitForMergeSuccess = async (
190
+ client: appSyncClient,
191
+ ~associationId: string,
192
+ ~mergedApiIdentifier: string,
193
+ ~maxAttempts=60,
194
+ ~attempt=0,
195
+ ~delayMs=2000,
196
+ ) => {
197
+ let result = await client->sendGetSourceApiAssociation(
198
+ {associationId, mergedApiIdentifier}->makeGetSourceApiAssociationCommand,
199
+ )
200
+ let status =
201
+ result.sourceApiAssociation
202
+ ->Option.flatMap(a => a.sourceApiAssociationStatus)
203
+ ->Option.getOr("(no status)")
204
+ let detail =
205
+ result.sourceApiAssociation
206
+ ->Option.flatMap(a => a.sourceApiAssociationStatusDetail)
207
+ ->Option.getOr("(no details)")
208
+ switch status {
209
+ | "MERGE_SUCCESS" => ()
210
+ | "MERGE_FAILED" | "AUTO_MERGE_SCHEDULE_FAILED" =>
211
+ JsError.throwWithMessage(
212
+ `Source API association ${associationId} on ${mergedApiIdentifier} failed to merge (${status}): ${detail}`,
213
+ )
214
+ | _ if attempt >= maxAttempts =>
215
+ JsError.throwWithMessage(
216
+ `Source API association ${associationId} merge timed out after ${maxAttempts->Int.toString} attempts (status: ${status})`,
217
+ )
218
+ | _ =>
219
+ await Promise.make((resolve, _) => setTimeout(resolve, delayMs)->ignore)
220
+ await waitForMergeSuccess(
221
+ client,
222
+ ~associationId,
223
+ ~mergedApiIdentifier,
224
+ ~maxAttempts,
225
+ ~attempt=attempt + 1,
226
+ ~delayMs,
227
+ )
228
+ }
229
+ }
230
+
251
231
  // ── @aws_auth directive injection ─────────────────────────────────────────
252
232
  // Injects @aws_auth(cognito_groups: [...]) directives into SDL field strings
253
233
  // based on authorization metadata from schema entries.
@@ -524,13 +504,40 @@ let stitchWithAwsDirectives = (
524
504
  ->stampSharedIamTypes
525
505
  }
526
506
 
507
+ /**
508
+ Merged-mode plugin subgraph document: one fragment rendered standalone
509
+ (relay base types included, global `node` omitted — only the platform's
510
+ canonical base document carries `node`), with the same AppSync dialect as
511
+ `stitchWithAwsDirectives`. No `@canonical` stamps — plugin subgraphs stay
512
+ unstamped; the admin source's canonical definitions win on merge.
513
+ */
514
+ let stitchStandaloneWithAwsDirectives = (
515
+ ~fragment: Reventless.Plugin.apiSchemaFragment,
516
+ ): string => {
517
+ let sources = ReventlessCore.GraphQL_Stitcher.collectSubscriptionSources(
518
+ ~baseFragment=fragment,
519
+ ~pluginFragments=[],
520
+ )
521
+ ReventlessCore.GraphQL_Stitcher.stitchStandalone(~fragment)
522
+ ->AppSync_SdlDecorate.injectAwsSubscribe(~sources)
523
+ ->stampSharedIamTypes
524
+ }
525
+
527
526
  // ── Provider implementation ────────────────────────────────────────────────
528
527
 
529
528
  type api = AppSync.GraphQLApi.t
530
529
  type role = IAM.Role.t
531
530
 
532
- let makeApiResource = (
531
+ // Primary authentication mode every platform-created AppSync API uses. A
532
+ // merged API and its source APIs must share this primary mode — exported via
533
+ // StackReference (`mergedApiPrimaryAuth`) and asserted where associations are
534
+ // created (AppSync_MergedApi.assertCompatiblePrimaryAuth).
535
+ let primaryAuthenticationType = AppSync.GraphQLApi.AMAZON_COGNITO_USER_POOLS
536
+
537
+ let _makeApiResourceWith = (
533
538
  ~name: string,
539
+ ~schema: option<string>,
540
+ ~userPoolConfig: option<Pulumi.Output.t<AppSync.GraphQLApi.userPoolConfig>>,
534
541
  ~opts: Pulumi.ComponentResource.options,
535
542
  ): (Pulumi.Output.t<api>, Pulumi.Output.t<role>) => {
536
543
  let customOpts: Pulumi.CustomResourceOptions.t = {
@@ -547,13 +554,16 @@ let makeApiResource = (
547
554
  ~opts=Some(customOpts),
548
555
  )
549
556
 
550
- // Resolve the Cognito UserPool — cached inside Platform_Stack, so calling
551
- // from each API call site (DomainApi, PlatformApi) is safe. Returned as a
552
- // single Output that yields the {userPoolId, awsRegion, defaultAction}
553
- // record AppSync expects.
554
- let authConfigOut = Auth_Cognito.make(~name=`${name}-auth`)
555
- let userPoolConfigOut =
556
- authConfigOut->Pulumi.Output.apply((c: Auth_Cognito.authConfig) =>
557
+ // Resolve the Cognito UserPool — either supplied by the caller (plugin-stack
558
+ // source APIs read it from the platform's StackReference exports so they
559
+ // never provision pool/client resources of their own) or resolved via
560
+ // Auth_Cognito (cached inside Platform_Stack, so calling from each API call
561
+ // site DomainApi, PlatformApi — is safe). A single Output yielding the
562
+ // {userPoolId, awsRegion, defaultAction} record AppSync expects.
563
+ let userPoolConfigOut = switch userPoolConfig {
564
+ | Some(config) => config
565
+ | None =>
566
+ Auth_Cognito.make(~name=`${name}-auth`)->Pulumi.Output.apply((c: Auth_Cognito.authConfig) =>
557
567
  (
558
568
  {
559
569
  userPoolId: c.userPoolId,
@@ -562,13 +572,13 @@ let makeApiResource = (
562
572
  }: AppSync.GraphQLApi.userPoolConfig
563
573
  )
564
574
  )
575
+ }
565
576
 
566
577
  // Cognito as primary auth, AWS_IAM as additional provider for
567
578
  // server-to-server lambdas (heartbeat, Plugin_Connected emission) signed via
568
579
  // the existing IAM role.
569
580
  let apiArgs: AppSync.GraphQLApi.args = {
570
- authenticationType: AppSync.GraphQLApi
571
- .AMAZON_COGNITO_USER_POOLS->Pulumi.Input.make,
581
+ authenticationType: primaryAuthenticationType->Pulumi.Input.make,
572
582
  userPoolConfig: userPoolConfigOut->Pulumi.Output.asInput,
573
583
  additionalAuthenticationProviders: [
574
584
  (
@@ -577,12 +587,45 @@ let makeApiResource = (
577
587
  }: AppSync.GraphQLApi.additionalAuthenticationProvider
578
588
  )->Pulumi.Input.make,
579
589
  ]->Pulumi.Input.make,
590
+ schema: ?(schema->Option.map(Pulumi.Input.make)),
580
591
  }
581
592
  let graphQLApi = AppSync.GraphQLApi.make(~name, ~args=apiArgs, ~opts=Some(customOpts))
582
593
 
583
594
  (graphQLApi->Pulumi.Output.make, iamRole->Pulumi.Output.make)
584
595
  }
585
596
 
597
+ let makeApiResource = (
598
+ ~name: string,
599
+ ~opts: Pulumi.ComponentResource.options,
600
+ ): (Pulumi.Output.t<api>, Pulumi.Output.t<role>) =>
601
+ _makeApiResourceWith(~name, ~schema=None, ~userPoolConfig=None, ~opts)
602
+
603
+ // Merged-mode source API: same auth shape as makeApiResource but with a
604
+ // DECLARATIVE inline schema — the provider runs StartSchemaCreation + poll
605
+ // before the resource resolves, so resolvers chained on the API are ordered
606
+ // after the schema is ACTIVE without the push-path hook machinery. Not part
607
+ // of the Api_Adapter.Provider interface (Platform.res calls it directly on
608
+ // the merge path).
609
+ let makeSourceApiResource = (
610
+ ~name: string,
611
+ ~schema: string,
612
+ ~opts: Pulumi.ComponentResource.options,
613
+ ): (Pulumi.Output.t<api>, Pulumi.Output.t<role>) =>
614
+ _makeApiResourceWith(~name, ~schema=Some(schema), ~userPoolConfig=None, ~opts)
615
+
616
+ // Merged-mode PLUGIN source API: schema-less at creation (the plugin's
617
+ // standalone subgraph document is only computable during P.make(), so
618
+ // preResolversSchemaHook pushes it — the plugin's own API is a single writer
619
+ // by construction). The user pool comes from the platform's StackReference
620
+ // exports so the merged endpoint's Cognito primary auth matches across every
621
+ // source API without the plugin stack provisioning pool/client resources.
622
+ let makePluginSourceApiResource = (
623
+ ~name: string,
624
+ ~userPoolConfig: Pulumi.Output.t<AppSync.GraphQLApi.userPoolConfig>,
625
+ ~opts: Pulumi.ComponentResource.options,
626
+ ): (Pulumi.Output.t<api>, Pulumi.Output.t<role>) =>
627
+ _makeApiResourceWith(~name, ~schema=None, ~userPoolConfig=Some(userPoolConfig), ~opts)
628
+
586
629
  let generateFragment = (
587
630
  ~mutationEntries: array<ReventlessInfra.Api.mutationSchemaEntry>,
588
631
  ~queryEntries: array<ReventlessInfra.Api.querySchemaEntry>,
@@ -10,15 +10,12 @@ import * as Stdlib_String from "@rescript/runtime/lib/es6/Stdlib_String.js";
10
10
  import * as Effect$1 from "effect/Effect";
11
11
  import * as Pulumi from "@pulumi/pulumi";
12
12
  import * as Stdlib_JsError from "@rescript/runtime/lib/es6/Stdlib_JsError.js";
13
- import * as Stdlib_Promise from "@rescript/runtime/lib/es6/Stdlib_Promise.js";
14
13
  import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
15
14
  import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js";
16
- import * as LibDynamodb from "@aws-sdk/lib-dynamodb";
17
15
  import * as Logger$ReventlessCore from "@reventlessdev/reventless-core/src/util/Logger.res.mjs";
18
16
  import * as ClientAppsync from "@aws-sdk/client-appsync";
19
17
  import * as Auth_Cognito$ReventlessAws from "../../adapter/Auth/Auth_Cognito.res.mjs";
20
18
  import * as AppSync_Error$ReventlessAws from "../../errors/AppSync_Error.res.mjs";
21
- import * as DynamoDb_DocumentClient$AwsSdk from "@reventlessdev/rescript-aws-sdk/src/DynamoDb_DocumentClient.res.mjs";
22
19
  import * as GraphQL_Stitcher$ReventlessCore from "@reventlessdev/reventless-core/src/components/Api/GraphQL_Stitcher.res.mjs";
23
20
  import * as AppSync_SdlDecorate$ReventlessAws from "./AppSync_SdlDecorate.res.mjs";
24
21
  import * as GraphQL_FragmentGenerator$ReventlessCore from "@reventlessdev/reventless-core/src/components/Api/GraphQL_FragmentGenerator.res.mjs";
@@ -90,84 +87,6 @@ function deploySchemaWithRetry(client, apiId, definition) {
90
87
  })).then(param => Promise.resolve())), AppSync_Error$ReventlessAws.retrySchedule);
91
88
  }
92
89
 
93
- function schemaLockSleep(ms) {
94
- return new Promise((resolve, param) => {
95
- setTimeout(() => resolve(), ms);
96
- });
97
- }
98
-
99
- let _schemaLockCounter = {
100
- contents: 0
101
- };
102
-
103
- async function withSchemaPushLock(tableName, apiId, leaseMsOpt, maxWaitMsOpt, fn) {
104
- let leaseMs = leaseMsOpt !== undefined ? leaseMsOpt : 120000;
105
- let maxWaitMs = maxWaitMsOpt !== undefined ? maxWaitMsOpt : 180000;
106
- let lockId = `schema-push-lock:` + apiId;
107
- _schemaLockCounter.contents = _schemaLockCounter.contents + 1 | 0;
108
- let holder = apiId + `#` + Date.now().toString() + `#` + _schemaLockCounter.contents.toString();
109
- let acquire = async () => {
110
- let deadline = Date.now() + maxWaitMs;
111
- let acquired = false;
112
- while (!acquired) {
113
- let now = Date.now();
114
- let ok = await Stdlib_Promise.$$catch(DynamoDb_DocumentClient$AwsSdk.PutCommand.send(new LibDynamodb.PutCommand({
115
- Item: Object.fromEntries([
116
- [
117
- "id",
118
- lockId
119
- ],
120
- [
121
- "holder",
122
- holder
123
- ],
124
- [
125
- "expiresAt",
126
- now + leaseMs
127
- ]
128
- ]),
129
- TableName: tableName,
130
- ConditionExpression: "attribute_not_exists(id) OR expiresAt < :now",
131
- ExpressionAttributeValues: Object.fromEntries([[
132
- ":now",
133
- now
134
- ]])
135
- })).then(param => true), param => Promise.resolve(false));
136
- if (ok) {
137
- acquired = true;
138
- } else if (Date.now() > deadline) {
139
- log.warn("AppSync_Adapter", undefined, `schema-push lock for ` + apiId + ` not acquired within ` + maxWaitMs.toString() + `ms — proceeding best-effort`);
140
- acquired = true;
141
- } else {
142
- await schemaLockSleep(1000);
143
- }
144
- };
145
- };
146
- let release = async () => {
147
- await Stdlib_Promise.$$catch(DynamoDb_DocumentClient$AwsSdk.DeleteCommand.send(new LibDynamodb.DeleteCommand({
148
- TableName: tableName,
149
- Key: Object.fromEntries([[
150
- "id",
151
- lockId
152
- ]]),
153
- ConditionExpression: "holder = :holder",
154
- ExpressionAttributeValues: Object.fromEntries([[
155
- ":holder",
156
- holder
157
- ]])
158
- })).then(param => {}), param => Promise.resolve());
159
- };
160
- await acquire();
161
- try {
162
- let r = await fn();
163
- await release();
164
- return r;
165
- } catch (exn) {
166
- await release();
167
- throw exn;
168
- }
169
- }
170
-
171
90
  let _client = {
172
91
  contents: undefined
173
92
  };
@@ -182,6 +101,35 @@ function getClient() {
182
101
  return c$1;
183
102
  }
184
103
 
104
+ async function waitForMergeSuccess(client, associationId, mergedApiIdentifier, maxAttemptsOpt, attemptOpt, delayMsOpt) {
105
+ let maxAttempts = maxAttemptsOpt !== undefined ? maxAttemptsOpt : 60;
106
+ let attempt = attemptOpt !== undefined ? attemptOpt : 0;
107
+ let delayMs = delayMsOpt !== undefined ? delayMsOpt : 2000;
108
+ let result = await client.send(new ClientAppsync.GetSourceApiAssociationCommand({
109
+ associationId: associationId,
110
+ mergedApiIdentifier: mergedApiIdentifier
111
+ }));
112
+ let status = Stdlib_Option.getOr(Stdlib_Option.flatMap(result.sourceApiAssociation, a => a.sourceApiAssociationStatus), "(no status)");
113
+ let detail = Stdlib_Option.getOr(Stdlib_Option.flatMap(result.sourceApiAssociation, a => a.sourceApiAssociationStatusDetail), "(no details)");
114
+ switch (status) {
115
+ case "AUTO_MERGE_SCHEDULE_FAILED" :
116
+ case "MERGE_FAILED" :
117
+ break;
118
+ case "MERGE_SUCCESS" :
119
+ return;
120
+ default:
121
+ if (attempt >= maxAttempts) {
122
+ return Stdlib_JsError.throwWithMessage(`Source API association ` + associationId + ` merge timed out after ` + maxAttempts.toString() + ` attempts (status: ` + status + `)`);
123
+ } else {
124
+ await new Promise((resolve, param) => {
125
+ setTimeout(resolve, delayMs);
126
+ });
127
+ return await waitForMergeSuccess(client, associationId, mergedApiIdentifier, maxAttempts, attempt + 1 | 0, delayMs);
128
+ }
129
+ }
130
+ return Stdlib_JsError.throwWithMessage(`Source API association ` + associationId + ` on ` + mergedApiIdentifier + ` failed to merge (` + status + `): ` + detail);
131
+ }
132
+
185
133
  function _permissionToCognitoGroups(permission) {
186
134
  if (typeof permission !== "object") {
187
135
  switch (permission) {
@@ -349,7 +297,12 @@ function stitchWithAwsDirectives(baseFragment, pluginFragments) {
349
297
  return AppSync_SdlDecorate$ReventlessAws.stampSharedIamTypes(AppSync_SdlDecorate$ReventlessAws.injectAwsSubscribe(GraphQL_Stitcher$ReventlessCore.stitch(baseFragment, pluginFragments), sources));
350
298
  }
351
299
 
352
- function makeApiResource(name, opts) {
300
+ function stitchStandaloneWithAwsDirectives(fragment) {
301
+ let sources = GraphQL_Stitcher$ReventlessCore.collectSubscriptionSources(fragment, []);
302
+ return AppSync_SdlDecorate$ReventlessAws.stampSharedIamTypes(AppSync_SdlDecorate$ReventlessAws.injectAwsSubscribe(GraphQL_Stitcher$ReventlessCore.stitchStandalone(fragment), sources));
303
+ }
304
+
305
+ function _makeApiResourceWith(name, schema, userPoolConfig, opts) {
353
306
  let customOpts_parent = opts.parent;
354
307
  let customOpts = {
355
308
  parent: customOpts_parent
@@ -357,18 +310,19 @@ function makeApiResource(name, opts) {
357
310
  let iamRole = new (Aws.iam.Role)(name + `-appsync-role`, {
358
311
  assumeRolePolicy: `{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"Service":"appsync.amazonaws.com"},"Action":"sts:AssumeRole"}]}`
359
312
  }, customOpts);
360
- let authConfigOut = Auth_Cognito$ReventlessAws.make(name + `-auth`, undefined);
361
- let userPoolConfigOut = authConfigOut.apply(c => ({
362
- userPoolId: c.userPoolId,
363
- defaultAction: "ALLOW",
364
- awsRegion: c.region
365
- }));
313
+ let userPoolConfigOut = userPoolConfig !== undefined ? userPoolConfig : Auth_Cognito$ReventlessAws.make(name + `-auth`, undefined).apply(c => ({
314
+ userPoolId: c.userPoolId,
315
+ defaultAction: "ALLOW",
316
+ awsRegion: c.region
317
+ }));
318
+ let apiArgs_schema = Stdlib_Option.map(schema, prim => prim);
366
319
  let apiArgs_userPoolConfig = userPoolConfigOut;
367
320
  let apiArgs_additionalAuthenticationProviders = [{
368
321
  authenticationType: "AWS_IAM"
369
322
  }];
370
323
  let apiArgs = {
371
324
  authenticationType: "AMAZON_COGNITO_USER_POOLS",
325
+ schema: apiArgs_schema,
372
326
  userPoolConfig: apiArgs_userPoolConfig,
373
327
  additionalAuthenticationProviders: apiArgs_additionalAuthenticationProviders
374
328
  };
@@ -379,6 +333,18 @@ function makeApiResource(name, opts) {
379
333
  ];
380
334
  }
381
335
 
336
+ function makeApiResource(name, opts) {
337
+ return _makeApiResourceWith(name, undefined, undefined, opts);
338
+ }
339
+
340
+ function makeSourceApiResource(name, schema, opts) {
341
+ return _makeApiResourceWith(name, schema, undefined, opts);
342
+ }
343
+
344
+ function makePluginSourceApiResource(name, userPoolConfig, opts) {
345
+ return _makeApiResourceWith(name, undefined, userPoolConfig, opts);
346
+ }
347
+
382
348
  function generateFragment(mutationEntries, queryEntries) {
383
349
  let fragment = GraphQL_FragmentGenerator$ReventlessCore.generate(mutationEntries, queryEntries);
384
350
  return injectAwsAuth(fragment, mutationEntries, queryEntries);
@@ -400,6 +366,8 @@ function updateSchema(api, baseFragment, pluginFragments) {
400
366
 
401
367
  let stampSharedIamTypes = AppSync_SdlDecorate$ReventlessAws.stampSharedIamTypes;
402
368
 
369
+ let primaryAuthenticationType = "AMAZON_COGNITO_USER_POOLS";
370
+
403
371
  export {
404
372
  log,
405
373
  sha256Hex,
@@ -408,11 +376,9 @@ export {
408
376
  waitForSchemaActive,
409
377
  getIntrospectionSdl,
410
378
  deploySchemaWithRetry,
411
- schemaLockSleep,
412
- _schemaLockCounter,
413
- withSchemaPushLock,
414
379
  _client,
415
380
  getClient,
381
+ waitForMergeSuccess,
416
382
  _permissionToCognitoGroups,
417
383
  _formatGroupsDirective,
418
384
  _formatDualAuthDirective,
@@ -422,7 +388,12 @@ export {
422
388
  injectAwsAuth,
423
389
  injectAwsAuthAll,
424
390
  stitchWithAwsDirectives,
391
+ stitchStandaloneWithAwsDirectives,
392
+ primaryAuthenticationType,
393
+ _makeApiResourceWith,
425
394
  makeApiResource,
395
+ makeSourceApiResource,
396
+ makePluginSourceApiResource,
426
397
  generateFragment,
427
398
  updateSchema,
428
399
  }