@lumerahq/cli 0.19.20 → 0.19.22
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/{chunk-ML7XB7Z2.js → chunk-JMRD5WIY.js} +56 -0
- package/dist/{chunk-S7FJU4GM.js → chunk-RH4FQF6O.js} +1 -1
- package/dist/{chunk-PY4J2U2M.js → chunk-XT4EGGK7.js} +8 -2
- package/dist/{deps-H4QYLGM7.js → deps-VTLXKCQ7.js} +2 -2
- package/dist/{dev-O6TXHGAK.js → dev-EQK27BUM.js} +3 -3
- package/dist/index.js +12 -12
- package/dist/{init-HUV5ZJAE.js → init-UF4JYQSQ.js} +10 -2
- package/dist/{register-OZDOFUPF.js → register-BQCVUPWS.js} +8 -2
- package/dist/{resources-FLFD64X2.js → resources-Z5ZMPWTK.js} +10 -4
- package/dist/{run-NR3725J2.js → run-LHHX7UBN.js} +1 -1
- package/package.json +1 -1
- package/templates/default/pnpm-lock.yaml +5 -5
|
@@ -7,6 +7,55 @@ import {
|
|
|
7
7
|
fetchWithRetry
|
|
8
8
|
} from "./chunk-FJFIWC7G.js";
|
|
9
9
|
|
|
10
|
+
// src/lib/name-limits.ts
|
|
11
|
+
var MAX_PROJECT_NAME_LENGTH = 30;
|
|
12
|
+
var MAX_COLLECTION_NAME_LENGTH = 30;
|
|
13
|
+
var MAX_POSTGRES_IDENTIFIER_BYTES = 63;
|
|
14
|
+
var PROJECT_EXTERNAL_ID_REGEX = /^[a-z0-9][a-z0-9-]*[a-z0-9]$|^[a-z0-9]$/;
|
|
15
|
+
var RESERVED_PROJECT_EXTERNAL_IDS = /* @__PURE__ */ new Set([
|
|
16
|
+
"collection",
|
|
17
|
+
"collections",
|
|
18
|
+
"default",
|
|
19
|
+
"admin",
|
|
20
|
+
"api",
|
|
21
|
+
"system",
|
|
22
|
+
"internal",
|
|
23
|
+
"platform",
|
|
24
|
+
"lumera",
|
|
25
|
+
"lm"
|
|
26
|
+
]);
|
|
27
|
+
function lengthOf(value) {
|
|
28
|
+
return Array.from(value).length;
|
|
29
|
+
}
|
|
30
|
+
function validateProjectNameLength(name, label = "App name") {
|
|
31
|
+
if (lengthOf(name.trim()) > MAX_PROJECT_NAME_LENGTH) {
|
|
32
|
+
return `${label} must be ${MAX_PROJECT_NAME_LENGTH} characters or less`;
|
|
33
|
+
}
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
function validateProjectExternalId(externalId) {
|
|
37
|
+
const trimmed = externalId.trim();
|
|
38
|
+
const lengthError = validateProjectNameLength(trimmed, "App ID");
|
|
39
|
+
if (lengthError) return lengthError;
|
|
40
|
+
if (!PROJECT_EXTERNAL_ID_REGEX.test(trimmed)) {
|
|
41
|
+
return "App ID must use lowercase letters, numbers, and hyphens only";
|
|
42
|
+
}
|
|
43
|
+
if (RESERVED_PROJECT_EXTERNAL_IDS.has(trimmed)) {
|
|
44
|
+
return `App ID "${trimmed}" is a reserved name`;
|
|
45
|
+
}
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
function validateCollectionNameLength(name) {
|
|
49
|
+
const trimmed = name.trim();
|
|
50
|
+
if (lengthOf(trimmed) > MAX_COLLECTION_NAME_LENGTH) {
|
|
51
|
+
return `collection name must be ${MAX_COLLECTION_NAME_LENGTH} characters or less`;
|
|
52
|
+
}
|
|
53
|
+
if (new TextEncoder().encode(trimmed).byteLength > MAX_POSTGRES_IDENTIFIER_BYTES) {
|
|
54
|
+
return `collection name must be ${MAX_POSTGRES_IDENTIFIER_BYTES} bytes or less`;
|
|
55
|
+
}
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
|
|
10
59
|
// src/lib/api.ts
|
|
11
60
|
init_auth();
|
|
12
61
|
import { readFileSync } from "fs";
|
|
@@ -282,6 +331,10 @@ var ApiClient = class {
|
|
|
282
331
|
// Projects — register/lookup via PocketBase records API
|
|
283
332
|
async registerProject(name, externalId) {
|
|
284
333
|
const extId = externalId || name;
|
|
334
|
+
const nameError = validateProjectNameLength(name, "App name");
|
|
335
|
+
if (nameError) throw new Error(nameError);
|
|
336
|
+
const externalIdError = validateProjectExternalId(extId);
|
|
337
|
+
if (externalIdError) throw new Error(externalIdError);
|
|
285
338
|
const existing = await this.getProjectByExternalId(extId);
|
|
286
339
|
if (existing) {
|
|
287
340
|
return existing;
|
|
@@ -364,6 +417,9 @@ function createApiClient(token, baseUrl, projectExternalId) {
|
|
|
364
417
|
}
|
|
365
418
|
|
|
366
419
|
export {
|
|
420
|
+
validateProjectNameLength,
|
|
421
|
+
validateProjectExternalId,
|
|
422
|
+
validateCollectionNameLength,
|
|
367
423
|
userContextHeaders,
|
|
368
424
|
ApiError,
|
|
369
425
|
isApiErrorStatus,
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
|
-
userContextHeaders
|
|
3
|
-
|
|
2
|
+
userContextHeaders,
|
|
3
|
+
validateProjectExternalId,
|
|
4
|
+
validateProjectNameLength
|
|
5
|
+
} from "./chunk-JMRD5WIY.js";
|
|
4
6
|
import {
|
|
5
7
|
fetchWithRetry
|
|
6
8
|
} from "./chunk-FJFIWC7G.js";
|
|
@@ -63,6 +65,10 @@ async function createTarball(distDir) {
|
|
|
63
65
|
});
|
|
64
66
|
}
|
|
65
67
|
async function ensureAppRecord(apiBase, token, appName, appTitle) {
|
|
68
|
+
const appIdError = validateProjectExternalId(appName);
|
|
69
|
+
if (appIdError) throw new Error(appIdError);
|
|
70
|
+
const appNameError = validateProjectNameLength(appTitle, "App name");
|
|
71
|
+
if (appNameError) throw new Error(appNameError);
|
|
66
72
|
const filterParam = encodeURIComponent(JSON.stringify({ external_id: appName }));
|
|
67
73
|
const searchRes = await fetchWithRetry(
|
|
68
74
|
`${apiBase}/pb/collections/lm_custom_apps/records?filter=${filterParam}`,
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
deps,
|
|
3
3
|
syncDeps
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-RH4FQF6O.js";
|
|
5
5
|
import "./chunk-2CR762KB.js";
|
|
6
|
-
import "./chunk-
|
|
6
|
+
import "./chunk-JMRD5WIY.js";
|
|
7
7
|
import "./chunk-ZH3NVYEQ.js";
|
|
8
8
|
import "./chunk-FJFIWC7G.js";
|
|
9
9
|
import "./chunk-PNKVD2UK.js";
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
dev
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-XT4EGGK7.js";
|
|
4
4
|
import {
|
|
5
5
|
syncDeps
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-RH4FQF6O.js";
|
|
7
7
|
import {
|
|
8
8
|
loadEnv
|
|
9
9
|
} from "./chunk-2CR762KB.js";
|
|
10
10
|
import {
|
|
11
11
|
createApiClient
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-JMRD5WIY.js";
|
|
13
13
|
import {
|
|
14
14
|
findProjectRoot,
|
|
15
15
|
getApiUrl,
|
package/dist/index.js
CHANGED
|
@@ -219,39 +219,39 @@ async function main() {
|
|
|
219
219
|
switch (command) {
|
|
220
220
|
// Resource commands
|
|
221
221
|
case "plan":
|
|
222
|
-
await import("./resources-
|
|
222
|
+
await import("./resources-Z5ZMPWTK.js").then((m) => m.plan(args.slice(1)));
|
|
223
223
|
break;
|
|
224
224
|
case "apply":
|
|
225
|
-
await import("./resources-
|
|
225
|
+
await import("./resources-Z5ZMPWTK.js").then((m) => m.apply(args.slice(1)));
|
|
226
226
|
break;
|
|
227
227
|
case "pull":
|
|
228
|
-
await import("./resources-
|
|
228
|
+
await import("./resources-Z5ZMPWTK.js").then((m) => m.pull(args.slice(1)));
|
|
229
229
|
break;
|
|
230
230
|
case "destroy":
|
|
231
|
-
await import("./resources-
|
|
231
|
+
await import("./resources-Z5ZMPWTK.js").then((m) => m.destroy(args.slice(1)));
|
|
232
232
|
break;
|
|
233
233
|
case "list":
|
|
234
|
-
await import("./resources-
|
|
234
|
+
await import("./resources-Z5ZMPWTK.js").then((m) => m.list(args.slice(1)));
|
|
235
235
|
break;
|
|
236
236
|
case "show":
|
|
237
|
-
await import("./resources-
|
|
237
|
+
await import("./resources-Z5ZMPWTK.js").then((m) => m.show(args.slice(1)));
|
|
238
238
|
break;
|
|
239
239
|
case "diff":
|
|
240
|
-
await import("./resources-
|
|
240
|
+
await import("./resources-Z5ZMPWTK.js").then((m) => m.diff(args.slice(1)));
|
|
241
241
|
break;
|
|
242
242
|
// Development
|
|
243
243
|
case "dev":
|
|
244
|
-
await import("./dev-
|
|
244
|
+
await import("./dev-EQK27BUM.js").then((m) => m.dev(args.slice(1)));
|
|
245
245
|
break;
|
|
246
246
|
case "run":
|
|
247
|
-
await import("./run-
|
|
247
|
+
await import("./run-LHHX7UBN.js").then((m) => m.run(args.slice(1)));
|
|
248
248
|
break;
|
|
249
249
|
// Project
|
|
250
250
|
case "init":
|
|
251
|
-
await import("./init-
|
|
251
|
+
await import("./init-UF4JYQSQ.js").then((m) => m.init(args.slice(1)));
|
|
252
252
|
break;
|
|
253
253
|
case "register":
|
|
254
|
-
await import("./register-
|
|
254
|
+
await import("./register-BQCVUPWS.js").then((m) => m.register(args.slice(1)));
|
|
255
255
|
break;
|
|
256
256
|
case "templates":
|
|
257
257
|
await import("./templates-LNUOTNLN.js").then((m) => m.templates(subcommand, args.slice(2)));
|
|
@@ -268,7 +268,7 @@ async function main() {
|
|
|
268
268
|
break;
|
|
269
269
|
// Dependencies
|
|
270
270
|
case "deps":
|
|
271
|
-
await import("./deps-
|
|
271
|
+
await import("./deps-VTLXKCQ7.js").then((m) => m.deps(args.slice(1)));
|
|
272
272
|
break;
|
|
273
273
|
// Auth
|
|
274
274
|
case "login":
|
|
@@ -6,8 +6,9 @@ import {
|
|
|
6
6
|
spinner
|
|
7
7
|
} from "./chunk-BHYDYR75.js";
|
|
8
8
|
import {
|
|
9
|
-
createApiClient
|
|
10
|
-
|
|
9
|
+
createApiClient,
|
|
10
|
+
validateProjectNameLength
|
|
11
|
+
} from "./chunk-JMRD5WIY.js";
|
|
11
12
|
import {
|
|
12
13
|
getToken,
|
|
13
14
|
init_auth,
|
|
@@ -280,6 +281,8 @@ async function init(args) {
|
|
|
280
281
|
initial: "my-app",
|
|
281
282
|
validate: (value) => {
|
|
282
283
|
if (!value) return "Project name is required";
|
|
284
|
+
const lengthError = validateProjectNameLength(value, "Project name");
|
|
285
|
+
if (lengthError) return lengthError;
|
|
283
286
|
if (!/^[a-z0-9-]+$/.test(value)) {
|
|
284
287
|
return "Use lowercase letters, numbers, and hyphens only";
|
|
285
288
|
}
|
|
@@ -301,6 +304,11 @@ async function init(args) {
|
|
|
301
304
|
console.log(pc.red(" Error: Project name must use lowercase letters, numbers, and hyphens only"));
|
|
302
305
|
process.exit(1);
|
|
303
306
|
}
|
|
307
|
+
const projectNameLengthError = validateProjectNameLength(finalProjectName, "Project name");
|
|
308
|
+
if (projectNameLengthError) {
|
|
309
|
+
console.log(pc.red(` Error: ${projectNameLengthError}`));
|
|
310
|
+
process.exit(1);
|
|
311
|
+
}
|
|
304
312
|
if (!directory) {
|
|
305
313
|
if (nonInteractive) {
|
|
306
314
|
directory = finalProjectName;
|
|
@@ -5,8 +5,9 @@ import {
|
|
|
5
5
|
spinner
|
|
6
6
|
} from "./chunk-BHYDYR75.js";
|
|
7
7
|
import {
|
|
8
|
-
createApiClient
|
|
9
|
-
|
|
8
|
+
createApiClient,
|
|
9
|
+
validateProjectExternalId
|
|
10
|
+
} from "./chunk-JMRD5WIY.js";
|
|
10
11
|
import {
|
|
11
12
|
findProjectRoot,
|
|
12
13
|
getAppName,
|
|
@@ -45,6 +46,11 @@ async function register(args) {
|
|
|
45
46
|
const projectRoot = findProjectRoot();
|
|
46
47
|
loadEnv(projectRoot);
|
|
47
48
|
const appName = getAppName(projectRoot);
|
|
49
|
+
const appNameError = validateProjectExternalId(appName);
|
|
50
|
+
if (appNameError) {
|
|
51
|
+
console.error(pc.red(` ${appNameError}`));
|
|
52
|
+
process.exit(1);
|
|
53
|
+
}
|
|
48
54
|
const existingId = getProjectId(projectRoot);
|
|
49
55
|
if (existingId && !force) {
|
|
50
56
|
console.log();
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import {
|
|
2
2
|
deploy
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-XT4EGGK7.js";
|
|
4
4
|
import {
|
|
5
5
|
syncDeps
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-RH4FQF6O.js";
|
|
7
7
|
import {
|
|
8
8
|
loadEnv
|
|
9
9
|
} from "./chunk-2CR762KB.js";
|
|
10
10
|
import {
|
|
11
11
|
ApiError,
|
|
12
|
-
createApiClient
|
|
13
|
-
|
|
12
|
+
createApiClient,
|
|
13
|
+
validateCollectionNameLength
|
|
14
|
+
} from "./chunk-JMRD5WIY.js";
|
|
14
15
|
import {
|
|
15
16
|
findProjectRoot,
|
|
16
17
|
getApiUrl,
|
|
@@ -1261,6 +1262,11 @@ function loadLocalCollections(platformDir, filterName) {
|
|
|
1261
1262
|
errors.push(`${file}: missing name field`);
|
|
1262
1263
|
continue;
|
|
1263
1264
|
}
|
|
1265
|
+
const collectionNameError = validateCollectionNameLength(collection.name);
|
|
1266
|
+
if (collectionNameError) {
|
|
1267
|
+
errors.push(`${file}: ${collectionNameError}`);
|
|
1268
|
+
continue;
|
|
1269
|
+
}
|
|
1264
1270
|
if (/\s/.test(collection.name)) {
|
|
1265
1271
|
errors.push(`${file}: collection name "${collection.name}" contains spaces - use underscores instead`);
|
|
1266
1272
|
continue;
|
package/package.json
CHANGED
|
@@ -12,8 +12,8 @@ importers:
|
|
|
12
12
|
.:
|
|
13
13
|
dependencies:
|
|
14
14
|
'@lumerahq/ui':
|
|
15
|
-
specifier: ^0.
|
|
16
|
-
version: 0.
|
|
15
|
+
specifier: ^0.10.0
|
|
16
|
+
version: 0.10.0(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
|
|
17
17
|
'@tanstack/react-query':
|
|
18
18
|
specifier: ^5.90.11
|
|
19
19
|
version: 5.101.0(react@19.2.7)
|
|
@@ -457,8 +457,8 @@ packages:
|
|
|
457
457
|
'@jridgewell/trace-mapping@0.3.31':
|
|
458
458
|
resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==}
|
|
459
459
|
|
|
460
|
-
'@lumerahq/ui@0.
|
|
461
|
-
resolution: {integrity: sha512-
|
|
460
|
+
'@lumerahq/ui@0.10.0':
|
|
461
|
+
resolution: {integrity: sha512-dWz7J9jXJBtHiAy7SFWWWhsoLOQ8TXVu7/FWvkW3wIkeTWRUdDreIaYIrOhpnvkH+PrTafiLGybSGrLQP+knSw==}
|
|
462
462
|
peerDependencies:
|
|
463
463
|
react: ^18.0.0 || ^19.0.0
|
|
464
464
|
react-dom: ^18.0.0 || ^19.0.0
|
|
@@ -2311,7 +2311,7 @@ snapshots:
|
|
|
2311
2311
|
'@jridgewell/resolve-uri': 3.1.2
|
|
2312
2312
|
'@jridgewell/sourcemap-codec': 1.5.5
|
|
2313
2313
|
|
|
2314
|
-
'@lumerahq/ui@0.
|
|
2314
|
+
'@lumerahq/ui@0.10.0(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)':
|
|
2315
2315
|
dependencies:
|
|
2316
2316
|
'@base-ui/react': 1.5.0(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
|
|
2317
2317
|
'@tanstack/react-query': 5.101.0(react@19.2.7)
|