@awsless/awsless 0.0.627 → 0.0.628

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/dist/bin.js CHANGED
@@ -2525,6 +2525,78 @@ var StackSchema = z44.object({
2525
2525
  // src/config/load/read.ts
2526
2526
  import { readFile as readFile2 } from "fs/promises";
2527
2527
  import { basename, dirname as dirname2, extname, join as join4 } from "path";
2528
+
2529
+ // src/config/stage-patch.ts
2530
+ import jsonPatch from "fast-json-patch";
2531
+ import { z as z45 } from "zod";
2532
+ var AddOperationSchema = z45.object({
2533
+ op: z45.literal("add"),
2534
+ path: z45.string(),
2535
+ value: z45.unknown()
2536
+ }).strict();
2537
+ var RemoveOperationSchema = z45.object({
2538
+ op: z45.literal("remove"),
2539
+ path: z45.string()
2540
+ }).strict();
2541
+ var ReplaceOperationSchema = z45.object({
2542
+ op: z45.literal("replace"),
2543
+ path: z45.string(),
2544
+ value: z45.unknown()
2545
+ }).strict();
2546
+ var MoveOperationSchema = z45.object({
2547
+ op: z45.literal("move"),
2548
+ from: z45.string(),
2549
+ path: z45.string()
2550
+ }).strict();
2551
+ var CopyOperationSchema = z45.object({
2552
+ op: z45.literal("copy"),
2553
+ from: z45.string(),
2554
+ path: z45.string()
2555
+ }).strict();
2556
+ var TestOperationSchema = z45.object({
2557
+ op: z45.literal("test"),
2558
+ path: z45.string(),
2559
+ value: z45.unknown()
2560
+ }).strict();
2561
+ var JsonPatchOperationSchema = z45.discriminatedUnion("op", [
2562
+ AddOperationSchema,
2563
+ RemoveOperationSchema,
2564
+ ReplaceOperationSchema,
2565
+ MoveOperationSchema,
2566
+ CopyOperationSchema,
2567
+ TestOperationSchema
2568
+ ]);
2569
+ var StagePatchSchema = z45.object({
2570
+ $schema: z45.string().optional(),
2571
+ operations: JsonPatchOperationSchema.array()
2572
+ }).strict();
2573
+ var applyStagePatch = (source, patch, file) => {
2574
+ try {
2575
+ const result = jsonPatch.applyPatch(structuredClone(source), patch.operations, true, false);
2576
+ return result.newDocument;
2577
+ } catch (error) {
2578
+ if (error instanceof Error) {
2579
+ throw new FileError(file, error.message);
2580
+ }
2581
+ throw error;
2582
+ }
2583
+ };
2584
+
2585
+ // src/config/load/validate.ts
2586
+ import { z as z46 } from "zod";
2587
+ var validateConfig = async (schema, file, data) => {
2588
+ try {
2589
+ const result = await schema.parseAsync(data);
2590
+ return result;
2591
+ } catch (error) {
2592
+ if (error instanceof z46.ZodError) {
2593
+ throw new ConfigError(file, error, data);
2594
+ }
2595
+ throw error;
2596
+ }
2597
+ };
2598
+
2599
+ // src/config/load/read.ts
2528
2600
  var readConfig = async (file) => {
2529
2601
  try {
2530
2602
  const json2 = await readFile2(file, "utf8");
@@ -2540,32 +2612,28 @@ var readConfig = async (file) => {
2540
2612
  var readConfigWithStage = async (file, stage) => {
2541
2613
  const config2 = await readConfig(file);
2542
2614
  if (!stage) {
2543
- return config2;
2615
+ return {
2616
+ file,
2617
+ data: config2
2618
+ };
2544
2619
  }
2545
2620
  const ext = extname(file);
2546
2621
  const stageFileName = basename(file, ext) + "." + stage + ext;
2547
2622
  const stageFile = join4(dirname2(file), stageFileName);
2548
2623
  const stageFileExists = await fileExist(stageFile);
2549
2624
  if (!stageFileExists) {
2550
- return config2;
2625
+ return {
2626
+ file,
2627
+ data: config2
2628
+ };
2551
2629
  }
2552
2630
  debug("Load env file:", color.info(stageFile));
2553
2631
  const stageConfig = await readConfig(stageFile);
2554
- return stageConfig;
2555
- };
2556
-
2557
- // src/config/load/validate.ts
2558
- import { z as z45 } from "zod";
2559
- var validateConfig = async (schema, file, data) => {
2560
- try {
2561
- const result = await schema.parseAsync(data);
2562
- return result;
2563
- } catch (error) {
2564
- if (error instanceof z45.ZodError) {
2565
- throw new ConfigError(file, error, data);
2566
- }
2567
- throw error;
2568
- }
2632
+ const patch = await validateConfig(StagePatchSchema, stageFile, stageConfig);
2633
+ return {
2634
+ file: stageFile,
2635
+ data: applyStagePatch(config2, patch, stageFile)
2636
+ };
2569
2637
  };
2570
2638
 
2571
2639
  // src/config/load/load.ts
@@ -2580,7 +2648,7 @@ var loadAppConfig = async (options) => {
2580
2648
  debug("Load app config file");
2581
2649
  const appConfig = await readConfigWithStage(appFileName, options.stage);
2582
2650
  debug("Validate app config file");
2583
- const app = await validateConfig(AppSchema, appFileName, appConfig);
2651
+ const app = await validateConfig(AppSchema, appConfig.file, appConfig.data);
2584
2652
  return app;
2585
2653
  };
2586
2654
  var loadStackConfigs = async (options) => {
@@ -2600,7 +2668,7 @@ var loadStackConfigs = async (options) => {
2600
2668
  debug("Load stack file:", color.info(file));
2601
2669
  const stackConfig = await readConfigWithStage(join5(directories.root, file), options.stage);
2602
2670
  setLocalBasePath(join5(directories.root, dirname3(file)));
2603
- const stack = await validateConfig(StackSchema, file, stackConfig);
2671
+ const stack = await validateConfig(StackSchema, stackConfig.file, stackConfig.data);
2604
2672
  stacks.push({
2605
2673
  ...stack,
2606
2674
  file
@@ -5312,14 +5380,15 @@ var siteFeature = defineFeature({
5312
5380
  const instance = Bun.spawn(buildProps.command.split(" "), {
5313
5381
  cwd,
5314
5382
  env,
5315
- stdout: "ignore",
5316
- stderr: "ignore"
5383
+ stdout: "pipe",
5384
+ stderr: "pipe"
5385
+ // stdout: 'ignore',
5386
+ // stderr: ''
5317
5387
  // stdout: 'inherit',
5318
5388
  // stderr: 'inherit',
5319
5389
  });
5320
5390
  await instance.exited;
5321
5391
  if (instance.exitCode !== null && instance.exitCode > 0) {
5322
- console.log(instance.stderr);
5323
5392
  throw new Error("Site build failed");
5324
5393
  }
5325
5394
  await write("HASH", fingerprint);
@@ -8863,6 +8932,14 @@ var startTest = async (props) => {
8863
8932
  exclude: ["**/_*", "**/_*/**", ...configDefaults.exclude],
8864
8933
  globals: true,
8865
8934
  reporters: [new NullReporter()],
8935
+ // isolate: false,
8936
+ // typecheck: {
8937
+ // enabled: true,
8938
+ // only: false,
8939
+ // exclude: ['**/_*', '**/_*/**', ...configDefaults.exclude],
8940
+ // include: ['**/*.{js,jsx,ts,tsx}'],
8941
+ // checker: 'tsc',
8942
+ // },
8866
8943
  // reporters: 'json',
8867
8944
  // typecheck: {
8868
8945
  // checker: 'tsc',
@@ -10261,6 +10338,7 @@ var parseJsonLog = (message) => {
10261
10338
  // src/cli/command/image/clear-cache.ts
10262
10339
  import { DeleteObjectsCommand, ListObjectsV2Command, S3Client as S3Client3 } from "@aws-sdk/client-s3";
10263
10340
  import { Cancelled as Cancelled3, log as log28, prompt as prompt14 } from "@awsless/clui";
10341
+ import { CloudFrontClient as CloudFrontClient2 } from "@aws-sdk/client-cloudfront";
10264
10342
  var clearCache = (program2) => {
10265
10343
  program2.command("clear-cache").argument("[stack]", "The stack name of the image proxy").argument("[name]", "The name of the image proxy").description("Clears the cache of the image proxy").action(async (stack, name) => {
10266
10344
  await layout("image clear-cache", async ({ appConfig, stackConfigs }) => {
@@ -10325,6 +10403,10 @@ var clearCache = (program2) => {
10325
10403
  credentials,
10326
10404
  region
10327
10405
  });
10406
+ const cloudFrontClient = new CloudFrontClient2({
10407
+ credentials,
10408
+ region
10409
+ });
10328
10410
  let totalDeleted = 0;
10329
10411
  await log28.task({
10330
10412
  initialMessage: "Clearing cache...",
@@ -10359,9 +10441,7 @@ var clearCache = (program2) => {
10359
10441
  break;
10360
10442
  }
10361
10443
  }
10362
- await createInvalidationForDistributionTenants({
10363
- credentials,
10364
- region,
10444
+ await createInvalidationForDistributionTenants(cloudFrontClient, {
10365
10445
  distributionId,
10366
10446
  paths: [shared.entry("image", "path", name)]
10367
10447
  });
@@ -10382,6 +10462,7 @@ var image = (program2) => {
10382
10462
  // src/cli/command/icon/clear-cache.ts
10383
10463
  import { DeleteObjectsCommand as DeleteObjectsCommand2, ListObjectsV2Command as ListObjectsV2Command2, S3Client as S3Client4 } from "@aws-sdk/client-s3";
10384
10464
  import { Cancelled as Cancelled4, log as log29, prompt as prompt15 } from "@awsless/clui";
10465
+ import { CloudFrontClient as CloudFrontClient3 } from "@aws-sdk/client-cloudfront";
10385
10466
  var clearCache2 = (program2) => {
10386
10467
  program2.command("clear-cache").argument("[stack]", "The stack name of the icon proxy").argument("[name]", "The name of the icon proxy").description("Clears the cache of the icon proxy").action(async (stack, name) => {
10387
10468
  await layout("icon clear-cache", async ({ appConfig, stackConfigs }) => {
@@ -10446,6 +10527,10 @@ var clearCache2 = (program2) => {
10446
10527
  credentials,
10447
10528
  region
10448
10529
  });
10530
+ const cloudFrontClient = new CloudFrontClient3({
10531
+ credentials,
10532
+ region
10533
+ });
10449
10534
  let totalDeleted = 0;
10450
10535
  await log29.task({
10451
10536
  initialMessage: "Clearing cache...",
@@ -10480,9 +10565,7 @@ var clearCache2 = (program2) => {
10480
10565
  break;
10481
10566
  }
10482
10567
  }
10483
- await createInvalidationForDistributionTenants({
10484
- credentials,
10485
- region,
10568
+ await createInvalidationForDistributionTenants(cloudFrontClient, {
10486
10569
  distributionId,
10487
10570
  paths: [shared.entry("icon", "path", name)]
10488
10571
  });
@@ -942,6 +942,259 @@ var AppSchema = z24.object({
942
942
  }).default({}).describe("Default properties")
943
943
  });
944
944
 
945
+ // src/config/stage-patch-json-schema.ts
946
+ var clone = (value) => {
947
+ return JSON.parse(JSON.stringify(value));
948
+ };
949
+ var escapePointerSegment = (value) => {
950
+ return value.replaceAll("~", "~0").replaceAll("/", "~1");
951
+ };
952
+ var escapeRegexSegment = (value) => {
953
+ return value.replace(/[|\\{}()[\]^$+*?.-]/g, "\\$&");
954
+ };
955
+ var makeExactPath = (prefix, segment) => {
956
+ return `${prefix}/${escapePointerSegment(segment)}`;
957
+ };
958
+ var makeExactPattern = (path) => {
959
+ return `^${path.split("/").map(escapeRegexSegment).join("/")}$`;
960
+ };
961
+ var makePatternPath = (prefix, segmentPattern) => {
962
+ return prefix ? `${prefix}/${segmentPattern}` : `/${segmentPattern}`;
963
+ };
964
+ var appendExactPattern = (pattern, segment) => {
965
+ const base = pattern.slice(1, -1);
966
+ return `^${base}/${escapeRegexSegment(segment)}$`;
967
+ };
968
+ var appendRegexPattern = (pattern, segmentPattern) => {
969
+ const base = pattern.slice(1, -1);
970
+ return `^${base}/${segmentPattern}$`;
971
+ };
972
+ var mergeSchemas = (schemas) => {
973
+ const list = schemas.map((schema) => clone(schema));
974
+ if (list.length === 1) {
975
+ return list[0];
976
+ }
977
+ return {
978
+ anyOf: list
979
+ };
980
+ };
981
+ var dereference = (schema, root) => {
982
+ if (typeof schema.$ref !== "string" || !schema.$ref.startsWith("#/")) {
983
+ return schema;
984
+ }
985
+ const target = schema.$ref.slice(2).split("/").map((segment) => segment.replaceAll("~1", "/").replaceAll("~0", "~")).reduce((value, segment) => {
986
+ if (typeof value === "object" && value !== null) {
987
+ return value[segment];
988
+ }
989
+ return void 0;
990
+ }, root);
991
+ if (!target || typeof target !== "object") {
992
+ return schema;
993
+ }
994
+ const { $ref: _, ...rest } = schema;
995
+ return {
996
+ ...clone(target),
997
+ ...rest
998
+ };
999
+ };
1000
+ var listBranches = (schema) => {
1001
+ const groups = [schema.anyOf, schema.oneOf, schema.allOf].filter(Boolean);
1002
+ if (groups.length === 0) {
1003
+ return [schema];
1004
+ }
1005
+ return groups.flatMap((group) => group);
1006
+ };
1007
+ var childSegmentPattern = (schema) => {
1008
+ const propertyNameSchema = schema.propertyNames;
1009
+ if (propertyNameSchema && typeof propertyNameSchema.pattern === "string") {
1010
+ return propertyNameSchema.pattern;
1011
+ }
1012
+ const firstPattern = Object.keys(schema.patternProperties ?? {})[0];
1013
+ if (firstPattern) {
1014
+ return firstPattern;
1015
+ }
1016
+ return "[^/]+";
1017
+ };
1018
+ var joinEntries = (entries) => {
1019
+ const map = /* @__PURE__ */ new Map();
1020
+ for (const entry of entries) {
1021
+ const key = [entry.path, entry.pattern ?? "", entry.addOnly ? "1" : "0"].join("|");
1022
+ const previous = map.get(key);
1023
+ if (!previous) {
1024
+ map.set(key, {
1025
+ ...entry,
1026
+ schema: clone(entry.schema)
1027
+ });
1028
+ continue;
1029
+ }
1030
+ previous.schema = mergeSchemas([previous.schema, entry.schema]);
1031
+ }
1032
+ return [...map.values()];
1033
+ };
1034
+ var collectEntries = (schema, pointer = "", pattern = makeExactPattern(pointer), root = schema) => {
1035
+ const resolved = dereference(schema, root);
1036
+ const entries = [
1037
+ {
1038
+ path: pointer,
1039
+ pattern,
1040
+ schema: clone(resolved)
1041
+ }
1042
+ ];
1043
+ for (const branch of listBranches(resolved)) {
1044
+ const branchType = Array.isArray(branch.type) ? branch.type : branch.type ? [branch.type] : [];
1045
+ const isObject = branchType.includes("object") || branch.properties !== void 0 || branch.additionalProperties !== void 0 || branch.patternProperties !== void 0;
1046
+ const isArray = branchType.includes("array") || branch.items !== void 0 || branch.prefixItems !== void 0;
1047
+ if (isObject) {
1048
+ for (const [property, propertySchema] of Object.entries(branch.properties ?? {})) {
1049
+ const path = makeExactPath(pointer, property);
1050
+ entries.push(...collectEntries(propertySchema, path, appendExactPattern(pattern, property), root));
1051
+ }
1052
+ for (const [propertyPattern, propertySchema] of Object.entries(branch.patternProperties ?? {})) {
1053
+ const path = makePatternPath(pointer, propertyPattern);
1054
+ entries.push(...collectEntries(propertySchema, path, appendRegexPattern(pattern, propertyPattern), root));
1055
+ }
1056
+ if (branch.additionalProperties && typeof branch.additionalProperties === "object") {
1057
+ const segmentPattern = childSegmentPattern(branch);
1058
+ const path = makePatternPath(pointer, segmentPattern);
1059
+ entries.push(...collectEntries(branch.additionalProperties, path, appendRegexPattern(pattern, segmentPattern), root));
1060
+ }
1061
+ }
1062
+ if (isArray) {
1063
+ if (Array.isArray(branch.items)) {
1064
+ branch.items.forEach((itemSchema, index) => {
1065
+ entries.push(...collectEntries(itemSchema, `${pointer}/${index}`, appendExactPattern(pattern, `${index}`), root));
1066
+ });
1067
+ } else if (branch.items && typeof branch.items === "object") {
1068
+ entries.push(...collectEntries(branch.items, `${pointer}/\\d+`, appendRegexPattern(pattern, "\\d+"), root));
1069
+ entries.push({
1070
+ path: `${pointer}/-`,
1071
+ pattern: makeExactPattern(`${pointer}/-`),
1072
+ schema: clone(branch.items),
1073
+ addOnly: true
1074
+ });
1075
+ }
1076
+ for (const [index, itemSchema] of (branch.prefixItems ?? []).entries()) {
1077
+ entries.push(...collectEntries(itemSchema, `${pointer}/${index}`, appendExactPattern(pattern, `${index}`), root));
1078
+ }
1079
+ }
1080
+ }
1081
+ return joinEntries(entries);
1082
+ };
1083
+ var pathMatcherSchema = (entry) => {
1084
+ if (entry.pattern && entry.pattern !== makeExactPattern(entry.path)) {
1085
+ return {
1086
+ type: "string",
1087
+ pattern: entry.pattern
1088
+ };
1089
+ }
1090
+ return {
1091
+ type: "string",
1092
+ const: entry.path
1093
+ };
1094
+ };
1095
+ var objectSchema = (properties, required) => {
1096
+ return {
1097
+ type: "object",
1098
+ properties,
1099
+ required,
1100
+ additionalProperties: false
1101
+ };
1102
+ };
1103
+ var conditionalValueSchema = (entry) => {
1104
+ return {
1105
+ if: {
1106
+ type: "object",
1107
+ properties: {
1108
+ path: pathMatcherSchema(entry)
1109
+ },
1110
+ required: ["path"]
1111
+ },
1112
+ then: {
1113
+ properties: {
1114
+ value: clone(entry.schema)
1115
+ }
1116
+ }
1117
+ };
1118
+ };
1119
+ var matchersSchema = (entries) => {
1120
+ return {
1121
+ oneOf: entries.map(pathMatcherSchema)
1122
+ };
1123
+ };
1124
+ var patchOperationSchema = (op, entries) => {
1125
+ const props = {
1126
+ op: {
1127
+ type: "string",
1128
+ const: op
1129
+ },
1130
+ path: matchersSchema(entries)
1131
+ };
1132
+ const required = ["op", "path"];
1133
+ const schema = objectSchema(props, required);
1134
+ switch (op) {
1135
+ case "add":
1136
+ case "replace":
1137
+ case "test":
1138
+ schema.properties = {
1139
+ ...schema.properties,
1140
+ value: {}
1141
+ };
1142
+ schema.required = [...required, "value"];
1143
+ schema.allOf = entries.map(conditionalValueSchema);
1144
+ return schema;
1145
+ case "move":
1146
+ case "copy":
1147
+ schema.properties = {
1148
+ ...schema.properties,
1149
+ from: matchersSchema(entries)
1150
+ };
1151
+ schema.required = ["op", "from", "path"];
1152
+ return schema;
1153
+ default:
1154
+ return schema;
1155
+ }
1156
+ };
1157
+ var normalizeEntry = (entry) => {
1158
+ return {
1159
+ ...entry,
1160
+ pattern: entry.pattern ?? makeExactPattern(entry.path)
1161
+ };
1162
+ };
1163
+ var isSchemaMetadataPath = (entry) => {
1164
+ return entry.path === "/$schema" || entry.path.startsWith("/$schema/");
1165
+ };
1166
+ var createStagePatchJsonSchema = (baseSchema, title) => {
1167
+ const entries = collectEntries(baseSchema).map(normalizeEntry).filter((entry) => !isSchemaMetadataPath(entry));
1168
+ const standardEntries = entries.filter((entry) => !entry.addOnly);
1169
+ const addEntries = entries;
1170
+ const moveCopyEntries = standardEntries.filter((entry) => entry.path !== "");
1171
+ return {
1172
+ $schema: "http://json-schema.org/draft-07/schema#",
1173
+ title,
1174
+ type: "object",
1175
+ additionalProperties: false,
1176
+ properties: {
1177
+ $schema: {
1178
+ type: "string"
1179
+ },
1180
+ operations: {
1181
+ type: "array",
1182
+ items: {
1183
+ oneOf: [
1184
+ patchOperationSchema("add", addEntries),
1185
+ patchOperationSchema("remove", standardEntries),
1186
+ patchOperationSchema("replace", standardEntries),
1187
+ patchOperationSchema("move", moveCopyEntries),
1188
+ patchOperationSchema("copy", moveCopyEntries),
1189
+ patchOperationSchema("test", standardEntries)
1190
+ ]
1191
+ }
1192
+ }
1193
+ },
1194
+ required: ["operations"]
1195
+ };
1196
+ };
1197
+
945
1198
  // src/config/stack.ts
946
1199
  import { z as z40 } from "zod";
947
1200
 
@@ -1597,6 +1850,7 @@ var generateJsonSchema = (props) => {
1597
1850
  appendDefaults(schema);
1598
1851
  schema.title = props.title;
1599
1852
  writeFileSync(file, JSON.stringify(schema));
1853
+ return schema;
1600
1854
  };
1601
1855
  var appendDefaults = (object) => {
1602
1856
  if (Array.isArray(object)) {
@@ -1619,13 +1873,21 @@ var appendDefaults = (object) => {
1619
1873
  }
1620
1874
  }
1621
1875
  };
1622
- generateJsonSchema({
1876
+ var appSchema = generateJsonSchema({
1623
1877
  schema: AppSchema,
1624
1878
  name: "app",
1625
1879
  title: "Awsless App Config"
1626
1880
  });
1627
- generateJsonSchema({
1881
+ var stackSchema = generateJsonSchema({
1628
1882
  schema: StackSchema,
1629
1883
  name: "stack",
1630
1884
  title: "Awsless Stack Config"
1631
1885
  });
1886
+ writeFileSync(
1887
+ join2(process.cwd(), "dist/app.stage.json"),
1888
+ JSON.stringify(createStagePatchJsonSchema(appSchema, "Awsless App Stage Patch Config"))
1889
+ );
1890
+ writeFileSync(
1891
+ join2(process.cwd(), "dist/stack.stage.json"),
1892
+ JSON.stringify(createStagePatchJsonSchema(stackSchema, "Awsless Stack Stage Patch Config"))
1893
+ );
Binary file
Binary file
Binary file