sayren 0.8.0 → 0.8.1
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/index.mjs +42 -13
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -965,7 +965,7 @@ const cli_app_dev_store_name_required = ((inputs = {}, options = {}) => {
|
|
|
965
965
|
/** @typedef {import('../runtime.js').LocalizedString} LocalizedString */
|
|
966
966
|
/** @typedef {{ dir: NonNullable<unknown> }} Cli_App_Dir_ExistsInputs */
|
|
967
967
|
const ko_cli_app_dir_exists = (i) => {
|
|
968
|
-
return `${i?.dir}에 이미
|
|
968
|
+
return `${i?.dir}에 이미 매니페스트(manifest.json)가 있습니다`;
|
|
969
969
|
};
|
|
970
970
|
/**
|
|
971
971
|
|
|
@@ -1200,6 +1200,24 @@ const cli_app_manifest_invalid = ((inputs, options = {}) => {
|
|
|
1200
1200
|
return ko_cli_app_manifest_invalid(inputs);
|
|
1201
1201
|
});
|
|
1202
1202
|
|
|
1203
|
+
//#endregion
|
|
1204
|
+
//#region ../i18n/src/paraglide/messages/cli_app_manifest_legacy.js
|
|
1205
|
+
/** @typedef {import('../runtime.js').LocalizedString} LocalizedString */
|
|
1206
|
+
/** @typedef {{}} Cli_App_Manifest_LegacyInputs */
|
|
1207
|
+
const ko_cli_app_manifest_legacy = () => {
|
|
1208
|
+
return `sayren.app.json은 옛 매니페스트 이름입니다. 파일 이름을 manifest.json으로 바꾸십시오`;
|
|
1209
|
+
};
|
|
1210
|
+
/**
|
|
1211
|
+
|
|
1212
|
+
* @param {Cli_App_Manifest_LegacyInputs} inputs
|
|
1213
|
+
* @param {{ locale?: "ko" }} options
|
|
1214
|
+
* @returns {LocalizedString}
|
|
1215
|
+
*/
|
|
1216
|
+
const cli_app_manifest_legacy = ((inputs = {}, options = {}) => {
|
|
1217
|
+
experimentalStaticLocale ?? options.locale ?? getLocale();
|
|
1218
|
+
return ko_cli_app_manifest_legacy(inputs);
|
|
1219
|
+
});
|
|
1220
|
+
|
|
1203
1221
|
//#endregion
|
|
1204
1222
|
//#region ../i18n/src/paraglide/messages/cli_app_manifest_missing.js
|
|
1205
1223
|
/** @typedef {import('../runtime.js').LocalizedString} LocalizedString */
|
|
@@ -9182,7 +9200,7 @@ async function selectStore(auth, client, io, candidates, folderStore = null) {
|
|
|
9182
9200
|
|
|
9183
9201
|
//#endregion
|
|
9184
9202
|
//#region package.json
|
|
9185
|
-
var version = "0.8.
|
|
9203
|
+
var version = "0.8.1";
|
|
9186
9204
|
|
|
9187
9205
|
//#endregion
|
|
9188
9206
|
//#region src/client.ts
|
|
@@ -9224,14 +9242,16 @@ function detailsOf(error) {
|
|
|
9224
9242
|
//#endregion
|
|
9225
9243
|
//#region src/app-commands.ts
|
|
9226
9244
|
/**
|
|
9227
|
-
* `sayren app …`(이슈 #22, 매뉴얼 「앱 만들기」) — 앱 폴더(`
|
|
9245
|
+
* `sayren app …`(이슈 #22, 매뉴얼 「앱 만들기」) — 앱 폴더(`manifest.json`)에서 돈다. 서버는 코드를 빌드하지 않는다(A1):
|
|
9228
9246
|
* CLI가 esbuild로 서버 번들 한 파일을 만들어 올리고 api가 `DEPENDENCIES`·`VERIFY`·`BUNDLE`·`UPLOAD`를 돈다. 앱 화면(`ui/`)은
|
|
9229
9247
|
* 정적 파일 그대로 올린다.
|
|
9230
9248
|
*
|
|
9231
9249
|
* 인증은 둘이다. 앱 배포 키(`--key`·`SAYREN_APP_KEY`, developer.sayren.app에서 발행, `sak_…`)는 그 앱의 경로에만 쓰이고(CI 용도),
|
|
9232
9250
|
* 그 밖에는 `sayren login`의 계정 토큰이다. 앱 등록(`init`)·개발 상점은 계정 토큰만 된다.
|
|
9233
9251
|
*/
|
|
9234
|
-
const APP_MANIFEST_FILE = "
|
|
9252
|
+
const APP_MANIFEST_FILE = "manifest.json";
|
|
9253
|
+
/** 0.8.0까지의 매니페스트 이름 — `manifest.json`이 없을 때만 읽고 경고한다 */
|
|
9254
|
+
const LEGACY_APP_MANIFEST_FILE = "sayren.app.json";
|
|
9235
9255
|
const APP_STATE_FILE = `${STATE_DIR}/app.json`;
|
|
9236
9256
|
const APP_DEV_PORT = 4020;
|
|
9237
9257
|
const SERVER_ENTRY_CANDIDATES = [
|
|
@@ -9261,10 +9281,17 @@ function writeAppState(dir, state) {
|
|
|
9261
9281
|
mkdirSync(join(dir, STATE_DIR), { recursive: true });
|
|
9262
9282
|
writeFileSync(join(dir, APP_STATE_FILE), `${JSON.stringify(state, null, 2)}\n`, { mode: 384 });
|
|
9263
9283
|
}
|
|
9264
|
-
/**
|
|
9284
|
+
/** 앱 폴더의 매니페스트 파일 — `manifest.json`, 없으면 옛 이름 `sayren.app.json`. 둘 다 없으면 null */
|
|
9285
|
+
function manifestFileOf(dir) {
|
|
9286
|
+
if (existsSync(join(dir, APP_MANIFEST_FILE))) return APP_MANIFEST_FILE;
|
|
9287
|
+
if (existsSync(join(dir, LEGACY_APP_MANIFEST_FILE))) return LEGACY_APP_MANIFEST_FILE;
|
|
9288
|
+
return null;
|
|
9289
|
+
}
|
|
9290
|
+
/** 매니페스트 원문(JSON)과 검증 결과 — 문제가 있으면 CliError. 옛 이름으로 읽었으면 `warnings`에 이름 변경 안내가 든다 */
|
|
9265
9291
|
function loadManifest(dir) {
|
|
9266
|
-
const
|
|
9267
|
-
if (!
|
|
9292
|
+
const file = manifestFileOf(dir);
|
|
9293
|
+
if (!file) throw new CliError(cli_app_manifest_missing({ file: APP_MANIFEST_FILE }));
|
|
9294
|
+
const path = join(dir, file);
|
|
9268
9295
|
let raw;
|
|
9269
9296
|
try {
|
|
9270
9297
|
raw = JSON.parse(readFileSync(path, "utf8"));
|
|
@@ -9275,9 +9302,11 @@ function loadManifest(dir) {
|
|
|
9275
9302
|
if (!parsed.success) throw new CliError(cli_app_manifest_invalid({ problems: parsed.error.issues.map((issue) => `- ${issue.path.join(".") || "(root)"}: ${issue.message}`).join("\n") }));
|
|
9276
9303
|
const problems = appManifestProblems(parsed.data);
|
|
9277
9304
|
if (problems.length) throw new CliError(cli_app_manifest_invalid({ problems: problems.map((p) => `- ${p.path}: ${p.message} (${p.code})`).join("\n") }));
|
|
9305
|
+
const warnings = file === LEGACY_APP_MANIFEST_FILE ? [cli_app_manifest_legacy()] : [];
|
|
9278
9306
|
return {
|
|
9279
9307
|
raw,
|
|
9280
|
-
manifest: parsed.data
|
|
9308
|
+
manifest: parsed.data,
|
|
9309
|
+
warnings
|
|
9281
9310
|
};
|
|
9282
9311
|
}
|
|
9283
9312
|
function appDir(flags, io) {
|
|
@@ -9285,7 +9314,7 @@ function appDir(flags, io) {
|
|
|
9285
9314
|
}
|
|
9286
9315
|
function requireState(dir) {
|
|
9287
9316
|
const state = readAppState(dir);
|
|
9288
|
-
if (!state) throw new CliError(cli_app_not_registered({ file: APP_MANIFEST_FILE }));
|
|
9317
|
+
if (!state) throw new CliError(cli_app_not_registered({ file: manifestFileOf(dir) ?? APP_MANIFEST_FILE }));
|
|
9289
9318
|
return state;
|
|
9290
9319
|
}
|
|
9291
9320
|
/** 배포 키(`--key` → `SAYREN_APP_KEY`)가 있으면 그것, 없으면 계정 토큰(`resolveAuth`) */
|
|
@@ -9452,7 +9481,7 @@ const EMPTY_META = {
|
|
|
9452
9481
|
tools: []
|
|
9453
9482
|
};
|
|
9454
9483
|
async function verifyApp(dir) {
|
|
9455
|
-
const { raw, manifest } = loadManifest(dir);
|
|
9484
|
+
const { raw, manifest, warnings } = loadManifest(dir);
|
|
9456
9485
|
const external = manifest.runtime === "external";
|
|
9457
9486
|
const server = external ? EXTERNAL_STUB_SERVER : await bundleServer(dir);
|
|
9458
9487
|
if (APP_SECRET_PATTERNS.find((pattern) => pattern.test(server))) throw new CliError(cli_app_secret_in_source());
|
|
@@ -9474,7 +9503,6 @@ async function verifyApp(dir) {
|
|
|
9474
9503
|
...(manifest.http?.public ?? []).filter((key) => !httpKeys.has(key))
|
|
9475
9504
|
];
|
|
9476
9505
|
if (missing.length) throw new CliError(cli_app_handler_missing({ events: missing.join(", ") }));
|
|
9477
|
-
const warnings = [];
|
|
9478
9506
|
const listed = manifest.events;
|
|
9479
9507
|
const extra = meta.events.filter((event) => !listed.includes(event));
|
|
9480
9508
|
if (extra.length) warnings.push(cli_app_handler_unlisted({ events: extra.join(", ") }));
|
|
@@ -9584,7 +9612,7 @@ export default defineApp({
|
|
|
9584
9612
|
async function appInit(handle, flags, io) {
|
|
9585
9613
|
if (!handle || !HANDLE_RE.test(handle)) throw new CliError(cli_app_handle_invalid());
|
|
9586
9614
|
const dir = resolve(io.cwd, flags.dir ?? handle);
|
|
9587
|
-
if (
|
|
9615
|
+
if (manifestFileOf(dir)) throw new CliError(cli_app_dir_exists({ dir: relative(io.cwd, dir) || "." }));
|
|
9588
9616
|
const name = flags.name?.trim() || handle;
|
|
9589
9617
|
const auth = await developerAuth(flags, dir, io, { accountOnly: true });
|
|
9590
9618
|
const privateStoreId = flags.privateStore?.trim();
|
|
@@ -9910,7 +9938,8 @@ function readBody(req) {
|
|
|
9910
9938
|
async function appDev(flags, io) {
|
|
9911
9939
|
const dir = appDir(flags, io);
|
|
9912
9940
|
const state = requireState(dir);
|
|
9913
|
-
const { manifest } = loadManifest(dir);
|
|
9941
|
+
const { manifest, warnings } = loadManifest(dir);
|
|
9942
|
+
for (const warning of warnings) io.err(cli_app_warning({ message: warning }));
|
|
9914
9943
|
const { app } = await loadBundle(dir, await bundleServer(dir));
|
|
9915
9944
|
const port = Number(flags.port ?? io.env.SAYREN_APP_PORT ?? APP_DEV_PORT);
|
|
9916
9945
|
if (!Number.isInteger(port) || port < 1 || port > 65535) throw new CliError(cli_app_port_invalid({ value: String(flags.port) }));
|