@deployfoundation/foundation-deploy 0.2.15 → 0.2.17
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.
- package/agent-image/Dockerfile +1 -0
- package/dist/bin/app.js +13 -3
- package/dist/bin/foundation-deploy.js +121 -7
- package/dist/bin/release-account.js +2 -2
- package/dist/{chunk-7qn00ny1.js → chunk-9rasrppa.js} +46 -4
- package/dist/{chunk-e9vs85ah.js → chunk-pygj3x43.js} +1 -1
- package/dist/{chunk-83781ggk.js → chunk-rq4dc5ns.js} +550 -12
- package/dist/src/index.js +4 -2
- package/package.json +1 -1
- package/src/artifacts.ts +2 -0
- package/src/deploy/cli.ts +3 -0
- package/src/deploy/deploy.ts +49 -0
- package/src/deploy/pages-domain.ts +106 -0
- package/src/deploy/runtime-secret.ts +8 -0
- package/src/deploy/setup.ts +13 -1
- package/src/deploy/slack-manifest.ts +44 -3
- package/src/index.ts +1 -0
- package/src/stacks/agent-stack.ts +78 -0
- package/src/stacks/pages-edge-function.ts +149 -0
- package/src/stacks/pages-stack.ts +504 -0
package/agent-image/Dockerfile
CHANGED
|
@@ -253,6 +253,7 @@ COPY packages/capability-email/ ./packages/capability-email/
|
|
|
253
253
|
COPY packages/capability-crm/ ./packages/capability-crm/
|
|
254
254
|
COPY packages/capability-upwork/ ./packages/capability-upwork/
|
|
255
255
|
COPY packages/capability-etrade/ ./packages/capability-etrade/
|
|
256
|
+
COPY packages/capability-pages/ ./packages/capability-pages/
|
|
256
257
|
COPY packages/agent/ ./packages/agent/
|
|
257
258
|
# Manifest only: the gateway and every proxy are Lambdas, the newsletter is a
|
|
258
259
|
# Lambda service, and the infra package is the CDK app a pipeline runs. None of
|
package/dist/bin/app.js
CHANGED
|
@@ -5,14 +5,16 @@ import {
|
|
|
5
5
|
FoundationCi,
|
|
6
6
|
FoundationData,
|
|
7
7
|
FoundationNetwork,
|
|
8
|
+
FoundationPages,
|
|
8
9
|
FoundationPipeline,
|
|
9
10
|
NewsletterStack
|
|
10
|
-
} from "../chunk-
|
|
11
|
+
} from "../chunk-rq4dc5ns.js";
|
|
11
12
|
import {
|
|
12
13
|
adminsFor,
|
|
13
14
|
instanceNames,
|
|
14
|
-
loadInstanceFile
|
|
15
|
-
|
|
15
|
+
loadInstanceFile,
|
|
16
|
+
provisionsIntegration
|
|
17
|
+
} from "../chunk-9rasrppa.js";
|
|
16
18
|
|
|
17
19
|
// bin/app.ts
|
|
18
20
|
import { execFileSync } from "node:child_process";
|
|
@@ -33,6 +35,14 @@ var alarmEmail = app.node.tryGetContext("alarmEmail");
|
|
|
33
35
|
var pipelineInstanceFile = app.node.tryGetContext("pipelineInstanceFile") ?? repoRelativePath(instanceFilePath);
|
|
34
36
|
var network = new FoundationNetwork(app, names.network, { env, instance, configPath });
|
|
35
37
|
var data = new FoundationData(app, names.data, { env, instance });
|
|
38
|
+
if (provisionsIntegration(instance, "pages"))
|
|
39
|
+
new FoundationPages(app, names.pages, {
|
|
40
|
+
env,
|
|
41
|
+
instance,
|
|
42
|
+
dataKey: data.dataKey,
|
|
43
|
+
secrets: { signing: data.secrets.signing, slackApp: data.secrets.slackApp },
|
|
44
|
+
domainDelegated: app.node.tryGetContext("pagesDomainDelegated") === "true"
|
|
45
|
+
});
|
|
36
46
|
var agent = new FoundationAgent(app, names.agent, {
|
|
37
47
|
env,
|
|
38
48
|
instance,
|
|
@@ -29,7 +29,7 @@ import {
|
|
|
29
29
|
stackExists,
|
|
30
30
|
stackOutput,
|
|
31
31
|
toolVersion
|
|
32
|
-
} from "../chunk-
|
|
32
|
+
} from "../chunk-pygj3x43.js";
|
|
33
33
|
import {
|
|
34
34
|
BASE_SLACK_EVENTS,
|
|
35
35
|
CAPABILITY_IDS,
|
|
@@ -45,7 +45,7 @@ import {
|
|
|
45
45
|
requiredSlackScopes,
|
|
46
46
|
skillsKey,
|
|
47
47
|
slackCommandPrefix
|
|
48
|
-
} from "../chunk-
|
|
48
|
+
} from "../chunk-9rasrppa.js";
|
|
49
49
|
|
|
50
50
|
// src/deploy/config-sync.ts
|
|
51
51
|
import { existsSync, mkdirSync, mkdtempSync, readdirSync } from "node:fs";
|
|
@@ -749,6 +749,63 @@ async function failureText(response) {
|
|
|
749
749
|
}
|
|
750
750
|
}
|
|
751
751
|
|
|
752
|
+
// src/deploy/pages-domain.ts
|
|
753
|
+
import { Resolver } from "node:dns/promises";
|
|
754
|
+
function pagesDomainMode(instance) {
|
|
755
|
+
if (!instance.integrations.pages || instance.pages.domain === undefined)
|
|
756
|
+
return "none";
|
|
757
|
+
return instance.pages.hostedZoneId === undefined ? "own-zone" : "parent-zone";
|
|
758
|
+
}
|
|
759
|
+
function normal(name) {
|
|
760
|
+
return name.trim().toLowerCase().replace(/\.$/, "");
|
|
761
|
+
}
|
|
762
|
+
async function pagesDomainState(instance, deps) {
|
|
763
|
+
const mode = pagesDomainMode(instance);
|
|
764
|
+
const domain = instance.pages.domain;
|
|
765
|
+
if (mode === "none" || domain === undefined)
|
|
766
|
+
return { mode, delegated: false, nameServers: [] };
|
|
767
|
+
if (mode === "parent-zone")
|
|
768
|
+
return { mode, domain, delegated: true, nameServers: [] };
|
|
769
|
+
const nameServers = (await deps.output("PagesNameServers") ?? "").split(",").map(normal).filter((server) => server !== "");
|
|
770
|
+
if (await deps.output("PagesCustomDomainAttached") === "true" && await deps.output("PagesCustomDomain") === domain)
|
|
771
|
+
return { mode, domain, delegated: true, nameServers };
|
|
772
|
+
if (nameServers.length === 0)
|
|
773
|
+
return { mode, domain, delegated: false, nameServers };
|
|
774
|
+
let answer;
|
|
775
|
+
try {
|
|
776
|
+
answer = (await deps.resolveNs(domain)).map(normal);
|
|
777
|
+
} catch {
|
|
778
|
+
answer = [];
|
|
779
|
+
}
|
|
780
|
+
const delegated = nameServers.every((server) => answer.includes(server));
|
|
781
|
+
return { mode, domain, delegated, nameServers };
|
|
782
|
+
}
|
|
783
|
+
async function publicNs(name) {
|
|
784
|
+
const resolver = new Resolver({ timeout: 5000, tries: 2 });
|
|
785
|
+
resolver.setServers(["1.1.1.1", "8.8.8.8"]);
|
|
786
|
+
try {
|
|
787
|
+
return await resolver.resolveNs(name);
|
|
788
|
+
} catch {
|
|
789
|
+
return [];
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
function pagesDomainReport(state, baseUrl) {
|
|
793
|
+
if (state.mode === "none" || state.domain === undefined)
|
|
794
|
+
return baseUrl === undefined ? [] : [` pages are served at ${baseUrl}`];
|
|
795
|
+
if (state.delegated)
|
|
796
|
+
return [` pages are served at https://${state.domain}`];
|
|
797
|
+
if (state.nameServers.length === 0)
|
|
798
|
+
return [
|
|
799
|
+
` ${state.domain}: the pages zone is created by this deploy; its NS records follow on the next run.`
|
|
800
|
+
];
|
|
801
|
+
return [
|
|
802
|
+
` ☐ add these NS records for ${state.domain} at your DNS provider:`,
|
|
803
|
+
...state.nameServers.map((server) => ` ${state.domain}. NS ${server}.`),
|
|
804
|
+
` until they resolve, pages are served at ${baseUrl ?? "the CloudFront default domain"}.`,
|
|
805
|
+
" Deploy again once they do: that deploy issues the certificate and moves pages to the domain."
|
|
806
|
+
];
|
|
807
|
+
}
|
|
808
|
+
|
|
752
809
|
// src/deploy/runtime-secret.ts
|
|
753
810
|
var LIVE_ENDPOINT = "live";
|
|
754
811
|
function composeRuntimeSecret(inputs) {
|
|
@@ -797,6 +854,7 @@ function composeRuntimeSecret(inputs) {
|
|
|
797
854
|
...inputs.browserProxyFunctionArn !== undefined && inputs.browserProxyFunctionArn !== "" ? { FOUNDATION_BROWSER_PROXY_FUNCTION_ARN: inputs.browserProxyFunctionArn } : {},
|
|
798
855
|
...inputs.crmProxyFunctionArn !== undefined && inputs.crmProxyFunctionArn !== "" ? { FOUNDATION_CRM_PROXY_FUNCTION_ARN: inputs.crmProxyFunctionArn } : {},
|
|
799
856
|
...inputs.crmPolicyFingerprint !== undefined && inputs.crmPolicyFingerprint !== "" ? { FOUNDATION_CRM_POLICY_FINGERPRINT: inputs.crmPolicyFingerprint } : {},
|
|
857
|
+
...inputs.pagesApiFunctionArn !== undefined && inputs.pagesApiFunctionArn !== "" ? { FOUNDATION_PAGES_API_FUNCTION_ARN: inputs.pagesApiFunctionArn } : {},
|
|
800
858
|
...inputs.otterProxyFunctionArn !== undefined && inputs.otterProxyFunctionArn !== "" ? { FOUNDATION_OTTER_PROXY_FUNCTION_ARN: inputs.otterProxyFunctionArn } : {},
|
|
801
859
|
...inputs.knockProxyFunctionArn !== undefined && inputs.knockProxyFunctionArn !== "" ? { FOUNDATION_KNOCK_PROXY_FUNCTION_ARN: inputs.knockProxyFunctionArn } : {},
|
|
802
860
|
...inputs.upworkProxyFunctionArn !== undefined && inputs.upworkProxyFunctionArn !== "" ? { FOUNDATION_UPWORK_PROXY_ARN: inputs.upworkProxyFunctionArn } : {},
|
|
@@ -1032,7 +1090,8 @@ async function cdkDeploy(ctx, opts) {
|
|
|
1032
1090
|
...opts.phase1 === true ? ["-c", "deployRuntime=false"] : [],
|
|
1033
1091
|
...opts.tag === undefined || opts.release !== undefined ? [] : ["-c", `agentImageTag=${opts.tag}`],
|
|
1034
1092
|
...opts.release === undefined ? [] : releaseContext(opts.release),
|
|
1035
|
-
...opts.runtimeSecretDigest === undefined ? [] : ["-c", `runtimeSecretDigest=${opts.runtimeSecretDigest}`]
|
|
1093
|
+
...opts.runtimeSecretDigest === undefined ? [] : ["-c", `runtimeSecretDigest=${opts.runtimeSecretDigest}`],
|
|
1094
|
+
...await pagesDomainContext(ctx)
|
|
1036
1095
|
];
|
|
1037
1096
|
await run([
|
|
1038
1097
|
...cdkCommand(),
|
|
@@ -1049,6 +1108,30 @@ async function cdkDeploy(ctx, opts) {
|
|
|
1049
1108
|
dryRun: ctx.dryRun
|
|
1050
1109
|
});
|
|
1051
1110
|
}
|
|
1111
|
+
async function pagesDomain(ctx) {
|
|
1112
|
+
return pagesDomainState(ctx.instance, {
|
|
1113
|
+
output: (key) => optionalOutput(ctx, ctx.names.pages, key),
|
|
1114
|
+
resolveNs: publicNs
|
|
1115
|
+
});
|
|
1116
|
+
}
|
|
1117
|
+
async function pagesDomainContext(ctx) {
|
|
1118
|
+
if (pagesDomainMode(ctx.instance) !== "own-zone" || ctx.dryRun === true)
|
|
1119
|
+
return [];
|
|
1120
|
+
return (await pagesDomain(ctx)).delegated ? ["-c", "pagesDomainDelegated=true"] : [];
|
|
1121
|
+
}
|
|
1122
|
+
async function reportPagesDomain(ctx) {
|
|
1123
|
+
if (!ctx.instance.integrations.pages)
|
|
1124
|
+
return;
|
|
1125
|
+
console.log("▶ hosted pages");
|
|
1126
|
+
if (ctx.dryRun === true) {
|
|
1127
|
+
console.log(` <${ctx.names.pages}.PagesBaseUrl>; NS records from <${ctx.names.pages}.PagesNameServers>`);
|
|
1128
|
+
return;
|
|
1129
|
+
}
|
|
1130
|
+
const state = await pagesDomain(ctx);
|
|
1131
|
+
const baseUrl = await optionalOutput(ctx, ctx.names.pages, "PagesBaseUrl");
|
|
1132
|
+
for (const line of pagesDomainReport(state, baseUrl))
|
|
1133
|
+
console.log(line);
|
|
1134
|
+
}
|
|
1052
1135
|
async function optionalOutput(ctx, stack, key) {
|
|
1053
1136
|
try {
|
|
1054
1137
|
return await stackOutput(ctx, stack, key);
|
|
@@ -1098,6 +1181,7 @@ async function syncRuntimeSecret(ctx) {
|
|
|
1098
1181
|
const browserProxyFunctionArn = dry ? `<${api}.BrowserProxyFunctionArn>` : await optionalOutput(ctx, api, "BrowserProxyFunctionArn");
|
|
1099
1182
|
const crmProxyFunctionArn = ctx.instance.integrations.crm ? dry ? `<${api}.CrmProxyFunctionArn>` : await optionalOutput(ctx, api, "CrmProxyFunctionArn") : undefined;
|
|
1100
1183
|
const crmPolicyFingerprint = ctx.instance.integrations.crm ? dry ? `<${api}.CrmPolicyFingerprint>` : await optionalOutput(ctx, api, "CrmPolicyFingerprint") : undefined;
|
|
1184
|
+
const pagesApiFunctionArn = ctx.instance.integrations.pages ? dry ? `<${ctx.names.pages}.PagesApiFunctionArn>` : await optionalOutput(ctx, ctx.names.pages, "PagesApiFunctionArn") : undefined;
|
|
1101
1185
|
const otterProxyFunctionArn = dry ? `<${api}.OtterProxyFunctionArn>` : await optionalOutput(ctx, api, "OtterProxyFunctionArn");
|
|
1102
1186
|
const knockProxyFunctionArn = ctx.instance.integrations.knock ? dry ? `<${api}.KnockProxyFunctionArn>` : await optionalOutput(ctx, api, "KnockProxyFunctionArn") : undefined;
|
|
1103
1187
|
const upworkProxyFunctionArn = ctx.instance.integrations.upwork ? dry ? `<${api}.UpworkProxyFunctionArn>` : await optionalOutput(ctx, api, "UpworkProxyFunctionArn") : undefined;
|
|
@@ -1123,6 +1207,7 @@ async function syncRuntimeSecret(ctx) {
|
|
|
1123
1207
|
...browserProxyFunctionArn === undefined ? {} : { browserProxyFunctionArn },
|
|
1124
1208
|
...crmProxyFunctionArn === undefined ? {} : { crmProxyFunctionArn },
|
|
1125
1209
|
...crmPolicyFingerprint === undefined ? {} : { crmPolicyFingerprint },
|
|
1210
|
+
...pagesApiFunctionArn === undefined ? {} : { pagesApiFunctionArn },
|
|
1126
1211
|
...otterProxyFunctionArn === undefined ? {} : { otterProxyFunctionArn },
|
|
1127
1212
|
...knockProxyFunctionArn === undefined ? {} : { knockProxyFunctionArn },
|
|
1128
1213
|
...upworkProxyFunctionArn === undefined ? {} : { upworkProxyFunctionArn },
|
|
@@ -1218,6 +1303,7 @@ async function deploy(ctx, opts) {
|
|
|
1218
1303
|
...runtimeSecretDigest2 === undefined ? {} : { runtimeSecretDigest: runtimeSecretDigest2 }
|
|
1219
1304
|
});
|
|
1220
1305
|
await deployStacks(deployed);
|
|
1306
|
+
await reportPagesDomain(ctx);
|
|
1221
1307
|
if (ctx.instance.integrations.knock) {
|
|
1222
1308
|
console.log(`▶ Knock OAuth public-client registration (${ctx.names.secretKnockOauthClient})`);
|
|
1223
1309
|
console.log(` ${await syncKnockOAuthClient(ctx)}`);
|
|
@@ -1473,6 +1559,14 @@ function buildSlackManifest(template, instance, env) {
|
|
|
1473
1559
|
if (manifest.oauth_config?.scopes?.bot !== undefined)
|
|
1474
1560
|
throw new Error("app-manifest.yml: bot scopes are generated from the Foundation capability registry; remove them from the template");
|
|
1475
1561
|
manifest.oauth_config = { scopes: { bot: requiredSlackScopes(CAPABILITY_IDS) } };
|
|
1562
|
+
if (instance.pages === true) {
|
|
1563
|
+
manifest.oauth_config.scopes.user = ["openid"];
|
|
1564
|
+
const redirects = [
|
|
1565
|
+
...new Set((env.PAGES_AUTH_REDIRECT_URL ?? "").split(",").map((url) => url.trim()).filter((url) => url !== ""))
|
|
1566
|
+
];
|
|
1567
|
+
if (redirects.length > 0)
|
|
1568
|
+
manifest.oauth_config.redirect_urls = redirects;
|
|
1569
|
+
}
|
|
1476
1570
|
const declared = new Set((manifest.features.slash_commands ?? []).map((c) => c.command));
|
|
1477
1571
|
for (const command of requiredSlackCommands(CAPABILITY_IDS, instance.commandPrefix))
|
|
1478
1572
|
if (!declared.has(command))
|
|
@@ -1492,7 +1586,19 @@ function buildSlackManifest(template, instance, env) {
|
|
|
1492
1586
|
return manifest;
|
|
1493
1587
|
}
|
|
1494
1588
|
function slackManifestFor(instance, env) {
|
|
1495
|
-
return buildSlackManifest(readFileSync5(SLACK_APP_MANIFEST_PATH, "utf8"), {
|
|
1589
|
+
return buildSlackManifest(readFileSync5(SLACK_APP_MANIFEST_PATH, "utf8"), {
|
|
1590
|
+
displayName: instance.displayName,
|
|
1591
|
+
commandPrefix: slackCommandPrefix(instance),
|
|
1592
|
+
pages: instance.integrations.pages
|
|
1593
|
+
}, {
|
|
1594
|
+
...env,
|
|
1595
|
+
...instance.integrations.pages && instance.pages.domain !== undefined ? {
|
|
1596
|
+
PAGES_AUTH_REDIRECT_URL: [
|
|
1597
|
+
`https://${instance.pages.domain}/_auth/callback`,
|
|
1598
|
+
...env.PAGES_AUTH_REDIRECT_URL === undefined ? [] : [env.PAGES_AUTH_REDIRECT_URL]
|
|
1599
|
+
].join(",")
|
|
1600
|
+
} : {}
|
|
1601
|
+
});
|
|
1496
1602
|
}
|
|
1497
1603
|
|
|
1498
1604
|
// src/deploy/tracing.ts
|
|
@@ -1721,7 +1827,13 @@ async function reportSlackManifest(ctx) {
|
|
|
1721
1827
|
const manifest = slackManifestFor(ctx.instance, {
|
|
1722
1828
|
EVENTS_REQUEST_URL: await output(ctx, ctx.names.api, "EventsUrl"),
|
|
1723
1829
|
COMMANDS_REQUEST_URL: await output(ctx, ctx.names.api, "CommandsUrl"),
|
|
1724
|
-
INTERACTIVE_REQUEST_URL: await output(ctx, ctx.names.api, "InteractiveUrl")
|
|
1830
|
+
INTERACTIVE_REQUEST_URL: await output(ctx, ctx.names.api, "InteractiveUrl"),
|
|
1831
|
+
...ctx.instance.integrations.pages ? {
|
|
1832
|
+
PAGES_AUTH_REDIRECT_URL: [
|
|
1833
|
+
await output(ctx, ctx.names.pages, "PagesAuthRedirectUrl"),
|
|
1834
|
+
await output(ctx, ctx.names.pages, "PagesDefaultAuthRedirectUrl")
|
|
1835
|
+
].join(",")
|
|
1836
|
+
} : {}
|
|
1725
1837
|
});
|
|
1726
1838
|
console.log(` manifest: ${JSON.stringify(manifest)}`);
|
|
1727
1839
|
console.log([
|
|
@@ -1874,8 +1986,9 @@ async function setup(ctx, opts = {}) {
|
|
|
1874
1986
|
await setDeployRoleVariable(ctx);
|
|
1875
1987
|
step(13, "deploy the instance's own pipeline, if it has one");
|
|
1876
1988
|
await deployPipelineStack(ctx);
|
|
1877
|
-
step(14, "the Slack app manifest for the deployed API");
|
|
1989
|
+
step(14, "the Slack app manifest for the deployed API, and the pages domain");
|
|
1878
1990
|
await reportSlackManifest(ctx);
|
|
1991
|
+
await reportPagesDomain(ctx);
|
|
1879
1992
|
step(15, "smoke test the runtime");
|
|
1880
1993
|
await smokeTest(ctx);
|
|
1881
1994
|
console.log(`
|
|
@@ -1987,7 +2100,8 @@ ${USAGE}`);
|
|
|
1987
2100
|
console.log(JSON.stringify(slackManifestFor(paths.instance, {
|
|
1988
2101
|
...process.env.EVENTS_REQUEST_URL === undefined ? {} : { EVENTS_REQUEST_URL: process.env.EVENTS_REQUEST_URL },
|
|
1989
2102
|
...process.env.COMMANDS_REQUEST_URL === undefined ? {} : { COMMANDS_REQUEST_URL: process.env.COMMANDS_REQUEST_URL },
|
|
1990
|
-
...process.env.INTERACTIVE_REQUEST_URL === undefined ? {} : { INTERACTIVE_REQUEST_URL: process.env.INTERACTIVE_REQUEST_URL }
|
|
2103
|
+
...process.env.INTERACTIVE_REQUEST_URL === undefined ? {} : { INTERACTIVE_REQUEST_URL: process.env.INTERACTIVE_REQUEST_URL },
|
|
2104
|
+
...process.env.PAGES_AUTH_REDIRECT_URL === undefined ? {} : { PAGES_AUTH_REDIRECT_URL: process.env.PAGES_AUTH_REDIRECT_URL }
|
|
1991
2105
|
})));
|
|
1992
2106
|
return 0;
|
|
1993
2107
|
}
|
|
@@ -266,6 +266,7 @@ var RawTodosCapability = z.object({
|
|
|
266
266
|
digestHour: z.union([z.number().int().min(0).max(23), z.literal("off")]).default(8)
|
|
267
267
|
}).strict().default({});
|
|
268
268
|
var RawRoutinesCapability = z.object({ enabled: z.boolean().default(true) }).strict().default({});
|
|
269
|
+
var RawPagesCapability = z.object({ enabled: z.boolean().default(false) }).strict().default({});
|
|
269
270
|
var NONE = {
|
|
270
271
|
secrets: [],
|
|
271
272
|
resources: [],
|
|
@@ -461,6 +462,14 @@ var CAPABILITIES = [
|
|
|
461
462
|
resources: ["upworkProxyFunctionName"],
|
|
462
463
|
slackCommands: ["upwork-connect"]
|
|
463
464
|
},
|
|
465
|
+
{
|
|
466
|
+
id: "pages",
|
|
467
|
+
summary: "Private, versioned web pages (decks, reports, dashboards) the agent publishes; members of the channel they were made in open them with a Slack sign-in.",
|
|
468
|
+
config: RawPagesCapability,
|
|
469
|
+
integration: true,
|
|
470
|
+
...NONE,
|
|
471
|
+
resources: ["pagesApiFunctionName"]
|
|
472
|
+
},
|
|
464
473
|
{
|
|
465
474
|
id: "etrade",
|
|
466
475
|
summary: "E*TRADE account data through six fixed reads for named admins and deployment jobs in configured private channels.",
|
|
@@ -699,6 +708,7 @@ var RawIntegrations = z2.object({
|
|
|
699
708
|
knock: z2.boolean().default(false),
|
|
700
709
|
upwork: z2.boolean().default(false),
|
|
701
710
|
etrade: z2.boolean().default(false),
|
|
711
|
+
pages: z2.boolean().default(false),
|
|
702
712
|
crm: z2.boolean().default(false),
|
|
703
713
|
crmStorage: z2.boolean().optional()
|
|
704
714
|
}).strict().default({}).transform((integrations) => ({
|
|
@@ -706,6 +716,18 @@ var RawIntegrations = z2.object({
|
|
|
706
716
|
crmStorage: integrations.crmStorage ?? integrations.crm
|
|
707
717
|
}));
|
|
708
718
|
var RawLicense = z2.object({ key: z2.string().min(1) }).strict();
|
|
719
|
+
var PAGES_DOMAIN_RE = /^(?=.{1,253}$)(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z]{2,63}$/;
|
|
720
|
+
var RawPages = z2.object({
|
|
721
|
+
domain: z2.string().regex(PAGES_DOMAIN_RE, "pages.domain must be a lowercase host name without a scheme or path").optional(),
|
|
722
|
+
hostedZoneId: z2.string().regex(HOSTED_ZONE_ID_RE, "pages.hostedZoneId must be a Route 53 hosted zone id (Z…)").optional()
|
|
723
|
+
}).strict().superRefine((pages, ctx) => {
|
|
724
|
+
if (pages.hostedZoneId !== undefined && pages.domain === undefined)
|
|
725
|
+
ctx.addIssue({
|
|
726
|
+
code: z2.ZodIssueCode.custom,
|
|
727
|
+
path: ["hostedZoneId"],
|
|
728
|
+
message: "pages.hostedZoneId needs pages.domain"
|
|
729
|
+
});
|
|
730
|
+
}).default({});
|
|
709
731
|
var RawInstance = z2.object({
|
|
710
732
|
name: z2.string().min(1).max(63).regex(/^[a-z][a-z0-9-]*$/),
|
|
711
733
|
displayName: z2.string().min(1).max(120),
|
|
@@ -722,8 +744,15 @@ var RawInstance = z2.object({
|
|
|
722
744
|
runtime: RawRuntime,
|
|
723
745
|
network: RawNetwork,
|
|
724
746
|
integrations: RawIntegrations,
|
|
725
|
-
newsletter: RawNewsletter
|
|
747
|
+
newsletter: RawNewsletter,
|
|
748
|
+
pages: RawPages
|
|
726
749
|
}).strict().superRefine((doc, ctx) => {
|
|
750
|
+
if (doc.pages.domain !== undefined && !doc.integrations.pages)
|
|
751
|
+
ctx.addIssue({
|
|
752
|
+
code: z2.ZodIssueCode.custom,
|
|
753
|
+
path: ["pages", "domain"],
|
|
754
|
+
message: "pages.domain needs integrations.pages: true"
|
|
755
|
+
});
|
|
727
756
|
if (doc.customization !== undefined && doc.deploy.via !== "codepipeline")
|
|
728
757
|
ctx.addIssue({
|
|
729
758
|
code: z2.ZodIssueCode.custom,
|
|
@@ -772,12 +801,13 @@ function instanceNames(instance) {
|
|
|
772
801
|
const { prefix, secretPrefix, runtimeName } = instance.naming;
|
|
773
802
|
const stack = (suffix) => `${prefix}${suffix}`;
|
|
774
803
|
const secret = (suffix) => `${secretPrefix}/${suffix}`;
|
|
775
|
-
const [network, data, api, agent, newsletter] = [
|
|
804
|
+
const [network, data, api, agent, newsletter, pages] = [
|
|
776
805
|
stack("Network"),
|
|
777
806
|
stack("Data"),
|
|
778
807
|
stack("Api"),
|
|
779
808
|
stack("Agent"),
|
|
780
|
-
stack("Newsletter")
|
|
809
|
+
stack("Newsletter"),
|
|
810
|
+
stack("Pages")
|
|
781
811
|
];
|
|
782
812
|
return {
|
|
783
813
|
network,
|
|
@@ -786,8 +816,16 @@ function instanceNames(instance) {
|
|
|
786
816
|
api,
|
|
787
817
|
ci: stack("Ci"),
|
|
788
818
|
newsletter,
|
|
819
|
+
pages,
|
|
789
820
|
pipeline: stack("Pipeline"),
|
|
790
|
-
allStacks: [
|
|
821
|
+
allStacks: [
|
|
822
|
+
network,
|
|
823
|
+
data,
|
|
824
|
+
...instance.integrations.pages ? [pages] : [],
|
|
825
|
+
api,
|
|
826
|
+
agent,
|
|
827
|
+
...instance.newsletter.enabled ? [newsletter] : []
|
|
828
|
+
],
|
|
791
829
|
secretSlackSigning: secret("slack/signing"),
|
|
792
830
|
secretSlackApp: secret("slack/app"),
|
|
793
831
|
secretGithubApp: secret("github/app"),
|
|
@@ -822,6 +860,8 @@ function instanceNames(instance) {
|
|
|
822
860
|
emailProxyFunctionName: stack("EmailProxy"),
|
|
823
861
|
otterProxyFunctionName: stack("OtterProxy"),
|
|
824
862
|
crmProxyFunctionName: stack("CrmProxy"),
|
|
863
|
+
pagesApiFunctionName: stack("PagesApi"),
|
|
864
|
+
secretPagesCookieKey: secret("pages/cookie-key"),
|
|
825
865
|
browserProxyFunctionName: stack("BrowserProxy"),
|
|
826
866
|
knockProxyFunctionName: stack("KnockProxy"),
|
|
827
867
|
upworkProxyFunctionName: stack("UpworkProxy"),
|
|
@@ -1493,6 +1533,8 @@ var LAMBDA_ENTRY_POINTS = {
|
|
|
1493
1533
|
"crm-proxy": { entry: "packages/capability-crm/src/proxy/handler.ts" },
|
|
1494
1534
|
"upwork-proxy": { entry: "packages/capability-upwork/src/proxy/handler.ts" },
|
|
1495
1535
|
"etrade-proxy": { entry: "packages/capability-etrade/src/proxy/handler.ts" },
|
|
1536
|
+
"pages-api": { entry: "packages/capability-pages/src/proxy/handler.ts" },
|
|
1537
|
+
"pages-auth": { entry: "packages/capability-pages/src/auth/lambda.ts" },
|
|
1496
1538
|
"browser-proxy": { entry: "packages/gateway/src/browser-proxy.ts", playwright: true },
|
|
1497
1539
|
"newsletter-public": { entry: "packages/newsletter/src/lambda-public.ts" },
|
|
1498
1540
|
"newsletter-campaign": { entry: "packages/newsletter/src/lambda-campaign.ts" },
|