qubu 0.0.0 → 0.3.3
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/canonical-BbnqavJm.mjs +972 -0
- package/dist/codegen.d.mts +107 -0
- package/dist/codegen.mjs +1199 -0
- package/dist/column-CXMxx8Hq.mjs +118 -0
- package/dist/complete-D5Djh-zo.mjs +1788 -0
- package/dist/complete-types-BdFqUfbb.d.mts +371 -0
- package/dist/core.d.mts +33 -0
- package/dist/core.mjs +36 -0
- package/dist/ddl.d.mts +118 -0
- package/dist/ddl.mjs +1120 -0
- package/dist/dialect-b2-Z6uBF.mjs +13 -0
- package/dist/diff.d.mts +2 -0
- package/dist/diff.mjs +883 -0
- package/dist/drizzle-mysql.d.mts +24 -0
- package/dist/drizzle-mysql.mjs +72 -0
- package/dist/drizzle-postgres.d.mts +24 -0
- package/dist/drizzle-postgres.mjs +73 -0
- package/dist/drizzle-sqlite.d.mts +24 -0
- package/dist/drizzle-sqlite.mjs +82 -0
- package/dist/drizzle.d.mts +13 -0
- package/dist/drizzle.mjs +2 -0
- package/dist/errors-BGCoLe_r.mjs +14 -0
- package/dist/errors-Dxv73YJu.mjs +26 -0
- package/dist/explain-CkIK13L_.mjs +98 -0
- package/dist/index-Ds7-mhJi.d.mts +146 -0
- package/dist/index-Dug5HnLB.d.mts +204 -0
- package/dist/index.d.mts +2 -0
- package/dist/index.mjs +1276 -0
- package/dist/introspection.d.mts +117 -0
- package/dist/introspection.mjs +4341 -0
- package/dist/json-CUZlv4HT.mjs +169 -0
- package/dist/migration.d.mts +215 -0
- package/dist/migration.mjs +1161 -0
- package/dist/mysql-DqkqXB6A.mjs +355 -0
- package/dist/mysql.d.mts +5 -0
- package/dist/mysql.mjs +50 -0
- package/dist/naming-QVCOnSj2.mjs +20 -0
- package/dist/omit-OxV58AwX.mjs +5 -0
- package/dist/on-conflict-BxnxubMb.mjs +143 -0
- package/dist/postgres-DEBBeh52.mjs +235 -0
- package/dist/postgres.d.mts +123 -0
- package/dist/postgres.mjs +52 -0
- package/dist/registry-BufIskVN.mjs +569 -0
- package/dist/relational-DCZrrNia.mjs +77 -0
- package/dist/runtime-BTr-MTlo.mjs +193 -0
- package/dist/schema.d.mts +2 -0
- package/dist/schema.mjs +5 -0
- package/dist/serialize-PF1cfH2P.mjs +556 -0
- package/dist/snapshot-CWPgzxNx.mjs +392 -0
- package/dist/snapshot.d.mts +4 -0
- package/dist/snapshot.mjs +8 -0
- package/dist/source-DUoJVXmL.mjs +68 -0
- package/dist/sqlite-BU6DBxef.mjs +320 -0
- package/dist/sqlite.d.mts +5 -0
- package/dist/sqlite.mjs +48 -0
- package/dist/standard-BTVYKh_F.mjs +12 -0
- package/dist/table-llv9tsZ8.mjs +384 -0
- package/dist/types-4Q076HKo.d.mts +3636 -0
- package/dist/types-BX0mckiU.d.mts +644 -0
- package/dist/types-CO1KaRNc.d.mts +46 -0
- package/dist/types-Cec0xzo4.mjs +116 -0
- package/dist/value-BvilP0oz.mjs +29 -0
- package/dist/vite/ambient.d.ts +449 -0
- package/dist/vite.d.mts +35 -0
- package/dist/vite.mjs +498 -0
- package/docs/config.json +21 -0
- package/docs/dialects-and-execution.md +427 -0
- package/docs/getting-started.md +96 -0
- package/docs/guides/compose-queries.md +225 -0
- package/docs/guides/drizzle.md +129 -0
- package/docs/guides/extensions/dialects.md +40 -0
- package/docs/guides/extensions/overview.md +36 -0
- package/docs/guides/extensions/sources-and-clauses.md +82 -0
- package/docs/guides/extensions/typed-expressions.md +94 -0
- package/docs/guides/extensions/unsafe-syntax.md +27 -0
- package/docs/guides/json.md +65 -0
- package/docs/guides/mutations.md +138 -0
- package/docs/guides/select/conditions.md +110 -0
- package/docs/guides/select/grouping-and-windows.md +82 -0
- package/docs/guides/select/ordering-and-pagination.md +78 -0
- package/docs/guides/select/overview.md +139 -0
- package/docs/guides/sql-templates.md +157 -0
- package/docs/guides/vite-plugin.md +92 -0
- package/docs/index.md +111 -0
- package/docs/query-model/fragments.md +109 -0
- package/docs/query-model/result-shapes.md +125 -0
- package/docs/query-model/source-scope.md +182 -0
- package/docs/reference/introspection-support.md +196 -0
- package/docs/reference/mysql-snapshot.md +55 -0
- package/docs/reference/postgres-snapshot.md +61 -0
- package/docs/reference/sqlite-snapshot.md +53 -0
- package/docs/reference/supported-surface.md +104 -0
- package/docs/schema/catalog-model.md +58 -0
- package/docs/schema/code-generation.md +139 -0
- package/docs/schema/columns-and-writes.md +130 -0
- package/docs/schema/constraints-and-indexes.md +180 -0
- package/docs/schema/ddl-emission.md +75 -0
- package/docs/schema/diff.md +75 -0
- package/docs/schema/introspection.md +214 -0
- package/docs/schema/migration-plans.md +76 -0
- package/docs/schema/snapshots.md +93 -0
- package/docs/schema/storage-and-schema-sql.md +104 -0
- package/docs/schema/tables-and-names.md +106 -0
- package/docs/sql-semantic-types.md +141 -0
- package/docs/troubleshooting.md +151 -0
- package/package.json +132 -10
- package/skills/qubu/SKILL.md +42 -0
- package/skills/qubu/agents/openai.yaml +6 -0
- package/readme.md +0 -1
package/dist/vite.d.mts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
//#region src/vite/globals.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Public runtime names that the `"use qubu"` transform can auto-import.
|
|
4
|
+
* Keep this catalog aligned with the ordinary authoring surface of `qubu`;
|
|
5
|
+
* fragment internals, dialect construction, and schema extensions belong to
|
|
6
|
+
* the layered entrypoints.
|
|
7
|
+
*/
|
|
8
|
+
declare const qubuGlobals: readonly ["add", "alias", "all", "allowAll", "and", "asc", "asValue", "avg", "bigint", "between", "binary", "boolean", "call", "caseWhen", "cast", "check", "coalesce", "column", "concat", "count", "countDistinct", "correlate", "crossJoin", "cte", "date", "denseRank", "defaultValues", "deleteFrom", "desc", "distinct", "divide", "eq", "except", "execute", "executeRows", "externalDefault", "externalGeneratedColumn", "exists", "fetchFirst", "fetchNext", "foreignKey", "from", "fullJoin", "generatedColumn", "gt", "gte", "groupBy", "having", "identityColumn", "inList", "inQuery", "index", "innerJoin", "insertInto", "insertSelect", "integer", "intersect", "isDistinctFrom", "isNotDistinctFrom", "isNotNull", "isNull", "isTrue", "json", "jsonBoolean", "jsonExists", "jsonNumber", "jsonPath", "jsonText", "lateral", "leftJoin", "like", "lower", "lt", "lte", "max", "min", "modulo", "multiply", "naturalJoin", "nativeColumn", "nativeStorage", "ne", "not", "notExists", "notIn", "notLike", "nullsFirst", "nullsLast", "numeric", "nullable", "offset", "omit", "or", "order", "orderBy", "over", "portableStorage", "primaryKey", "qubu", "references", "recursiveCte", "render", "returning", "rightJoin", "rank", "rowNumber", "scalar", "schema", "schemaCall", "select", "sql", "stream", "subtract", "sum", "table", "text", "timestamp", "union", "unionAll", "unique", "uniqueConstraint", "update", "upper", "value", "values", "where", "withCte", "uuid"];
|
|
9
|
+
type QubuGlobal = (typeof qubuGlobals)[number];
|
|
10
|
+
//#endregion
|
|
11
|
+
//#region src/vite/index.d.ts
|
|
12
|
+
interface QubuVitePluginOptions {
|
|
13
|
+
/** Module specifier used for injected imports. @default "qubu" */
|
|
14
|
+
readonly module?: string;
|
|
15
|
+
/** Restrict transformation to matching module IDs. */
|
|
16
|
+
readonly include?: RegExp | ((id: string) => boolean);
|
|
17
|
+
/** Exclude matching module IDs. */
|
|
18
|
+
readonly exclude?: RegExp | ((id: string) => boolean);
|
|
19
|
+
/** Override the auto-importable public Qubu names. */
|
|
20
|
+
readonly globals?: readonly QubuGlobal[];
|
|
21
|
+
}
|
|
22
|
+
interface QubuViteTransformResult {
|
|
23
|
+
readonly code: string;
|
|
24
|
+
readonly map: null;
|
|
25
|
+
}
|
|
26
|
+
/** A Vite-compatible plugin without a runtime dependency on Vite itself. */
|
|
27
|
+
interface QubuVitePlugin {
|
|
28
|
+
readonly name: 'qubu:compiler-hint';
|
|
29
|
+
readonly enforce: 'pre';
|
|
30
|
+
transform(code: string, id: string): QubuViteTransformResult | null;
|
|
31
|
+
}
|
|
32
|
+
declare function qubu(options?: QubuVitePluginOptions): QubuVitePlugin;
|
|
33
|
+
declare const qubuVitePlugin: typeof qubu;
|
|
34
|
+
//#endregion
|
|
35
|
+
export { type QubuGlobal, QubuVitePlugin, QubuVitePluginOptions, QubuViteTransformResult, qubu as default, qubu, qubuGlobals, qubuVitePlugin };
|
package/dist/vite.mjs
ADDED
|
@@ -0,0 +1,498 @@
|
|
|
1
|
+
//#region src/vite/directive.ts
|
|
2
|
+
function findQubuDirective(source) {
|
|
3
|
+
let cursor = skipTrivia(source, 0);
|
|
4
|
+
while (cursor < source.length && isQuote(source[cursor])) {
|
|
5
|
+
const literal = readString(source, cursor);
|
|
6
|
+
if (!literal) break;
|
|
7
|
+
let statementEnd = literal.end;
|
|
8
|
+
if (source[statementEnd] === ";") statementEnd += 1;
|
|
9
|
+
const next = skipTrivia(source, statementEnd);
|
|
10
|
+
if (literal.value === "use qubu") return { end: next };
|
|
11
|
+
if (next >= source.length || !isQuote(source[next])) break;
|
|
12
|
+
cursor = next;
|
|
13
|
+
}
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
function skipTrivia(source, start) {
|
|
17
|
+
let cursor = start;
|
|
18
|
+
while (cursor < source.length) {
|
|
19
|
+
if (isWhitespace$1(source[cursor])) {
|
|
20
|
+
cursor += 1;
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
if (source.startsWith("//", cursor)) {
|
|
24
|
+
const lineEnd = source.indexOf("\n", cursor + 2);
|
|
25
|
+
cursor = lineEnd === -1 ? source.length : lineEnd + 1;
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
if (source.startsWith("/*", cursor)) {
|
|
29
|
+
const commentEnd = source.indexOf("*/", cursor + 2);
|
|
30
|
+
cursor = commentEnd === -1 ? source.length : commentEnd + 2;
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
if (cursor === 0 && source.startsWith("#!", cursor)) {
|
|
34
|
+
const lineEnd = source.indexOf("\n", cursor + 2);
|
|
35
|
+
cursor = lineEnd === -1 ? source.length : lineEnd + 1;
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
break;
|
|
39
|
+
}
|
|
40
|
+
return cursor;
|
|
41
|
+
}
|
|
42
|
+
function readString(source, start) {
|
|
43
|
+
const quote = source[start];
|
|
44
|
+
let cursor = start + 1;
|
|
45
|
+
let value = "";
|
|
46
|
+
while (cursor < source.length) {
|
|
47
|
+
const character = source[cursor];
|
|
48
|
+
if (character === "\\") {
|
|
49
|
+
if (cursor + 1 >= source.length) return null;
|
|
50
|
+
value += source[cursor + 1];
|
|
51
|
+
cursor += 2;
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
if (character === quote) return {
|
|
55
|
+
value,
|
|
56
|
+
end: cursor + 1
|
|
57
|
+
};
|
|
58
|
+
if (character === "\n" || character === "\r") return null;
|
|
59
|
+
value += character;
|
|
60
|
+
cursor += 1;
|
|
61
|
+
}
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
function isQuote(character) {
|
|
65
|
+
return character === "'" || character === "\"";
|
|
66
|
+
}
|
|
67
|
+
function isWhitespace$1(character) {
|
|
68
|
+
return character !== void 0 && /\s/.test(character);
|
|
69
|
+
}
|
|
70
|
+
//#endregion
|
|
71
|
+
//#region src/vite/globals.ts
|
|
72
|
+
/**
|
|
73
|
+
* Public runtime names that the `"use qubu"` transform can auto-import.
|
|
74
|
+
* Keep this catalog aligned with the ordinary authoring surface of `qubu`;
|
|
75
|
+
* fragment internals, dialect construction, and schema extensions belong to
|
|
76
|
+
* the layered entrypoints.
|
|
77
|
+
*/
|
|
78
|
+
const qubuGlobals = [
|
|
79
|
+
"add",
|
|
80
|
+
"alias",
|
|
81
|
+
"all",
|
|
82
|
+
"allowAll",
|
|
83
|
+
"and",
|
|
84
|
+
"asc",
|
|
85
|
+
"asValue",
|
|
86
|
+
"avg",
|
|
87
|
+
"bigint",
|
|
88
|
+
"between",
|
|
89
|
+
"binary",
|
|
90
|
+
"boolean",
|
|
91
|
+
"call",
|
|
92
|
+
"caseWhen",
|
|
93
|
+
"cast",
|
|
94
|
+
"check",
|
|
95
|
+
"coalesce",
|
|
96
|
+
"column",
|
|
97
|
+
"concat",
|
|
98
|
+
"count",
|
|
99
|
+
"countDistinct",
|
|
100
|
+
"correlate",
|
|
101
|
+
"crossJoin",
|
|
102
|
+
"cte",
|
|
103
|
+
"date",
|
|
104
|
+
"denseRank",
|
|
105
|
+
"defaultValues",
|
|
106
|
+
"deleteFrom",
|
|
107
|
+
"desc",
|
|
108
|
+
"distinct",
|
|
109
|
+
"divide",
|
|
110
|
+
"eq",
|
|
111
|
+
"except",
|
|
112
|
+
"execute",
|
|
113
|
+
"executeRows",
|
|
114
|
+
"externalDefault",
|
|
115
|
+
"externalGeneratedColumn",
|
|
116
|
+
"exists",
|
|
117
|
+
"fetchFirst",
|
|
118
|
+
"fetchNext",
|
|
119
|
+
"foreignKey",
|
|
120
|
+
"from",
|
|
121
|
+
"fullJoin",
|
|
122
|
+
"generatedColumn",
|
|
123
|
+
"gt",
|
|
124
|
+
"gte",
|
|
125
|
+
"groupBy",
|
|
126
|
+
"having",
|
|
127
|
+
"identityColumn",
|
|
128
|
+
"inList",
|
|
129
|
+
"inQuery",
|
|
130
|
+
"index",
|
|
131
|
+
"innerJoin",
|
|
132
|
+
"insertInto",
|
|
133
|
+
"insertSelect",
|
|
134
|
+
"integer",
|
|
135
|
+
"intersect",
|
|
136
|
+
"isDistinctFrom",
|
|
137
|
+
"isNotDistinctFrom",
|
|
138
|
+
"isNotNull",
|
|
139
|
+
"isNull",
|
|
140
|
+
"isTrue",
|
|
141
|
+
"json",
|
|
142
|
+
"jsonBoolean",
|
|
143
|
+
"jsonExists",
|
|
144
|
+
"jsonNumber",
|
|
145
|
+
"jsonPath",
|
|
146
|
+
"jsonText",
|
|
147
|
+
"lateral",
|
|
148
|
+
"leftJoin",
|
|
149
|
+
"like",
|
|
150
|
+
"lower",
|
|
151
|
+
"lt",
|
|
152
|
+
"lte",
|
|
153
|
+
"max",
|
|
154
|
+
"min",
|
|
155
|
+
"modulo",
|
|
156
|
+
"multiply",
|
|
157
|
+
"naturalJoin",
|
|
158
|
+
"nativeColumn",
|
|
159
|
+
"nativeStorage",
|
|
160
|
+
"ne",
|
|
161
|
+
"not",
|
|
162
|
+
"notExists",
|
|
163
|
+
"notIn",
|
|
164
|
+
"notLike",
|
|
165
|
+
"nullsFirst",
|
|
166
|
+
"nullsLast",
|
|
167
|
+
"numeric",
|
|
168
|
+
"nullable",
|
|
169
|
+
"offset",
|
|
170
|
+
"omit",
|
|
171
|
+
"or",
|
|
172
|
+
"order",
|
|
173
|
+
"orderBy",
|
|
174
|
+
"over",
|
|
175
|
+
"portableStorage",
|
|
176
|
+
"primaryKey",
|
|
177
|
+
"qubu",
|
|
178
|
+
"references",
|
|
179
|
+
"recursiveCte",
|
|
180
|
+
"render",
|
|
181
|
+
"returning",
|
|
182
|
+
"rightJoin",
|
|
183
|
+
"rank",
|
|
184
|
+
"rowNumber",
|
|
185
|
+
"scalar",
|
|
186
|
+
"schema",
|
|
187
|
+
"schemaCall",
|
|
188
|
+
"select",
|
|
189
|
+
"sql",
|
|
190
|
+
"stream",
|
|
191
|
+
"subtract",
|
|
192
|
+
"sum",
|
|
193
|
+
"table",
|
|
194
|
+
"text",
|
|
195
|
+
"timestamp",
|
|
196
|
+
"union",
|
|
197
|
+
"unionAll",
|
|
198
|
+
"unique",
|
|
199
|
+
"uniqueConstraint",
|
|
200
|
+
"update",
|
|
201
|
+
"upper",
|
|
202
|
+
"value",
|
|
203
|
+
"values",
|
|
204
|
+
"where",
|
|
205
|
+
"withCte",
|
|
206
|
+
"uuid"
|
|
207
|
+
];
|
|
208
|
+
//#endregion
|
|
209
|
+
//#region src/vite/tokens.ts
|
|
210
|
+
const identifierStart = /[A-Za-z_$]/;
|
|
211
|
+
const identifierPart = /[A-Za-z0-9_$]/;
|
|
212
|
+
const punctuators = [
|
|
213
|
+
">>>=",
|
|
214
|
+
"===",
|
|
215
|
+
"!==",
|
|
216
|
+
"**=",
|
|
217
|
+
">>>",
|
|
218
|
+
"&&=",
|
|
219
|
+
"||=",
|
|
220
|
+
"??=",
|
|
221
|
+
"...",
|
|
222
|
+
"=>",
|
|
223
|
+
"?.",
|
|
224
|
+
"==",
|
|
225
|
+
"!=",
|
|
226
|
+
"<=",
|
|
227
|
+
">=",
|
|
228
|
+
"++",
|
|
229
|
+
"--",
|
|
230
|
+
"&&",
|
|
231
|
+
"||",
|
|
232
|
+
"??",
|
|
233
|
+
"**",
|
|
234
|
+
"+=",
|
|
235
|
+
"-=",
|
|
236
|
+
"*=",
|
|
237
|
+
"/=",
|
|
238
|
+
"%=",
|
|
239
|
+
"&=",
|
|
240
|
+
"|=",
|
|
241
|
+
"^=",
|
|
242
|
+
"<<",
|
|
243
|
+
">>"
|
|
244
|
+
];
|
|
245
|
+
function tokenize(source) {
|
|
246
|
+
const tokens = [];
|
|
247
|
+
let cursor = 0;
|
|
248
|
+
while (cursor < source.length) {
|
|
249
|
+
const character = source[cursor];
|
|
250
|
+
if (isWhitespace(character)) {
|
|
251
|
+
cursor += 1;
|
|
252
|
+
continue;
|
|
253
|
+
}
|
|
254
|
+
if (source.startsWith("//", cursor)) {
|
|
255
|
+
cursor = skipLineComment(source, cursor);
|
|
256
|
+
continue;
|
|
257
|
+
}
|
|
258
|
+
if (source.startsWith("/*", cursor)) {
|
|
259
|
+
cursor = skipBlockComment(source, cursor);
|
|
260
|
+
continue;
|
|
261
|
+
}
|
|
262
|
+
if (character === "'" || character === "\"") {
|
|
263
|
+
cursor = skipQuotedString(source, cursor);
|
|
264
|
+
continue;
|
|
265
|
+
}
|
|
266
|
+
if (character === "`") {
|
|
267
|
+
cursor = skipTemplate(source, cursor);
|
|
268
|
+
continue;
|
|
269
|
+
}
|
|
270
|
+
if (isIdentifierStart(character)) {
|
|
271
|
+
const start = cursor;
|
|
272
|
+
cursor += 1;
|
|
273
|
+
while (cursor < source.length && isIdentifierPart(source[cursor])) cursor += 1;
|
|
274
|
+
tokens.push({
|
|
275
|
+
kind: "identifier",
|
|
276
|
+
value: source.slice(start, cursor),
|
|
277
|
+
start,
|
|
278
|
+
end: cursor
|
|
279
|
+
});
|
|
280
|
+
continue;
|
|
281
|
+
}
|
|
282
|
+
if (isNumberStart(character)) {
|
|
283
|
+
cursor = skipNumber(source, cursor);
|
|
284
|
+
continue;
|
|
285
|
+
}
|
|
286
|
+
const punctuator = punctuators.find((value) => source.startsWith(value, cursor));
|
|
287
|
+
if (punctuator) {
|
|
288
|
+
tokens.push({
|
|
289
|
+
kind: "punctuator",
|
|
290
|
+
value: punctuator,
|
|
291
|
+
start: cursor,
|
|
292
|
+
end: cursor + punctuator.length
|
|
293
|
+
});
|
|
294
|
+
cursor += punctuator.length;
|
|
295
|
+
continue;
|
|
296
|
+
}
|
|
297
|
+
tokens.push({
|
|
298
|
+
kind: "punctuator",
|
|
299
|
+
value: character,
|
|
300
|
+
start: cursor,
|
|
301
|
+
end: cursor + 1
|
|
302
|
+
});
|
|
303
|
+
cursor += 1;
|
|
304
|
+
}
|
|
305
|
+
return tokens;
|
|
306
|
+
}
|
|
307
|
+
function skipLineComment(source, start) {
|
|
308
|
+
const lineEnd = source.indexOf("\n", start + 2);
|
|
309
|
+
return lineEnd === -1 ? source.length : lineEnd + 1;
|
|
310
|
+
}
|
|
311
|
+
function skipBlockComment(source, start) {
|
|
312
|
+
const commentEnd = source.indexOf("*/", start + 2);
|
|
313
|
+
return commentEnd === -1 ? source.length : commentEnd + 2;
|
|
314
|
+
}
|
|
315
|
+
function skipQuotedString(source, start) {
|
|
316
|
+
const quote = source[start];
|
|
317
|
+
let cursor = start + 1;
|
|
318
|
+
while (cursor < source.length) {
|
|
319
|
+
if (source[cursor] === "\\") {
|
|
320
|
+
cursor += 2;
|
|
321
|
+
continue;
|
|
322
|
+
}
|
|
323
|
+
if (source[cursor] === quote) return cursor + 1;
|
|
324
|
+
cursor += 1;
|
|
325
|
+
}
|
|
326
|
+
return source.length;
|
|
327
|
+
}
|
|
328
|
+
function skipTemplate(source, start) {
|
|
329
|
+
let cursor = start + 1;
|
|
330
|
+
while (cursor < source.length) {
|
|
331
|
+
if (source[cursor] === "\\") {
|
|
332
|
+
cursor += 2;
|
|
333
|
+
continue;
|
|
334
|
+
}
|
|
335
|
+
if (source[cursor] === "`") return cursor + 1;
|
|
336
|
+
cursor += 1;
|
|
337
|
+
}
|
|
338
|
+
return source.length;
|
|
339
|
+
}
|
|
340
|
+
function skipNumber(source, start) {
|
|
341
|
+
let cursor = start;
|
|
342
|
+
while (cursor < source.length && /[A-Za-z0-9._]/.test(source[cursor])) cursor += 1;
|
|
343
|
+
return cursor;
|
|
344
|
+
}
|
|
345
|
+
function isIdentifierStart(character) {
|
|
346
|
+
return character !== void 0 && identifierStart.test(character);
|
|
347
|
+
}
|
|
348
|
+
function isIdentifierPart(character) {
|
|
349
|
+
return character !== void 0 && identifierPart.test(character);
|
|
350
|
+
}
|
|
351
|
+
function isNumberStart(character) {
|
|
352
|
+
return character !== void 0 && /[0-9]/.test(character);
|
|
353
|
+
}
|
|
354
|
+
function isWhitespace(character) {
|
|
355
|
+
return character !== void 0 && /\s/.test(character);
|
|
356
|
+
}
|
|
357
|
+
//#endregion
|
|
358
|
+
//#region src/vite/references.ts
|
|
359
|
+
function findQubuReferences(source, globals) {
|
|
360
|
+
const tokens = tokenize(source);
|
|
361
|
+
const available = new Set(globals);
|
|
362
|
+
const boundNames = collectBoundNames(tokens);
|
|
363
|
+
const used = /* @__PURE__ */ new Set();
|
|
364
|
+
for (const [index, token] of tokens.entries()) {
|
|
365
|
+
if (token.kind !== "identifier") continue;
|
|
366
|
+
if (!available.has(token.value)) continue;
|
|
367
|
+
if (boundNames.has(token.value)) continue;
|
|
368
|
+
if (!isReference(tokens, index)) continue;
|
|
369
|
+
used.add(token.value);
|
|
370
|
+
}
|
|
371
|
+
return globals.filter((name) => used.has(name));
|
|
372
|
+
}
|
|
373
|
+
function collectBoundNames(tokens) {
|
|
374
|
+
const boundNames = /* @__PURE__ */ new Set();
|
|
375
|
+
for (let index = 0; index < tokens.length; index += 1) {
|
|
376
|
+
const value = tokens[index].value;
|
|
377
|
+
if (value === "import") {
|
|
378
|
+
collectImportBindings(tokens, index, boundNames);
|
|
379
|
+
continue;
|
|
380
|
+
}
|
|
381
|
+
if (value === "const" || value === "let" || value === "var") {
|
|
382
|
+
collectVariableBinding(tokens, index + 1, boundNames);
|
|
383
|
+
continue;
|
|
384
|
+
}
|
|
385
|
+
if (value === "function" || value === "class" || value === "interface" || value === "type" || value === "enum" || value === "namespace") {
|
|
386
|
+
addNextIdentifier(tokens, index + 1, boundNames);
|
|
387
|
+
if (value === "function") collectParameterBindings(tokens, index + 1, boundNames);
|
|
388
|
+
continue;
|
|
389
|
+
}
|
|
390
|
+
if (value === "catch") {
|
|
391
|
+
collectParameterBindings(tokens, index + 1, boundNames);
|
|
392
|
+
continue;
|
|
393
|
+
}
|
|
394
|
+
if (value === "=>") {
|
|
395
|
+
const previous = tokens[index - 1];
|
|
396
|
+
if (previous?.kind === "identifier") boundNames.add(previous.value);
|
|
397
|
+
else if (previous?.value === ")") {
|
|
398
|
+
const opening = findMatchingOpening(tokens, index - 1, "(", ")");
|
|
399
|
+
if (opening !== -1) collectIdentifiers(tokens, opening + 1, index - 1, boundNames);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
return boundNames;
|
|
404
|
+
}
|
|
405
|
+
function collectImportBindings(tokens, importIndex, boundNames) {
|
|
406
|
+
const next = tokens[importIndex + 1];
|
|
407
|
+
if (!next || next.value === "(" || next.value === ".") return;
|
|
408
|
+
for (let index = importIndex + 1; index < tokens.length; index += 1) {
|
|
409
|
+
const token = tokens[index];
|
|
410
|
+
if (token.value === "from" || token.value === ";") break;
|
|
411
|
+
if (token.kind === "identifier" && token.value !== "type") boundNames.add(token.value);
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
function collectVariableBinding(tokens, start, boundNames) {
|
|
415
|
+
const first = tokens[start];
|
|
416
|
+
if (!first) return;
|
|
417
|
+
if (first.kind === "identifier") {
|
|
418
|
+
boundNames.add(first.value);
|
|
419
|
+
return;
|
|
420
|
+
}
|
|
421
|
+
if (first.value !== "{" && first.value !== "[") return;
|
|
422
|
+
const closing = findMatchingClosing(tokens, start);
|
|
423
|
+
if (closing !== -1) collectIdentifiers(tokens, start + 1, closing, boundNames);
|
|
424
|
+
}
|
|
425
|
+
function collectParameterBindings(tokens, start, boundNames) {
|
|
426
|
+
const opening = tokens.findIndex((token, index) => index >= start && token.value === "(");
|
|
427
|
+
if (opening === -1) return;
|
|
428
|
+
const closing = findMatchingClosing(tokens, opening);
|
|
429
|
+
if (closing !== -1) collectIdentifiers(tokens, opening + 1, closing, boundNames);
|
|
430
|
+
}
|
|
431
|
+
function collectIdentifiers(tokens, start, end, boundNames) {
|
|
432
|
+
for (let index = start; index < end; index += 1) {
|
|
433
|
+
const token = tokens[index];
|
|
434
|
+
if (token.kind === "identifier" && token.value !== "as") boundNames.add(token.value);
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
function addNextIdentifier(tokens, start, boundNames) {
|
|
438
|
+
const token = tokens[start];
|
|
439
|
+
if (token?.kind === "identifier") boundNames.add(token.value);
|
|
440
|
+
}
|
|
441
|
+
function isReference(tokens, index) {
|
|
442
|
+
const previous = tokens[index - 1]?.value;
|
|
443
|
+
const next = tokens[index + 1]?.value;
|
|
444
|
+
if (previous === "." || previous === "?." || previous === "#") return false;
|
|
445
|
+
if (next === ":") return false;
|
|
446
|
+
if (previous === "interface" || previous === "type") return false;
|
|
447
|
+
return true;
|
|
448
|
+
}
|
|
449
|
+
function findMatchingClosing(tokens, opening) {
|
|
450
|
+
const open = tokens[opening]?.value;
|
|
451
|
+
return findMatchingOpening(tokens, opening, open, open === "{" ? "}" : open === "[" ? "]" : ")", true);
|
|
452
|
+
}
|
|
453
|
+
function findMatchingOpening(tokens, start, open, close, forward = false) {
|
|
454
|
+
let depth = 0;
|
|
455
|
+
const step = forward ? 1 : -1;
|
|
456
|
+
const end = forward ? tokens.length : -1;
|
|
457
|
+
for (let index = start; index !== end; index += step) {
|
|
458
|
+
if (tokens[index].value === open) depth += 1;
|
|
459
|
+
if (tokens[index].value === close) depth -= 1;
|
|
460
|
+
if (depth === 0) return index;
|
|
461
|
+
}
|
|
462
|
+
return -1;
|
|
463
|
+
}
|
|
464
|
+
//#endregion
|
|
465
|
+
//#region src/vite/index.ts
|
|
466
|
+
const scriptExtension = /\.(?:[cm]?js|[cm]?ts|jsx|tsx)$/;
|
|
467
|
+
function qubu(options = {}) {
|
|
468
|
+
const moduleId = options.module ?? "qubu";
|
|
469
|
+
const globals = options.globals ?? qubuGlobals;
|
|
470
|
+
return {
|
|
471
|
+
name: "qubu:compiler-hint",
|
|
472
|
+
enforce: "pre",
|
|
473
|
+
transform(code, id) {
|
|
474
|
+
const filename = id.split("?", 1)[0];
|
|
475
|
+
if (!scriptExtension.test(filename)) return null;
|
|
476
|
+
if (filename.includes("/node_modules/")) return null;
|
|
477
|
+
if (options.include && !matches(options.include, id)) return null;
|
|
478
|
+
if (options.exclude && matches(options.exclude, id)) return null;
|
|
479
|
+
const directive = findQubuDirective(code);
|
|
480
|
+
if (!directive) return null;
|
|
481
|
+
const references = findQubuReferences(code, globals);
|
|
482
|
+
if (references.length === 0) return null;
|
|
483
|
+
const imports = `import { ${references.join(", ")} } from ${JSON.stringify(moduleId)};\n`;
|
|
484
|
+
return {
|
|
485
|
+
code: `${code.slice(0, directive.end)}${imports}${code.slice(directive.end)}`,
|
|
486
|
+
map: null
|
|
487
|
+
};
|
|
488
|
+
}
|
|
489
|
+
};
|
|
490
|
+
}
|
|
491
|
+
const qubuVitePlugin = qubu;
|
|
492
|
+
function matches(filter, id) {
|
|
493
|
+
if (typeof filter === "function") return filter(id);
|
|
494
|
+
filter.lastIndex = 0;
|
|
495
|
+
return filter.test(id);
|
|
496
|
+
}
|
|
497
|
+
//#endregion
|
|
498
|
+
export { qubu as default, qubu, qubuGlobals, qubuVitePlugin };
|
package/docs/config.json
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"link": {
|
|
3
|
+
"underline": "hover"
|
|
4
|
+
},
|
|
5
|
+
"reference": {
|
|
6
|
+
"enabled": false
|
|
7
|
+
},
|
|
8
|
+
"navigation": {
|
|
9
|
+
"order": [
|
|
10
|
+
"getting-started.md",
|
|
11
|
+
"query-model/",
|
|
12
|
+
"schema/",
|
|
13
|
+
"dialects-and-execution.md",
|
|
14
|
+
"sql-semantic-types.md",
|
|
15
|
+
"guides/",
|
|
16
|
+
"reference/",
|
|
17
|
+
"troubleshooting.md"
|
|
18
|
+
],
|
|
19
|
+
"duration": 125
|
|
20
|
+
}
|
|
21
|
+
}
|