@awsless/cli 0.0.46-local.7 → 0.0.46-local.9
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 +110 -15
- package/package.json +14 -14
package/dist/bin.js
CHANGED
|
@@ -150257,6 +150257,16 @@ var bootstrapAwsless = async (props) => {
|
|
|
150257
150257
|
// src/config/load/load.ts
|
|
150258
150258
|
import { basename as basename2, dirname as dirname5, join as join13 } from "path";
|
|
150259
150259
|
|
|
150260
|
+
// src/feature/config/schema.ts
|
|
150261
|
+
var ConfigNameSchema = exports_external.string().regex(/^[a-z0-9-]+$/, "Invalid config name");
|
|
150262
|
+
var ConfigsSchema = exports_external.array(ConfigNameSchema).optional().describe("Define the config values for your app.");
|
|
150263
|
+
var ConfigFileSchema = exports_external.record(ConfigNameSchema, exports_external.union([
|
|
150264
|
+
exports_external.string().describe("A committed default value for the local dev environment."),
|
|
150265
|
+
exports_external.object({
|
|
150266
|
+
secret: exports_external.literal(true).describe("Pulled from ssm into memory on local dev boot, never stored locally.")
|
|
150267
|
+
}).describe("A secret config value.")
|
|
150268
|
+
])).describe("The config values of your app.");
|
|
150269
|
+
|
|
150260
150270
|
// src/config/schema/config-ref.ts
|
|
150261
150271
|
var ConfigRefSchema = exports_external.string().regex(/^config:[a-z0-9-]+$/, "Invalid config reference");
|
|
150262
150272
|
var isConfigRef = (value) => {
|
|
@@ -150325,10 +150335,6 @@ var AuthDefaultSchema = exports_external.record(ResourceIdSchema, exports_extern
|
|
|
150325
150335
|
}).default({}).describe("Specifies the validity duration for every JWT token.")
|
|
150326
150336
|
})).default({}).describe("Define the authenticatable users in your app.");
|
|
150327
150337
|
|
|
150328
|
-
// src/feature/config/schema.ts
|
|
150329
|
-
var ConfigNameSchema = exports_external.string().regex(/^[a-z0-9-]+$/, "Invalid config name");
|
|
150330
|
-
var ConfigsSchema = exports_external.array(ConfigNameSchema).optional().describe("Define the config values for your app.");
|
|
150331
|
-
|
|
150332
150338
|
// src/feature/domain/schema.ts
|
|
150333
150339
|
var DomainNameSchema = exports_external.string().regex(/[a-z\-\_\.]/g, "Invalid domain name").describe("Enter a fully qualified domain name, for example, www.example.com. You can optionally include a trailing dot. If you omit the trailing dot, Amazon Route 53 assumes that the domain name that you specify is fully qualified. This means that Route 53 treats www.example.com (without a trailing dot) and www.example.com. (with a trailing dot) as identical.");
|
|
150334
150340
|
var DNSTypeSchema = exports_external.enum(["A", "AAAA", "CAA", "CNAME", "DS", "MX", "NAPTR", "NS", "PTR", "SOA", "SPF", "SRV", "TXT"]).describe("The DNS record type.");
|
|
@@ -152482,8 +152488,32 @@ var loadAppConfig = async (options) => {
|
|
|
152482
152488
|
debug("Validate app config file");
|
|
152483
152489
|
const app = await validateConfig(AppSchema, appConfig.file, appConfig.data);
|
|
152484
152490
|
app.stage = options.stage;
|
|
152491
|
+
await loadConfigFile(app, root3, options.stage);
|
|
152485
152492
|
return app;
|
|
152486
152493
|
};
|
|
152494
|
+
var loadConfigFile = async (app, root3, stage) => {
|
|
152495
|
+
const ext2 = ["config.json", "config.jsonc", "config.json5"];
|
|
152496
|
+
const files = await glob(ext2, { cwd: root3 });
|
|
152497
|
+
const file2 = ext2.find((name) => files.includes(name));
|
|
152498
|
+
if (!file2) {
|
|
152499
|
+
return;
|
|
152500
|
+
}
|
|
152501
|
+
debug("Load config file:", color2.info(file2));
|
|
152502
|
+
const config = await readConfigWithStage(join13(root3, file2), stage);
|
|
152503
|
+
const entries2 = await validateConfig(ConfigFileSchema, config.file, config.data);
|
|
152504
|
+
const defaults2 = {};
|
|
152505
|
+
const secrets = [];
|
|
152506
|
+
for (const [name, value] of Object.entries(entries2)) {
|
|
152507
|
+
if (typeof value === "string") {
|
|
152508
|
+
defaults2[name] = value;
|
|
152509
|
+
} else {
|
|
152510
|
+
secrets.push(name);
|
|
152511
|
+
}
|
|
152512
|
+
}
|
|
152513
|
+
app.configs = [...new Set([...app.configs ?? [], ...Object.keys(entries2)])].sort();
|
|
152514
|
+
app.configDefaults = defaults2;
|
|
152515
|
+
app.configSecrets = secrets;
|
|
152516
|
+
};
|
|
152487
152517
|
var loadStackConfigs = async (options) => {
|
|
152488
152518
|
debug("Load stacks config files");
|
|
152489
152519
|
const ext2 = "{json,jsonc,json5}";
|
|
@@ -154771,6 +154801,9 @@ var createSsmServer = (props) => {
|
|
|
154771
154801
|
let closeServer;
|
|
154772
154802
|
let log;
|
|
154773
154803
|
const warned2 = new Set;
|
|
154804
|
+
let defaults2 = {};
|
|
154805
|
+
let pulled = {};
|
|
154806
|
+
let secrets = new Set;
|
|
154774
154807
|
const loadValues = async () => {
|
|
154775
154808
|
try {
|
|
154776
154809
|
return JSON.parse(await readFile12(props.file, "utf8"));
|
|
@@ -154782,6 +154815,11 @@ var createSsmServer = (props) => {
|
|
|
154782
154815
|
connect(logFn) {
|
|
154783
154816
|
log = logFn;
|
|
154784
154817
|
},
|
|
154818
|
+
setValues(next) {
|
|
154819
|
+
defaults2 = next.defaults;
|
|
154820
|
+
pulled = next.pulled;
|
|
154821
|
+
secrets = next.secrets;
|
|
154822
|
+
},
|
|
154785
154823
|
async listen(port = 0) {
|
|
154786
154824
|
server = createServer2((req, res) => {
|
|
154787
154825
|
const chunks = [];
|
|
@@ -154801,12 +154839,12 @@ var createSsmServer = (props) => {
|
|
|
154801
154839
|
const parameters = [];
|
|
154802
154840
|
for (const name of Names ?? []) {
|
|
154803
154841
|
const key = name.split("/").at(-1);
|
|
154804
|
-
const value = values[key];
|
|
154842
|
+
const value = values[key] ?? defaults2[key] ?? pulled[key];
|
|
154805
154843
|
if (typeof value === "string") {
|
|
154806
154844
|
parameters.push({ Name: name, Type: "SecureString", Value: value });
|
|
154807
154845
|
} else if (!warned2.has(key)) {
|
|
154808
154846
|
warned2.add(key);
|
|
154809
|
-
log?.(`The "${key}" config has no local value yet. Set it on the dashboard or in
|
|
154847
|
+
log?.(secrets.has(key) ? `The "${key}" config secret has no value - the ssm pull didn't provide one. Set it with "awsless config set ${key}" or override it on the dashboard.` : `The "${key}" config has no local value yet. Set it on the dashboard or add a default in config.jsonc`);
|
|
154810
154848
|
}
|
|
154811
154849
|
}
|
|
154812
154850
|
res.writeHead(200, { "content-type": "application/x-amz-json-1.1" });
|
|
@@ -154992,9 +155030,10 @@ var configFeature = defineFeature({
|
|
|
154992
155030
|
if (names.size === 0) {
|
|
154993
155031
|
return;
|
|
154994
155032
|
}
|
|
155033
|
+
const secrets = new Set(ctx.appConfig.configSecrets ?? []);
|
|
154995
155034
|
for (const name of names) {
|
|
154996
155035
|
ctx.addEnv(`CONFIG_${constantCase(name)}`, name);
|
|
154997
|
-
ctx.registerResource({ kind: "config", id: name });
|
|
155036
|
+
ctx.registerResource({ kind: "config", id: name, detail: secrets.has(name) ? "secret" : "" });
|
|
154998
155037
|
}
|
|
154999
155038
|
const file2 = join18(directories.output, "local", "config.json");
|
|
155000
155039
|
const { server, port } = await ctx.keep("shim:ssm", file2, async () => {
|
|
@@ -155003,6 +155042,38 @@ var configFeature = defineFeature({
|
|
|
155003
155042
|
return { value: { server: server2, port: port2 }, stop: () => server2.stop() };
|
|
155004
155043
|
});
|
|
155005
155044
|
ctx.addEnv("AWS_ENDPOINT_URL_SSM", `http://127.0.0.1:${port}`);
|
|
155045
|
+
let pulled = {};
|
|
155046
|
+
if (secrets.size > 0) {
|
|
155047
|
+
pulled = await ctx.keep("config:pull", [...secrets].sort().join(","), async () => {
|
|
155048
|
+
const values = {};
|
|
155049
|
+
try {
|
|
155050
|
+
ctx.log(`Pulling ${secrets.size} config secret${secrets.size === 1 ? "" : "s"} from SSM...`);
|
|
155051
|
+
const credentials2 = await getCredentials(ctx.appConfig.profile);
|
|
155052
|
+
const store = new SsmStore({ credentials: credentials2, appConfig: ctx.appConfig });
|
|
155053
|
+
let timer;
|
|
155054
|
+
const all5 = await Promise.race([
|
|
155055
|
+
store.list(),
|
|
155056
|
+
new Promise((_3, reject) => {
|
|
155057
|
+
timer = setTimeout(() => reject(new Error("the pull timed out after 15s")), 15000);
|
|
155058
|
+
})
|
|
155059
|
+
]).finally(() => clearTimeout(timer));
|
|
155060
|
+
for (const name of secrets) {
|
|
155061
|
+
if (typeof all5[name] === "string") {
|
|
155062
|
+
values[name] = all5[name];
|
|
155063
|
+
}
|
|
155064
|
+
}
|
|
155065
|
+
} catch (error3) {
|
|
155066
|
+
debug("Config secret pull failed", error3);
|
|
155067
|
+
ctx.log(`Couldn't pull the config secrets from SSM (${error3 instanceof Error ? error3.message : String(error3)}) - secret-backed features will fail when called.`);
|
|
155068
|
+
}
|
|
155069
|
+
return { value: values, stop: () => {} };
|
|
155070
|
+
});
|
|
155071
|
+
}
|
|
155072
|
+
server.setValues({
|
|
155073
|
+
defaults: ctx.appConfig.configDefaults ?? {},
|
|
155074
|
+
pulled,
|
|
155075
|
+
secrets
|
|
155076
|
+
});
|
|
155006
155077
|
ctx.restartOnChange(file2);
|
|
155007
155078
|
ctx.registerServer({
|
|
155008
155079
|
name: "config",
|
|
@@ -165788,7 +165859,7 @@ var watchConfig = async (options, resolve5, reject) => {
|
|
|
165788
165859
|
await loadAppConfig(options);
|
|
165789
165860
|
debug("Start watching...");
|
|
165790
165861
|
const ext2 = "{json,jsonc,json5}";
|
|
165791
|
-
const watcher = $watch([`app.${ext2}`, `**/stack.${ext2}`, `**/*.stack.${ext2}`], {
|
|
165862
|
+
const watcher = $watch([`app.${ext2}`, `config.${ext2}`, `**/stack.${ext2}`, `**/*.stack.${ext2}`], {
|
|
165792
165863
|
cwd: directories.root,
|
|
165793
165864
|
ignored: ["**/node_modules/**", "**/dist/**"],
|
|
165794
165865
|
awaitWriteFinish: true
|
|
@@ -167120,12 +167191,25 @@ const configPanel = async (main) => {
|
|
|
167120
167191
|
const names = [...new Set(state.resources.filter(r => r.kind === 'config').map(r => r.id))].sort()
|
|
167121
167192
|
const data = await api('/api/config')
|
|
167122
167193
|
const values = data.values ?? {}
|
|
167194
|
+
const defaults = data.defaults ?? {}
|
|
167195
|
+
const secrets = new Set(data.secrets ?? [])
|
|
167123
167196
|
|
|
167124
167197
|
const inputs = new Map()
|
|
167125
167198
|
const form = $('div', { className: 'config-form' })
|
|
167126
167199
|
|
|
167127
167200
|
for (const name of names) {
|
|
167128
|
-
|
|
167201
|
+
// An empty input falls through to the committed default or the
|
|
167202
|
+
// pulled ssm secret - the placeholder shows which one carries.
|
|
167203
|
+
const placeholder = secrets.has(name)
|
|
167204
|
+
? 'pulled from ssm'
|
|
167205
|
+
: defaults[name] !== undefined ? 'default: ' + defaults[name] : 'not set'
|
|
167206
|
+
|
|
167207
|
+
const input = $('input', {
|
|
167208
|
+
value: values[name] ?? '',
|
|
167209
|
+
placeholder,
|
|
167210
|
+
spellcheck: false,
|
|
167211
|
+
...(secrets.has(name) ? { type: 'password' } : {}),
|
|
167212
|
+
})
|
|
167129
167213
|
inputs.set(name, input)
|
|
167130
167214
|
form.append($('label', { className: 'field' }, [$('span', { className: 'name' }, name), input]))
|
|
167131
167215
|
}
|
|
@@ -167567,7 +167651,14 @@ var createDashboardServer = (props) => {
|
|
|
167567
167651
|
try {
|
|
167568
167652
|
values = JSON.parse(await readFile21(props.configFile, "utf8"));
|
|
167569
167653
|
} catch (_4) {}
|
|
167570
|
-
return {
|
|
167654
|
+
return {
|
|
167655
|
+
status: 200,
|
|
167656
|
+
body: JSON.stringify({
|
|
167657
|
+
values,
|
|
167658
|
+
defaults: props.configMeta?.defaults ?? {},
|
|
167659
|
+
secrets: props.configMeta?.secrets ?? []
|
|
167660
|
+
})
|
|
167661
|
+
};
|
|
167571
167662
|
}
|
|
167572
167663
|
return { status: 404, body: JSON.stringify({ error: `Unknown dashboard path: ${url.pathname}` }) };
|
|
167573
167664
|
};
|
|
@@ -167990,6 +168081,10 @@ var startDev = async (props) => {
|
|
|
167990
168081
|
env: env4,
|
|
167991
168082
|
storeRoot: join53(directories.output, "local", "store"),
|
|
167992
168083
|
configFile: join53(directories.output, "local", "config.json"),
|
|
168084
|
+
configMeta: {
|
|
168085
|
+
defaults: appConfig.configDefaults ?? {},
|
|
168086
|
+
secrets: appConfig.configSecrets ?? []
|
|
168087
|
+
},
|
|
167993
168088
|
events: dev.events
|
|
167994
168089
|
});
|
|
167995
168090
|
dashboard.connect(dispatch);
|
|
@@ -168250,7 +168345,7 @@ import { DynamoDBClient as DynamoDBClient6, dynamoDBClient } from "@awsless/dyna
|
|
|
168250
168345
|
|
|
168251
168346
|
// ../../node_modules/.pnpm/@aws-sdk+client-iot-data-plane@3.1023.0_aws-crt@1.30.0_supports-color@8.1.1_/node_modules/@aws-sdk/client-iot-data-plane/dist-es/IoTDataPlaneClient.js
|
|
168252
168347
|
var import_core50 = __toESM(require_dist_cjs2(), 1);
|
|
168253
|
-
var
|
|
168348
|
+
var import_schema68 = __toESM(require_schema(), 1);
|
|
168254
168349
|
|
|
168255
168350
|
// ../../node_modules/.pnpm/@aws-sdk+client-iot-data-plane@3.1023.0_aws-crt@1.30.0_supports-color@8.1.1_/node_modules/@aws-sdk/client-iot-data-plane/dist-es/auth/httpAuthSchemeProvider.js
|
|
168256
168351
|
var import_httpAuthSchemes4 = __toESM(require_httpAuthSchemes(), 1);
|
|
@@ -168456,7 +168551,7 @@ var defaultEndpointResolver3 = (endpointParams, context = {}) => {
|
|
|
168456
168551
|
customEndpointFunctions.aws = awsEndpointFunctions;
|
|
168457
168552
|
|
|
168458
168553
|
// ../../node_modules/.pnpm/@aws-sdk+client-iot-data-plane@3.1023.0_aws-crt@1.30.0_supports-color@8.1.1_/node_modules/@aws-sdk/client-iot-data-plane/dist-es/schemas/schemas_0.js
|
|
168459
|
-
var
|
|
168554
|
+
var import_schema67 = __toESM(require_schema(), 1);
|
|
168460
168555
|
|
|
168461
168556
|
// ../../node_modules/.pnpm/@aws-sdk+client-iot-data-plane@3.1023.0_aws-crt@1.30.0_supports-color@8.1.1_/node_modules/@aws-sdk/client-iot-data-plane/dist-es/models/IoTDataPlaneServiceException.js
|
|
168462
168557
|
class IoTDataPlaneServiceException extends ServiceException {
|
|
@@ -168686,10 +168781,10 @@ var _xamcd = "x-amz-mqtt5-correlation-data";
|
|
|
168686
168781
|
var _xampfi = "x-amz-mqtt5-payload-format-indicator";
|
|
168687
168782
|
var _xamup = "x-amz-mqtt5-user-properties";
|
|
168688
168783
|
var n03 = "com.amazonaws.iotdataplane";
|
|
168689
|
-
var _s_registry3 =
|
|
168784
|
+
var _s_registry3 = import_schema67.TypeRegistry.for(_s3);
|
|
168690
168785
|
var IoTDataPlaneServiceException$ = [-3, _s3, "IoTDataPlaneServiceException", 0, [], []];
|
|
168691
168786
|
_s_registry3.registerError(IoTDataPlaneServiceException$, IoTDataPlaneServiceException);
|
|
168692
|
-
var n0_registry3 =
|
|
168787
|
+
var n0_registry3 = import_schema67.TypeRegistry.for(n03);
|
|
168693
168788
|
var ConflictException$ = [
|
|
168694
168789
|
-3,
|
|
168695
168790
|
n03,
|
|
@@ -169125,7 +169220,7 @@ class IoTDataPlaneClient extends Client {
|
|
|
169125
169220
|
const _config_7 = resolveHttpAuthSchemeConfig3(_config_6);
|
|
169126
169221
|
const _config_8 = resolveRuntimeExtensions3(_config_7, configuration?.extensions || []);
|
|
169127
169222
|
this.config = _config_8;
|
|
169128
|
-
this.middlewareStack.use(
|
|
169223
|
+
this.middlewareStack.use(import_schema68.getSchemaSerdePlugin(this.config));
|
|
169129
169224
|
this.middlewareStack.use(getUserAgentPlugin(this.config));
|
|
169130
169225
|
this.middlewareStack.use(getRetryPlugin(this.config));
|
|
169131
169226
|
this.middlewareStack.use(getContentLengthPlugin(this.config));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@awsless/cli",
|
|
3
|
-
"version": "0.0.46-local.
|
|
3
|
+
"version": "0.0.46-local.9",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -43,14 +43,14 @@
|
|
|
43
43
|
},
|
|
44
44
|
"peerDependencies": {
|
|
45
45
|
"@awsless/big-float": "^0.1.7",
|
|
46
|
-
"@awsless/dynamodb": "^0.3.22",
|
|
47
|
-
"@awsless/lambda": "^0.0.47",
|
|
48
46
|
"@awsless/duration": "^0.0.4",
|
|
49
47
|
"@awsless/json": "^0.0.11",
|
|
48
|
+
"@awsless/dynamodb": "^0.3.22",
|
|
50
49
|
"@awsless/s3": "^0.0.22",
|
|
51
|
-
"awsless": "^0.0.
|
|
50
|
+
"@awsless/lambda": "^0.0.47",
|
|
52
51
|
"@awsless/weak-cache": "^0.0.1",
|
|
53
|
-
"@awsless/validate": "^0.1.7"
|
|
52
|
+
"@awsless/validate": "^0.1.7",
|
|
53
|
+
"awsless": "^0.0.15-local.3"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
56
|
"@aws-sdk/client-cloudformation": "^3.369.0",
|
|
@@ -120,25 +120,25 @@
|
|
|
120
120
|
"zip-a-folder": "^3.1.6",
|
|
121
121
|
"zod": "^3.24.2",
|
|
122
122
|
"zod-to-json-schema": "^3.24.3",
|
|
123
|
+
"@awsless/big-float": "^0.1.7",
|
|
123
124
|
"@awsless/cloudwatch": "^0.0.1",
|
|
124
125
|
"@awsless/clui": "^0.0.9",
|
|
125
|
-
"@awsless/big-float": "^0.1.7",
|
|
126
|
-
"@awsless/dynamodb": "^0.3.22",
|
|
127
126
|
"@awsless/json": "^0.0.11",
|
|
128
127
|
"@awsless/lambda": "^0.0.47",
|
|
129
|
-
"@awsless/
|
|
128
|
+
"@awsless/iot": "^0.0.5",
|
|
130
129
|
"@awsless/duration": "^0.0.4",
|
|
130
|
+
"@awsless/open-search": "^0.0.24",
|
|
131
131
|
"@awsless/redis": "^0.1.13",
|
|
132
|
-
"@awsless/size": "^0.0.2",
|
|
133
|
-
"@awsless/iot": "^0.0.5",
|
|
134
|
-
"@awsless/sqs": "^0.0.24",
|
|
135
|
-
"@awsless/ssm": "^0.0.8",
|
|
136
|
-
"@awsless/sns": "^0.0.11",
|
|
137
132
|
"@awsless/s3": "^0.0.22",
|
|
133
|
+
"@awsless/scheduler": "^0.0.5",
|
|
134
|
+
"@awsless/sqs": "^0.0.24",
|
|
138
135
|
"@awsless/validate": "^0.1.7",
|
|
136
|
+
"@awsless/sns": "^0.0.11",
|
|
137
|
+
"@awsless/ssm": "^0.0.8",
|
|
139
138
|
"@awsless/weak-cache": "^0.0.1",
|
|
139
|
+
"@awsless/size": "^0.0.2",
|
|
140
140
|
"awsless": "^0.0.15-local.3",
|
|
141
|
-
"@awsless/
|
|
141
|
+
"@awsless/dynamodb": "^0.3.22"
|
|
142
142
|
},
|
|
143
143
|
"scripts": {
|
|
144
144
|
"test": "bun cli/build-handlers.ts && pnpm vitest",
|