@holo-js/cli 0.1.4 → 0.1.5
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/holo.mjs +192 -35
- package/dist/{broadcast-CSSARTSA.mjs → broadcast-RT5KVZWP.mjs} +5 -5
- package/dist/{cache-4G6QGIZO.mjs → cache-NHCCHT44.mjs} +5 -5
- package/dist/{cache-migrations-NATT5WPQ.mjs → cache-migrations-R2RL2RVD.mjs} +15 -16
- package/dist/{chunk-EUIVXVJL.mjs → chunk-57SJ566R.mjs} +1 -1
- package/dist/chunk-5BLEC66P.mjs +284 -0
- package/dist/{chunk-JX2ZH6XY.mjs → chunk-5EU32E7X.mjs} +3 -3
- package/dist/{chunk-Q5F6C2D4.mjs → chunk-BAFQ2GOA.mjs} +1 -1
- package/dist/{chunk-CUL4RJTG.mjs → chunk-F4MT6GBK.mjs} +1 -1
- package/dist/{chunk-3OTCSFDG.mjs → chunk-MXKNQACM.mjs} +544 -82
- package/dist/{chunk-QYLSMF7V.mjs → chunk-OZUDZEAW.mjs} +142 -28
- package/dist/{chunk-66FHW725.mjs → chunk-R6BWRY3E.mjs} +28 -2
- package/dist/{chunk-ZLRO7HXY.mjs → chunk-SCCPDJGO.mjs} +156 -15
- package/dist/{chunk-VT5IDQG6.mjs → chunk-UZTDQKIY.mjs} +61 -44
- package/dist/{chunk-MZXN2YMI.mjs → chunk-VCEO6N5T.mjs} +3542 -2517
- package/dist/{config-LS5USBRB.mjs → config-5JSC6KJG.mjs} +3 -3
- package/dist/{dev-LZ3O2E3U.mjs → dev-OSLYSBTL.mjs} +7 -7
- package/dist/{discovery-GBLAUTXS.mjs → discovery-JLT2EOGH.mjs} +3 -3
- package/dist/{generators-DSN4GWJI.mjs → generators-ZIWACCBE.mjs} +134 -16
- package/dist/index.d.ts +1 -1
- package/dist/index.mjs +189 -32
- package/dist/media-migrations-UBAL2YVV.mjs +117 -0
- package/dist/{queue-FV35LLPR.mjs → queue-I66EISVS.mjs} +14 -14
- package/dist/{queue-migrations-SSIYKK5S.mjs → queue-migrations-UIAMAB6E.mjs} +24 -20
- package/dist/{runtime-EFZ5H5IL.mjs → runtime-MMQGO4PP.mjs} +9 -7
- package/dist/{runtime-OOSJ5JBY.mjs → runtime-ZKD6URAV.mjs} +1 -1
- package/dist/{scaffold-7OTDH4UR.mjs → scaffold-ISDVICNQ.mjs} +18 -5
- package/dist/{security-ATKDC26E.mjs → security-OZXTMYXF.mjs} +10 -7
- package/package.json +13 -12
- package/dist/broadcast-YSIJCL3R.mjs +0 -85
- package/dist/cache-OWQY4E7W.mjs +0 -67
- package/dist/cache-migrations-RVEA6CEU.mjs +0 -155
- package/dist/chunk-BWW5TDFI.mjs +0 -4
- package/dist/chunk-D4GG556Y.mjs +0 -23
- package/dist/chunk-DMH2B4UQ.mjs +0 -343
- package/dist/chunk-ET7UXHHQ.mjs +0 -166
- package/dist/chunk-G5ADO27Q.mjs +0 -463
- package/dist/chunk-GSQ3HTRO.mjs +0 -165
- package/dist/chunk-H7TJ4FB3.mjs +0 -848
- package/dist/chunk-ICJR7TS4.mjs +0 -66
- package/dist/chunk-M7J3YTHR.mjs +0 -26
- package/dist/chunk-QFUSWV3J.mjs +0 -3237
- package/dist/chunk-S7P7EBM3.mjs +0 -787
- package/dist/chunk-SRWJU3A5.mjs +0 -11
- package/dist/chunk-URK7C3VQ.mjs +0 -538
- package/dist/chunk-XUYKPU5Q.mjs +0 -272
- package/dist/config-DMWBMMGD.mjs +0 -26
- package/dist/dev-KQFT7RHR.mjs +0 -43
- package/dist/discovery-R733D2PO.mjs +0 -29
- package/dist/generators-WX45BI4U.mjs +0 -426
- package/dist/queue-6OG7VJ34.mjs +0 -626
- package/dist/queue-migrations-NK2EYX3J.mjs +0 -163
- package/dist/runtime-4BV3JODY.mjs +0 -56
- package/dist/runtime-ANBO7VQM.mjs +0 -33
- package/dist/scaffold-DRKBGS2K.mjs +0 -120
- package/dist/security-R7VH6W5H.mjs +0 -69
|
@@ -7,11 +7,11 @@ import {
|
|
|
7
7
|
serializeDatabaseConfig,
|
|
8
8
|
serializeProjectConfig,
|
|
9
9
|
writeProjectConfig
|
|
10
|
-
} from "./chunk-
|
|
11
|
-
import "./chunk-
|
|
10
|
+
} from "./chunk-5BLEC66P.mjs";
|
|
11
|
+
import "./chunk-MXKNQACM.mjs";
|
|
12
12
|
import {
|
|
13
13
|
readTextFile
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-R6BWRY3E.mjs";
|
|
15
15
|
export {
|
|
16
16
|
defaultProjectConfig,
|
|
17
17
|
ensureGeneratedSchemaPlaceholder,
|
|
@@ -13,16 +13,16 @@ import {
|
|
|
13
13
|
runProjectLifecycleScript,
|
|
14
14
|
runProjectPrepare,
|
|
15
15
|
toPosixSlashes
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-SCCPDJGO.mjs";
|
|
17
17
|
import {
|
|
18
18
|
hasProjectDependency
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-F4MT6GBK.mjs";
|
|
20
20
|
import "./chunk-D7O4SU6N.mjs";
|
|
21
|
-
import "./chunk-
|
|
22
|
-
import "./chunk-
|
|
23
|
-
import "./chunk-
|
|
24
|
-
import "./chunk-
|
|
25
|
-
import "./chunk-
|
|
21
|
+
import "./chunk-UZTDQKIY.mjs";
|
|
22
|
+
import "./chunk-VCEO6N5T.mjs";
|
|
23
|
+
import "./chunk-5BLEC66P.mjs";
|
|
24
|
+
import "./chunk-MXKNQACM.mjs";
|
|
25
|
+
import "./chunk-R6BWRY3E.mjs";
|
|
26
26
|
export {
|
|
27
27
|
collectDirectoryTree,
|
|
28
28
|
collectDiscoveryWatchRoots,
|
|
@@ -10,9 +10,9 @@ import {
|
|
|
10
10
|
resolveListenerEventNamesFromSource,
|
|
11
11
|
resolveNamedExport,
|
|
12
12
|
resolveNamedExportEntry
|
|
13
|
-
} from "./chunk-
|
|
14
|
-
import "./chunk-
|
|
15
|
-
import "./chunk-
|
|
13
|
+
} from "./chunk-UZTDQKIY.mjs";
|
|
14
|
+
import "./chunk-MXKNQACM.mjs";
|
|
15
|
+
import "./chunk-R6BWRY3E.mjs";
|
|
16
16
|
export {
|
|
17
17
|
collectImportedBindingsBySource,
|
|
18
18
|
discoverAppCommands,
|
|
@@ -1,31 +1,32 @@
|
|
|
1
|
+
import {
|
|
2
|
+
resolveStringFlag
|
|
3
|
+
} from "./chunk-5EU32E7X.mjs";
|
|
4
|
+
import {
|
|
5
|
+
runProjectPrepare
|
|
6
|
+
} from "./chunk-SCCPDJGO.mjs";
|
|
7
|
+
import "./chunk-F4MT6GBK.mjs";
|
|
1
8
|
import {
|
|
2
9
|
hasRegisteredCreateTableMigration,
|
|
3
10
|
hasRegisteredMigrationSlug,
|
|
4
11
|
nextMigrationTemplate
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import {
|
|
7
|
-
resolveStringFlag
|
|
8
|
-
} from "./chunk-JX2ZH6XY.mjs";
|
|
12
|
+
} from "./chunk-BAFQ2GOA.mjs";
|
|
9
13
|
import {
|
|
10
14
|
writeLine
|
|
11
15
|
} from "./chunk-ZXDU7RHU.mjs";
|
|
12
16
|
import {
|
|
13
17
|
ensureAbsent,
|
|
14
18
|
fileExists
|
|
15
|
-
} from "./chunk-
|
|
16
|
-
import {
|
|
17
|
-
runProjectPrepare
|
|
18
|
-
} from "./chunk-ZLRO7HXY.mjs";
|
|
19
|
-
import "./chunk-CUL4RJTG.mjs";
|
|
19
|
+
} from "./chunk-57SJ566R.mjs";
|
|
20
20
|
import "./chunk-D7O4SU6N.mjs";
|
|
21
21
|
import {
|
|
22
|
+
collectFiles,
|
|
22
23
|
prepareProjectDiscovery
|
|
23
|
-
} from "./chunk-
|
|
24
|
-
import "./chunk-
|
|
24
|
+
} from "./chunk-UZTDQKIY.mjs";
|
|
25
|
+
import "./chunk-VCEO6N5T.mjs";
|
|
25
26
|
import {
|
|
26
27
|
ensureGeneratedSchemaPlaceholder,
|
|
27
28
|
ensureProjectConfig
|
|
28
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-5BLEC66P.mjs";
|
|
29
30
|
import {
|
|
30
31
|
ensureSuffix,
|
|
31
32
|
loadGeneratedProjectRegistry,
|
|
@@ -47,22 +48,127 @@ import {
|
|
|
47
48
|
toKebabCase,
|
|
48
49
|
toPascalCase,
|
|
49
50
|
toSnakeCase
|
|
50
|
-
} from "./chunk-
|
|
51
|
+
} from "./chunk-MXKNQACM.mjs";
|
|
51
52
|
import {
|
|
52
53
|
makeProjectRelativePath,
|
|
53
54
|
resolveDefaultArtifactPath,
|
|
54
55
|
writeTextFile
|
|
55
|
-
} from "./chunk-
|
|
56
|
+
} from "./chunk-R6BWRY3E.mjs";
|
|
56
57
|
|
|
57
58
|
// src/generators.ts
|
|
58
59
|
import { createHash } from "crypto";
|
|
59
60
|
import { readFile } from "fs/promises";
|
|
60
|
-
import { resolve } from "path";
|
|
61
|
+
import { basename, extname, resolve } from "path";
|
|
61
62
|
import { normalizeMigrationSlug } from "@holo-js/db";
|
|
62
63
|
var MAIL_VIEW_SCAFFOLDING_UNAVAILABLE_MESSAGE = 'View-backed mail scaffolding requires a renderView runtime binding, which the first-party app scaffolds do not configure yet. Use "--markdown" instead.';
|
|
63
64
|
function hasRegisteredModelName(registry, modelName) {
|
|
64
65
|
return Boolean(registry?.models.some((entry) => entry.name === modelName));
|
|
65
66
|
}
|
|
67
|
+
function findRegisteredModelByTableName(registry, tableName) {
|
|
68
|
+
return registry?.models.find((entry) => entry.tableName === tableName);
|
|
69
|
+
}
|
|
70
|
+
async function findGeneratedModelSourceByTableName(projectRoot, modelsPath, tableName) {
|
|
71
|
+
const files = await collectFiles(resolve(projectRoot, modelsPath));
|
|
72
|
+
const generatedTableReference = tableName;
|
|
73
|
+
for (const filePath of files) {
|
|
74
|
+
const contents = await readFile(filePath, "utf8");
|
|
75
|
+
if (containsDefineModelTableReference(contents, generatedTableReference)) {
|
|
76
|
+
return basename(filePath, extname(filePath));
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return void 0;
|
|
80
|
+
}
|
|
81
|
+
function containsDefineModelTableReference(contents, tableName) {
|
|
82
|
+
let index = 0;
|
|
83
|
+
while (index < contents.length) {
|
|
84
|
+
const nextReference = contents.indexOf("defineModel", index);
|
|
85
|
+
if (nextReference === -1) return false;
|
|
86
|
+
if (isInsideComment(contents, nextReference)) {
|
|
87
|
+
index = nextReference + "defineModel".length;
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
const before = contents[nextReference - 1];
|
|
91
|
+
const after = contents[nextReference + "defineModel".length];
|
|
92
|
+
const hasIdentifierBoundary = !isIdentifierCharacter(before) && !isIdentifierCharacter(after);
|
|
93
|
+
if (!hasIdentifierBoundary) {
|
|
94
|
+
index = nextReference + "defineModel".length;
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
const openParenIndex = skipWhitespace(contents, nextReference + "defineModel".length);
|
|
98
|
+
if (contents[openParenIndex] !== "(") {
|
|
99
|
+
index = nextReference + "defineModel".length;
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
const firstArgumentIndex = skipWhitespace(contents, openParenIndex + 1);
|
|
103
|
+
const quote = contents[firstArgumentIndex];
|
|
104
|
+
if (quote !== "'" && quote !== '"' && quote !== "`") {
|
|
105
|
+
index = firstArgumentIndex;
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
const literal = readStringLiteral(contents, firstArgumentIndex, quote);
|
|
109
|
+
if (literal?.value === tableName) return true;
|
|
110
|
+
index = literal?.endIndex ?? firstArgumentIndex + 1;
|
|
111
|
+
}
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
function isInsideComment(contents, position) {
|
|
115
|
+
let index = 0;
|
|
116
|
+
while (index < position) {
|
|
117
|
+
const current = contents[index];
|
|
118
|
+
const next = contents[index + 1];
|
|
119
|
+
if (current === "'" || current === '"' || current === "`") {
|
|
120
|
+
index = readStringLiteral(contents, index, current)?.endIndex ?? index + 1;
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
if (current === "/" && next === "/") {
|
|
124
|
+
const end = contents.indexOf("\n", index + 2);
|
|
125
|
+
if (end === -1 || end >= position) return true;
|
|
126
|
+
index = end + 1;
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
if (current === "/" && next === "*") {
|
|
130
|
+
const end = contents.indexOf("*/", index + 2);
|
|
131
|
+
if (end === -1 || end + 2 >= position) return true;
|
|
132
|
+
index = end + 2;
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
135
|
+
index += 1;
|
|
136
|
+
}
|
|
137
|
+
return false;
|
|
138
|
+
}
|
|
139
|
+
function isIdentifierCharacter(value) {
|
|
140
|
+
return typeof value === "string" && /[$\w]/.test(value);
|
|
141
|
+
}
|
|
142
|
+
function skipWhitespace(contents, startIndex) {
|
|
143
|
+
let index = startIndex;
|
|
144
|
+
while (/\s/.test(contents[index] ?? "")) {
|
|
145
|
+
index += 1;
|
|
146
|
+
}
|
|
147
|
+
return index;
|
|
148
|
+
}
|
|
149
|
+
function readStringLiteral(contents, startIndex, quote) {
|
|
150
|
+
let value = "";
|
|
151
|
+
let index = startIndex + 1;
|
|
152
|
+
while (index < contents.length) {
|
|
153
|
+
const current = contents[index];
|
|
154
|
+
if (current === "\\") {
|
|
155
|
+
const escaped = contents[index + 1];
|
|
156
|
+
if (typeof escaped === "string") {
|
|
157
|
+
value += escaped;
|
|
158
|
+
index += 2;
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
if (current === quote) {
|
|
163
|
+
return { value, endIndex: index + 1 };
|
|
164
|
+
}
|
|
165
|
+
if (typeof current === "string") {
|
|
166
|
+
value += current;
|
|
167
|
+
}
|
|
168
|
+
index += 1;
|
|
169
|
+
}
|
|
170
|
+
return void 0;
|
|
171
|
+
}
|
|
66
172
|
function hasRegisteredJobName(registry, jobName) {
|
|
67
173
|
return Boolean(registry?.jobs.some((entry) => entry.name === jobName));
|
|
68
174
|
}
|
|
@@ -128,6 +234,7 @@ async function resolveProjectMailViewFramework(projectRoot) {
|
|
|
128
234
|
}
|
|
129
235
|
async function runMakeModel(io, projectRoot, input) {
|
|
130
236
|
const project = await ensureProjectConfig(projectRoot);
|
|
237
|
+
const generatedSchemaFilePath = await ensureGeneratedSchemaPlaceholder(projectRoot, project.config);
|
|
131
238
|
const registry = await loadGeneratedProjectRegistry(projectRoot) ?? await prepareProjectDiscovery(projectRoot, project.config);
|
|
132
239
|
const requestedName = String(input.args[0] ?? "");
|
|
133
240
|
const options = {
|
|
@@ -146,7 +253,6 @@ async function runMakeModel(io, projectRoot, input) {
|
|
|
146
253
|
const seederFilePath = resolveArtifactPath(projectRoot, project.config.paths.seeders, seederInfo.directory, `${seederInfo.baseName}.ts`);
|
|
147
254
|
const factoryInfo = resolveNameInfo(`${requestedName}Factory`, { suffix: "Factory" });
|
|
148
255
|
const factoryFilePath = resolveArtifactPath(projectRoot, project.config.paths.factories, factoryInfo.directory, `${factoryInfo.baseName}.ts`);
|
|
149
|
-
const generatedSchemaFilePath = await ensureGeneratedSchemaPlaceholder(projectRoot, project.config);
|
|
150
256
|
if (await fileExists(modelFilePath) || hasRegisteredModelName(registry, nameInfo.baseName)) {
|
|
151
257
|
throw new Error(`Model with the same name already exists: ${nameInfo.baseName}.`);
|
|
152
258
|
}
|
|
@@ -156,6 +262,18 @@ async function runMakeModel(io, projectRoot, input) {
|
|
|
156
262
|
throw new Error(`A migration for table "${tableName}" already exists.`);
|
|
157
263
|
}
|
|
158
264
|
}
|
|
265
|
+
const existingTableModel = findRegisteredModelByTableName(registry, tableName);
|
|
266
|
+
if (existingTableModel) {
|
|
267
|
+
throw new Error(`Discovered duplicate model "${existingTableModel.name}" for table "${tableName}".`);
|
|
268
|
+
}
|
|
269
|
+
const existingGeneratedModelName = await findGeneratedModelSourceByTableName(
|
|
270
|
+
projectRoot,
|
|
271
|
+
project.config.paths.models,
|
|
272
|
+
tableName
|
|
273
|
+
);
|
|
274
|
+
if (existingGeneratedModelName) {
|
|
275
|
+
throw new Error(`Discovered duplicate model "${existingGeneratedModelName}" for table "${tableName}".`);
|
|
276
|
+
}
|
|
159
277
|
await ensureAbsent(modelFilePath);
|
|
160
278
|
if (options.observer) {
|
|
161
279
|
await ensureAbsent(observerFilePath);
|
package/dist/index.d.ts
CHANGED
|
@@ -19,7 +19,7 @@ interface HoloAppCommand {
|
|
|
19
19
|
readonly usage?: string;
|
|
20
20
|
run(context: CommandExecutionContext): unknown | Promise<unknown>;
|
|
21
21
|
}
|
|
22
|
-
declare function defineCommand
|
|
22
|
+
declare function defineCommand(command: HoloAppCommand): Readonly<HoloAppCommand>;
|
|
23
23
|
|
|
24
24
|
type IoStreams = {
|
|
25
25
|
readonly cwd: string;
|