@lunora/codegen 1.0.0-alpha.55 → 1.0.0-alpha.56
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.d.mts +59 -5
- package/dist/index.d.ts +59 -5
- package/dist/index.mjs +1 -38
- package/dist/packem_shared/AGENTS_FILENAME-BesaDYkL.mjs +1 -0
- package/dist/packem_shared/CONTAINERS_FILENAME-CFwdyaCI.mjs +1 -0
- package/dist/packem_shared/CodegenDiagnosticError-DPezpZTz.mjs +1 -0
- package/dist/packem_shared/FLAGS_FILENAME-DW5oGq1q.mjs +1 -0
- package/dist/packem_shared/GENERATED_HEADER-C94PuLpQ.mjs +1 -0
- package/dist/packem_shared/LUNORA_ERROR_CODES-Um9hC1gr.mjs +1 -0
- package/dist/packem_shared/MUTATORS_FILENAME-BKKPROzu.mjs +1 -0
- package/dist/packem_shared/NOTIFY_FILENAME-C-c7Lg-U.mjs +1 -0
- package/dist/packem_shared/OPENRPC_VERSION-DpV3v2W8.mjs +3 -0
- package/dist/packem_shared/QUEUES_FILENAME-CSE6i-ld.mjs +1 -0
- package/dist/packem_shared/SCHEMA_SNAPSHOT_FILENAME-DJsxljOQ.mjs +3 -0
- package/dist/packem_shared/SCHEMA_SNAPSHOT_VERSION-Bpf1FGMG.mjs +15 -0
- package/dist/packem_shared/SHAPES_FILENAME-DTkSJSsg.mjs +1 -0
- package/dist/packem_shared/WORKFLOWS_FILENAME-Bk5upkGM.mjs +1 -0
- package/dist/packem_shared/buildOpenApiDocument-DXX1G3GZ.mjs +3 -0
- package/dist/packem_shared/discover-ast-CezKqEhE.mjs +1 -0
- package/dist/packem_shared/discoverAuthApiCalls-DOfSQqVK.mjs +1 -0
- package/dist/packem_shared/discoverCrons-B09_uEuL.mjs +1 -0
- package/dist/packem_shared/discoverFunctions-BdibLQmc.mjs +1 -0
- package/dist/packem_shared/discoverHttpRoutes-BOWz6y_n.mjs +1 -0
- package/dist/packem_shared/discoverInserts-BtteTyNy.mjs +1 -0
- package/dist/packem_shared/discoverMaskProcedures-COPmwMBm.mjs +1 -0
- package/dist/packem_shared/discoverMigrations-iGMlp9YJ.mjs +1 -0
- package/dist/packem_shared/discoverNondeterministicCalls-Dmgc4QBx.mjs +1 -0
- package/dist/packem_shared/discoverQueries-CcfuGKHh.mjs +1 -0
- package/dist/packem_shared/discoverR2sqlCalls-CjZKvg-N.mjs +1 -0
- package/dist/packem_shared/discoverRlsMetadata-BXmNOgry.mjs +1 -0
- package/dist/packem_shared/discoverSandboxUsage-CDdBqWcM.mjs +1 -0
- package/dist/packem_shared/discoverSchema-m2voTncu.mjs +1 -0
- package/dist/packem_shared/discoverStorageRulesMetadata-b71cJJHz.mjs +1 -0
- package/dist/packem_shared/emit-Dr6XSLfW.mjs +2104 -0
- package/dist/packem_shared/emitApp-B671iU7r.mjs +413 -0
- package/dist/packem_shared/formatAdvisories-DZvv-0MG.mjs +2 -0
- package/dist/packem_shared/parse-validator-CSDlMEvE.mjs +1 -0
- package/dist/packem_shared/paths-BmX5O1sG.mjs +1 -0
- package/dist/packem_shared/redact-CQ8-to6l.mjs +1 -0
- package/dist/packem_shared/schemaFromIr-R1ZFzVyy.mjs +1 -0
- package/package.json +3 -3
- package/dist/packem_shared/AGENTS_FILENAME-Cxx7wiSs.mjs +0 -158
- package/dist/packem_shared/CONTAINERS_FILENAME-DjpXMqhp.mjs +0 -224
- package/dist/packem_shared/CodegenDiagnosticError-DyQ5FwkM.mjs +0 -24
- package/dist/packem_shared/FLAGS_FILENAME-D5igzqwR.mjs +0 -139
- package/dist/packem_shared/GENERATED_HEADER-C8tAvxqP.mjs +0 -4
- package/dist/packem_shared/LUNORA_ERROR_CODES-DvTLozCu.mjs +0 -68
- package/dist/packem_shared/MUTATORS_FILENAME-BZOfUhlY.mjs +0 -81
- package/dist/packem_shared/NOTIFY_FILENAME-CK2IrsrP.mjs +0 -152
- package/dist/packem_shared/OPENRPC_VERSION-DvDChMhC.mjs +0 -60
- package/dist/packem_shared/QUEUES_FILENAME-Xv6Vy-Ku.mjs +0 -145
- package/dist/packem_shared/SCHEMA_SNAPSHOT_FILENAME-YAL6GrxI.mjs +0 -3597
- package/dist/packem_shared/SCHEMA_SNAPSHOT_VERSION-DGD73E_n.mjs +0 -252
- package/dist/packem_shared/SHAPES_FILENAME-DOhPGi-6.mjs +0 -94
- package/dist/packem_shared/WORKFLOWS_FILENAME-Dtuzvluc.mjs +0 -158
- package/dist/packem_shared/buildOpenApiDocument-DCQSLuFc.mjs +0 -262
- package/dist/packem_shared/discover-ast-CT6BgBr4.mjs +0 -13
- package/dist/packem_shared/discoverAuthApiCalls-Dhwgf4J4.mjs +0 -62
- package/dist/packem_shared/discoverCrons-UbQLLmMS.mjs +0 -286
- package/dist/packem_shared/discoverFunctions-COG_Xkyz.mjs +0 -544
- package/dist/packem_shared/discoverHttpRoutes-CVXWZkzo.mjs +0 -139
- package/dist/packem_shared/discoverInserts-DdWnXmLS.mjs +0 -61
- package/dist/packem_shared/discoverMaskProcedures-BG58_fw3.mjs +0 -273
- package/dist/packem_shared/discoverMigrations-Bw1U01zr.mjs +0 -97
- package/dist/packem_shared/discoverNondeterministicCalls-BbXEFZUT.mjs +0 -122
- package/dist/packem_shared/discoverQueries-CDmxu2ET.mjs +0 -62
- package/dist/packem_shared/discoverR2sqlCalls-Bn7QVv7J.mjs +0 -80
- package/dist/packem_shared/discoverRlsMetadata-D9uN35no.mjs +0 -280
- package/dist/packem_shared/discoverSandboxUsage-B5jDU6Bt.mjs +0 -38
- package/dist/packem_shared/discoverSchema-BJp5_T4o.mjs +0 -906
- package/dist/packem_shared/discoverStorageRulesMetadata-BqMhuEjo.mjs +0 -97
- package/dist/packem_shared/emit-DIbr7U31.mjs +0 -3884
- package/dist/packem_shared/emitApp-DbMM8iHe.mjs +0 -706
- package/dist/packem_shared/formatAdvisories-Cans5TWS.mjs +0 -131
- package/dist/packem_shared/parse-validator-BDGV8iue.mjs +0 -144
- package/dist/packem_shared/paths-BRd6JHuF.mjs +0 -11
- package/dist/packem_shared/redact-oTmsol5A.mjs +0 -33
- package/dist/packem_shared/schemaFromIr-DTYsLBaA.mjs +0 -57
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
import { runAdvisor } from '@lunora/advisor';
|
|
2
|
-
|
|
3
|
-
const flattenIndexes = (table) => [
|
|
4
|
-
...table.indexes.map((index) => {
|
|
5
|
-
return { fields: index.fields, kind: "index", name: index.name, unique: index.unique };
|
|
6
|
-
}),
|
|
7
|
-
...table.searchIndexes.map((index) => {
|
|
8
|
-
return { fields: [index.field, ...index.filterFields ?? []], kind: "search", name: index.name };
|
|
9
|
-
}),
|
|
10
|
-
...table.rankIndexes.map((index) => {
|
|
11
|
-
return { fields: [...index.sortBy.map((key) => key.field), ...index.partitionBy ?? []], kind: "rank", name: index.name };
|
|
12
|
-
}),
|
|
13
|
-
...table.vectorIndexes.filter((index) => index.field !== void 0).map((index) => {
|
|
14
|
-
return { fields: [index.field], kind: "vector", name: index.name };
|
|
15
|
-
}),
|
|
16
|
-
...(table.geoIndexes ?? []).map((index) => {
|
|
17
|
-
return { fields: [index.field], kind: "geo", name: index.name };
|
|
18
|
-
})
|
|
19
|
-
];
|
|
20
|
-
const columnKindsOf = (table) => {
|
|
21
|
-
const kinds = {};
|
|
22
|
-
for (const [fieldName, validator] of Object.entries(table.shape)) {
|
|
23
|
-
kinds[fieldName] = validator.kind === "optional" ? validator.inner?.kind ?? "optional" : validator.kind;
|
|
24
|
-
}
|
|
25
|
-
return kinds;
|
|
26
|
-
};
|
|
27
|
-
const toAdvisorSchema = (schema) => {
|
|
28
|
-
return {
|
|
29
|
-
rlsMode: schema.rlsMode,
|
|
30
|
-
tables: schema.tables.map((table) => {
|
|
31
|
-
return {
|
|
32
|
-
externallyManaged: table.externallyManaged ?? false,
|
|
33
|
-
externalSource: table.externalSource ? {
|
|
34
|
-
hasReconcile: table.externalSource.hasReconcile ?? false,
|
|
35
|
-
hasSoftDelete: table.externalSource.hasSoftDelete ?? false,
|
|
36
|
-
hasTenantBy: table.externalSource.hasTenantBy,
|
|
37
|
-
mode: table.externalSource.mode,
|
|
38
|
-
unanalyzable: table.externalSource.unanalyzable
|
|
39
|
-
} : void 0,
|
|
40
|
-
columnKinds: columnKindsOf(table),
|
|
41
|
-
fields: Object.keys(table.shape),
|
|
42
|
-
indexes: flattenIndexes(table),
|
|
43
|
-
isPublic: table.isPublic ?? false,
|
|
44
|
-
name: table.name,
|
|
45
|
-
relations: table.relations.map((relation) => {
|
|
46
|
-
return {
|
|
47
|
-
field: relation.field,
|
|
48
|
-
kind: relation.kind,
|
|
49
|
-
name: relation.name,
|
|
50
|
-
onDelete: relation.onDelete,
|
|
51
|
-
references: relation.references,
|
|
52
|
-
table: relation.table
|
|
53
|
-
};
|
|
54
|
-
}),
|
|
55
|
-
shardKind: typeof table.shardMode === "string" ? table.shardMode : "shardBy",
|
|
56
|
-
softDelete: table.softDelete,
|
|
57
|
-
ttl: table.ttl
|
|
58
|
-
};
|
|
59
|
-
})
|
|
60
|
-
};
|
|
61
|
-
};
|
|
62
|
-
const toAdvisorShapes = (shapes) => shapes.map((shape) => {
|
|
63
|
-
return { exportName: shape.exportName, file: `lunora/${shape.filePath}.ts`, table: shape.table };
|
|
64
|
-
});
|
|
65
|
-
const lintSchema = (options) => runAdvisor(
|
|
66
|
-
{
|
|
67
|
-
adminRoutes: options.adminRoutes,
|
|
68
|
-
aiRawRuns: options.aiRawRuns,
|
|
69
|
-
aiToolSideEffects: options.aiToolSideEffects,
|
|
70
|
-
argumentDerivedFetches: options.argumentDerivedFetches,
|
|
71
|
-
argValidators: options.argumentValidators,
|
|
72
|
-
authApiCalls: options.authApiCalls,
|
|
73
|
-
authConfigs: options.authConfigs,
|
|
74
|
-
browserUrlAccesses: options.browserUrlAccesses,
|
|
75
|
-
configCalls: options.configCalls,
|
|
76
|
-
containerKeyAccesses: options.containerKeyAccesses,
|
|
77
|
-
containerOverrides: options.containerOverrides,
|
|
78
|
-
containers: options.containers,
|
|
79
|
-
exportSinks: options.exportSinks,
|
|
80
|
-
failOpenGuards: options.failOpenGuards,
|
|
81
|
-
flagSecurityDefaults: options.flagSecurityDefaults,
|
|
82
|
-
geoIndexUsages: options.geoIndexUsages,
|
|
83
|
-
httpActionGuards: options.httpActionGuards,
|
|
84
|
-
httpHeaderWrites: options.httpHeaderWrites,
|
|
85
|
-
identityClaimReads: options.identityClaimReads,
|
|
86
|
-
imageDeliveryUrlAccesses: options.imageDeliveryUrlAccesses,
|
|
87
|
-
inserts: options.inserts,
|
|
88
|
-
kvKeyAccesses: options.kvKeyAccesses,
|
|
89
|
-
mailRecipientAccesses: options.mailRecipientAccesses,
|
|
90
|
-
maskProcedures: options.maskProcedures,
|
|
91
|
-
maskStrategies: options.maskStrategies,
|
|
92
|
-
mutatorWrites: options.mutatorWrites,
|
|
93
|
-
nondeterministicCalls: options.nondeterministicCalls,
|
|
94
|
-
normalizeIdAuthorizations: options.normalizeIdAuthorizations,
|
|
95
|
-
notifyCalls: options.notifyCalls,
|
|
96
|
-
notifyConfig: options.notifyConfig,
|
|
97
|
-
ownerFieldWrites: options.ownerFieldWrites,
|
|
98
|
-
paymentWebhooks: options.paymentWebhooks,
|
|
99
|
-
privilegedDispatches: options.privilegedDispatches,
|
|
100
|
-
procedureProtections: options.procedureProtections,
|
|
101
|
-
queries: options.queries ?? [],
|
|
102
|
-
queues: options.queues,
|
|
103
|
-
r2sqlCalls: options.r2sqlCalls,
|
|
104
|
-
ratelimitKeySelectors: options.ratelimitKeySelectors,
|
|
105
|
-
rawRowReturns: options.rawRowReturns,
|
|
106
|
-
relationLoads: options.relationLoads,
|
|
107
|
-
rlsProcedures: options.rlsProcedures,
|
|
108
|
-
schema: toAdvisorSchema(options.schema),
|
|
109
|
-
secretLiterals: options.secretLiterals,
|
|
110
|
-
shapes: options.shapes === void 0 ? void 0 : toAdvisorShapes(options.shapes),
|
|
111
|
-
softDeleteReads: options.softDeleteReads,
|
|
112
|
-
sqlInterpolations: options.sqlInterpolations,
|
|
113
|
-
storageKeyAccesses: options.storageKeyAccesses,
|
|
114
|
-
storageUploads: options.storageUploads,
|
|
115
|
-
vectorNamespaceAccesses: options.vectorNamespaceAccesses,
|
|
116
|
-
workflowCalls: options.workflowCalls,
|
|
117
|
-
workflows: options.workflows,
|
|
118
|
-
wranglerVariables: options.wranglerVariables
|
|
119
|
-
},
|
|
120
|
-
{ source: "static" }
|
|
121
|
-
);
|
|
122
|
-
const formatAdvisories = (findings) => {
|
|
123
|
-
if (findings.length === 0) {
|
|
124
|
-
return "";
|
|
125
|
-
}
|
|
126
|
-
const header = `@lunora/codegen: ${String(findings.length)} schema advisor finding${findings.length === 1 ? "" : "s"}`;
|
|
127
|
-
const lines = findings.map((finding) => ` [${finding.level}] ${finding.name}: ${finding.detail}`);
|
|
128
|
-
return [header, ...lines].join("\n");
|
|
129
|
-
};
|
|
130
|
-
|
|
131
|
-
export { formatAdvisories, lintSchema };
|
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
import { LunoraError } from '@lunora/errors';
|
|
2
|
-
import { Node } from 'ts-morph';
|
|
3
|
-
|
|
4
|
-
const FIELD_NAME_RE = /^[A-Za-z_$][\w$]*$/u;
|
|
5
|
-
const COLUMN_MODIFIERS = /* @__PURE__ */ new Set(["$defaultFn", "$onUpdateFn", "$type", "default", "defaultNow", "nullable", "unique"]);
|
|
6
|
-
const applyColumnModifier = (base, modifier) => {
|
|
7
|
-
const column = { notNull: true, ...base.column };
|
|
8
|
-
switch (modifier) {
|
|
9
|
-
case "$defaultFn":
|
|
10
|
-
case "default":
|
|
11
|
-
case "defaultNow": {
|
|
12
|
-
column.hasDefault = true;
|
|
13
|
-
break;
|
|
14
|
-
}
|
|
15
|
-
case "$onUpdateFn": {
|
|
16
|
-
column.hasOnUpdate = true;
|
|
17
|
-
break;
|
|
18
|
-
}
|
|
19
|
-
case "$type": {
|
|
20
|
-
break;
|
|
21
|
-
}
|
|
22
|
-
case "nullable": {
|
|
23
|
-
column.notNull = false;
|
|
24
|
-
break;
|
|
25
|
-
}
|
|
26
|
-
case "unique": {
|
|
27
|
-
column.unique = true;
|
|
28
|
-
break;
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
return { ...base, column };
|
|
32
|
-
};
|
|
33
|
-
const SCALAR_KINDS = /* @__PURE__ */ new Set(["any", "bigint", "boolean", "bytes", "date", "geoPoint", "null", "number", "string", "timestamp"]);
|
|
34
|
-
const TRANSPARENT_MODIFIERS = /* @__PURE__ */ new Set(["check", "meta"]);
|
|
35
|
-
const parseValidator = (expression) => {
|
|
36
|
-
if (Node.isCallExpression(expression)) {
|
|
37
|
-
return parseValidatorCall(expression);
|
|
38
|
-
}
|
|
39
|
-
return { kind: "any", sourceText: expression.getText() };
|
|
40
|
-
};
|
|
41
|
-
const parseObjectShape = (object) => {
|
|
42
|
-
const out = {};
|
|
43
|
-
for (const property of object.getProperties()) {
|
|
44
|
-
if (!Node.isPropertyAssignment(property)) {
|
|
45
|
-
continue;
|
|
46
|
-
}
|
|
47
|
-
const nameNode = property.getNameNode();
|
|
48
|
-
if (Node.isComputedPropertyName(nameNode)) {
|
|
49
|
-
continue;
|
|
50
|
-
}
|
|
51
|
-
const initializer = property.getInitializer();
|
|
52
|
-
if (!initializer) {
|
|
53
|
-
continue;
|
|
54
|
-
}
|
|
55
|
-
const fieldName = property.getName();
|
|
56
|
-
if (!FIELD_NAME_RE.test(fieldName)) {
|
|
57
|
-
throw new LunoraError("INTERNAL", `@lunora/codegen: field name is not a valid JS identifier: ${JSON.stringify(fieldName)}`);
|
|
58
|
-
}
|
|
59
|
-
out[fieldName] = parseValidator(initializer);
|
|
60
|
-
}
|
|
61
|
-
return out;
|
|
62
|
-
};
|
|
63
|
-
const parseArgument = (argument, fallback) => argument && Node.isExpression(argument) ? parseValidator(argument) : fallback;
|
|
64
|
-
const renderLiteralSource = (node) => {
|
|
65
|
-
if (node === void 0) {
|
|
66
|
-
return "undefined";
|
|
67
|
-
}
|
|
68
|
-
if (Node.isStringLiteral(node) || Node.isNoSubstitutionTemplateLiteral(node)) {
|
|
69
|
-
return JSON.stringify(node.getLiteralValue());
|
|
70
|
-
}
|
|
71
|
-
return node.getText();
|
|
72
|
-
};
|
|
73
|
-
const parseBuilderMember = (member, args) => {
|
|
74
|
-
if (SCALAR_KINDS.has(member)) {
|
|
75
|
-
return { kind: member };
|
|
76
|
-
}
|
|
77
|
-
const [first, second] = args;
|
|
78
|
-
switch (member) {
|
|
79
|
-
case "array": {
|
|
80
|
-
return { inner: parseArgument(first, { kind: "any" }), kind: "array" };
|
|
81
|
-
}
|
|
82
|
-
case "from": {
|
|
83
|
-
return { kind: "from" };
|
|
84
|
-
}
|
|
85
|
-
case "id": {
|
|
86
|
-
return { kind: "id", tableName: first && Node.isStringLiteral(first) ? first.getLiteralText() : "_unknown_" };
|
|
87
|
-
}
|
|
88
|
-
case "literal": {
|
|
89
|
-
return {
|
|
90
|
-
kind: "literal",
|
|
91
|
-
// Canonical source text — strings/templates are re-encoded via
|
|
92
|
-
// JSON.stringify (see renderLiteralSource) so escapes/backticks
|
|
93
|
-
// survive; numbers/booleans/null keep their verbatim text.
|
|
94
|
-
literalValue: renderLiteralSource(first)
|
|
95
|
-
};
|
|
96
|
-
}
|
|
97
|
-
case "object": {
|
|
98
|
-
return first && Node.isObjectLiteralExpression(first) ? { kind: "object", shape: parseObjectShape(first) } : { kind: "object", shape: {} };
|
|
99
|
-
}
|
|
100
|
-
case "optional": {
|
|
101
|
-
return { inner: parseArgument(first, { kind: "any" }), kind: "optional" };
|
|
102
|
-
}
|
|
103
|
-
case "record": {
|
|
104
|
-
return {
|
|
105
|
-
keyType: parseArgument(first, { kind: "string" }),
|
|
106
|
-
kind: "record",
|
|
107
|
-
valueType: parseArgument(second, { kind: "any" })
|
|
108
|
-
};
|
|
109
|
-
}
|
|
110
|
-
case "storage": {
|
|
111
|
-
return first && Node.isStringLiteral(first) ? { bucket: first.getLiteralText(), kind: "storage" } : { kind: "storage" };
|
|
112
|
-
}
|
|
113
|
-
case "union": {
|
|
114
|
-
return {
|
|
115
|
-
kind: "union",
|
|
116
|
-
members: args.filter((argument) => Node.isExpression(argument)).map((argument) => parseValidator(argument))
|
|
117
|
-
};
|
|
118
|
-
}
|
|
119
|
-
default: {
|
|
120
|
-
throw new LunoraError("INTERNAL", `Unsupported validator kind: ${member}`);
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
};
|
|
124
|
-
const parseValidatorCall = (call) => {
|
|
125
|
-
const callee = call.getExpression();
|
|
126
|
-
if (!Node.isPropertyAccessExpression(callee)) {
|
|
127
|
-
return { kind: "any", sourceText: call.getText() };
|
|
128
|
-
}
|
|
129
|
-
const member = callee.getName();
|
|
130
|
-
const args = call.getArguments();
|
|
131
|
-
if (COLUMN_MODIFIERS.has(member)) {
|
|
132
|
-
const receiver = callee.getExpression();
|
|
133
|
-
const base = Node.isExpression(receiver) ? parseValidator(receiver) : { kind: "any" };
|
|
134
|
-
return applyColumnModifier(base, member);
|
|
135
|
-
}
|
|
136
|
-
if (TRANSPARENT_MODIFIERS.has(member)) {
|
|
137
|
-
const receiver = callee.getExpression();
|
|
138
|
-
const base = Node.isExpression(receiver) ? parseValidator(receiver) : { kind: "any" };
|
|
139
|
-
return member === "check" ? { ...base, hasRefinement: true } : base;
|
|
140
|
-
}
|
|
141
|
-
return parseBuilderMember(member, args);
|
|
142
|
-
};
|
|
143
|
-
|
|
144
|
-
export { parseObjectShape as a, parseValidator as p };
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
const INDEX_SUFFIX = /\/index$/u;
|
|
2
|
-
const NON_IDENTIFIER = /[^\dA-Za-z]/gu;
|
|
3
|
-
const sanitizeNamespace = (filePath) => (
|
|
4
|
-
// `lunora/ratelimit/index.ts` surfaces as `api.ratelimit.*` (and dispatches as
|
|
5
|
-
// `ratelimit:fn`) rather than the noisy `api.ratelimit_index.*` — the registry
|
|
6
|
-
// convention. Only a trailing `/index` is dropped, so `lunora/index.ts` and
|
|
7
|
-
// `lunora/ratelimit/queries.ts` (→ `ratelimit_queries`) are unaffected.
|
|
8
|
-
filePath.replace(INDEX_SUFFIX, "").replaceAll(NON_IDENTIFIER, "_")
|
|
9
|
-
);
|
|
10
|
-
|
|
11
|
-
export { sanitizeNamespace as s };
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
const HIGH_ENTROPY_TOKEN_RE = /[\w+/=-]{40,}/u;
|
|
2
|
-
const LOWER_RE = /[a-z]/u;
|
|
3
|
-
const UPPER_RE = /[A-Z]/u;
|
|
4
|
-
const DIGIT_RE = /\d/u;
|
|
5
|
-
const HEX_SECRET_RE = /\b(?:[\da-f]{32,}|[\dA-F]{32,})\b/u;
|
|
6
|
-
const isHighEntropy = (value) => {
|
|
7
|
-
const token = HIGH_ENTROPY_TOKEN_RE.exec(value)?.[0];
|
|
8
|
-
if (token === void 0) {
|
|
9
|
-
return false;
|
|
10
|
-
}
|
|
11
|
-
return LOWER_RE.test(token) && UPPER_RE.test(token) && DIGIT_RE.test(token);
|
|
12
|
-
};
|
|
13
|
-
const isHexSecret = (value) => HEX_SECRET_RE.test(value);
|
|
14
|
-
const STRIPE_LIVE_KEY_RE = /\b(?:sk|rk)_live_[\dA-Za-z]{20,}/u;
|
|
15
|
-
const AWS_ACCESS_KEY_RE = /\bAKIA[\dA-Z]{16}\b/u;
|
|
16
|
-
const GITHUB_TOKEN_RE = /\bgh[posru]_[\dA-Za-z]{36,}/u;
|
|
17
|
-
const OPENAI_KEY_RE = /\bsk-[\dA-Za-z]{32,}/u;
|
|
18
|
-
const SLACK_TOKEN_RE = /\bxox[abprs]-[\dA-Za-z-]{10,}/u;
|
|
19
|
-
const PRIVATE_KEY_RE = /-----BEGIN(?: [A-Z]+)? PRIVATE KEY-----/u;
|
|
20
|
-
const SECRET_RULES = [
|
|
21
|
-
{ kind: "stripe_live_key", test: (value) => STRIPE_LIVE_KEY_RE.test(value) },
|
|
22
|
-
{ kind: "aws_access_key", test: (value) => AWS_ACCESS_KEY_RE.test(value) },
|
|
23
|
-
{ kind: "github_token", test: (value) => GITHUB_TOKEN_RE.test(value) },
|
|
24
|
-
{ kind: "openai_key", test: (value) => OPENAI_KEY_RE.test(value) },
|
|
25
|
-
{ kind: "slack_token", test: (value) => SLACK_TOKEN_RE.test(value) },
|
|
26
|
-
{ kind: "private_key", test: (value) => PRIVATE_KEY_RE.test(value) },
|
|
27
|
-
{ kind: "high_entropy", test: isHighEntropy },
|
|
28
|
-
{ kind: "hex_secret", test: isHexSecret }
|
|
29
|
-
];
|
|
30
|
-
const secretKindOf = (value) => SECRET_RULES.find((rule) => rule.test(value))?.kind;
|
|
31
|
-
const redact = (value) => `${value.slice(0, 4)}…(${String(value.length)} chars)`;
|
|
32
|
-
|
|
33
|
-
export { SECRET_RULES, redact, secretKindOf };
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
const parseLiteral = (text) => {
|
|
2
|
-
try {
|
|
3
|
-
return JSON.parse(text);
|
|
4
|
-
} catch {
|
|
5
|
-
const trimmed = text.trim();
|
|
6
|
-
if (trimmed.length >= 2 && (trimmed.startsWith("'") || trimmed.startsWith('"')) && trimmed.at(-1) === trimmed[0]) {
|
|
7
|
-
return trimmed.slice(1, -1);
|
|
8
|
-
}
|
|
9
|
-
return trimmed;
|
|
10
|
-
}
|
|
11
|
-
};
|
|
12
|
-
const convertValidator = (ir) => {
|
|
13
|
-
const meta = {};
|
|
14
|
-
if (ir.column !== void 0) {
|
|
15
|
-
meta.column = {
|
|
16
|
-
// A non-undefined `defaultValue` is the sentinel `hasServerDefault`
|
|
17
|
-
// reads to skip the column (the server fills `.default()`/`.$defaultFn()`).
|
|
18
|
-
// eslint-disable-next-line unicorn/no-null -- null is a deliberate non-undefined sentinel here
|
|
19
|
-
defaultValue: ir.column.hasDefault === true ? null : void 0,
|
|
20
|
-
notNull: ir.column.notNull,
|
|
21
|
-
unique: ir.column.unique
|
|
22
|
-
};
|
|
23
|
-
}
|
|
24
|
-
if (ir.inner !== void 0) {
|
|
25
|
-
meta.inner = convertValidator(ir.inner);
|
|
26
|
-
}
|
|
27
|
-
if (ir.members !== void 0) {
|
|
28
|
-
meta.members = ir.members.map((member) => convertValidator(member));
|
|
29
|
-
}
|
|
30
|
-
if (ir.shape !== void 0) {
|
|
31
|
-
meta.shape = Object.fromEntries(Object.entries(ir.shape).map(([field, child]) => [field, convertValidator(child)]));
|
|
32
|
-
}
|
|
33
|
-
if (ir.tableName !== void 0) {
|
|
34
|
-
meta.tableName = ir.tableName;
|
|
35
|
-
}
|
|
36
|
-
if (ir.literalValue !== void 0) {
|
|
37
|
-
meta.value = parseLiteral(ir.literalValue);
|
|
38
|
-
}
|
|
39
|
-
if (ir.keyType !== void 0) {
|
|
40
|
-
meta.keyValidator = convertValidator(ir.keyType);
|
|
41
|
-
}
|
|
42
|
-
if (ir.valueType !== void 0) {
|
|
43
|
-
meta.valueValidator = convertValidator(ir.valueType);
|
|
44
|
-
}
|
|
45
|
-
return { _meta: meta, kind: ir.kind };
|
|
46
|
-
};
|
|
47
|
-
const schemaFromIr = (ir) => {
|
|
48
|
-
const tables = Object.fromEntries(
|
|
49
|
-
ir.tables.map((table) => [
|
|
50
|
-
table.name,
|
|
51
|
-
{ shape: Object.fromEntries(Object.entries(table.shape).map(([field, validator]) => [field, convertValidator(validator)])) }
|
|
52
|
-
])
|
|
53
|
-
);
|
|
54
|
-
return { tables };
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
export { schemaFromIr };
|