@monimesl/dot-script-parser 1.0.0-beta.1 → 1.0.0-beta.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/index.d.ts.map +1 -1
- package/dist/index.js +18 -9
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/globals.ts","../src/dot.ts","../src/errors.ts","../src/ast/expression/types.ts","../src/ast/expression/parse.ts","../src/ast/page/types.ts","../src/ast/page/parse.ts"],"mappings":";;;wBAagB,kBACd,gBACA,0BACA;wBAcc,iBAAiB,gBAAgB,cAAc;;;UCzB9C;WACN;WACA;aAAqB;aAAwB;;;wBAGxC,eAAe,gBAAgB,gBAAkB;;;qBCPpD,yBAAyB;WAClB;;;;cCJP;cAEA;KAoBD;KAEP;WAAyB;WAA0B,OAAO;;KAE1D;WAA4B;WAA6B;;KAEzD;WACM;WACA,QAAQ;WACR,UAAU;;KAGT,wBAAwB;KAE/B;WACM;WACA,UAAU;WACV,UAAU;;KAGT,yBAAyB;KAEhC;WACM;WACA,UAAU;WACV,MAAM;WACN,OAAO;;KAGb;WACM;WACA,MAAM;WACN,YAAY;WACZ,WAAW;;KAGV,WACV,cAAc,iBAAiB,aAAa,gBAAgB,iBAAiB;;;wBCpD/D,gBAAgB,iBAAiB;;;UCPhC;WAEN;WAEA,YAAY,SAAS;;UAGf;WACN;WAEA;WACA;WACA;WACA;WAEA,gBAAgB,SAAS;;;;wBCHpB,iBAAiB,gBAAgB,gBAAoB;
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/globals.ts","../src/dot.ts","../src/errors.ts","../src/ast/expression/types.ts","../src/ast/expression/parse.ts","../src/ast/page/types.ts","../src/ast/page/parse.ts"],"mappings":";;;wBAagB,kBACd,gBACA,0BACA;wBAcc,iBAAiB,gBAAgB,cAAc;;;UCzB9C;WACN;WACA;aAAqB;aAAwB;;;wBAGxC,eAAe,gBAAgB,gBAAkB;;;qBCPpD,yBAAyB;WAClB;;;;cCJP;cAEA;KAoBD;KAEP;WAAyB;WAA0B,OAAO;;KAE1D;WAA4B;WAA6B;;KAEzD;WACM;WACA,QAAQ;WACR,UAAU;;KAGT,wBAAwB;KAE/B;WACM;WACA,UAAU;WACV,UAAU;;KAGT,yBAAyB;KAEhC;WACM;WACA,UAAU;WACV,MAAM;WACN,OAAO;;KAGb;WACM;WACA,MAAM;WACN,YAAY;WACZ,WAAW;;KAGV,WACV,cAAc,iBAAiB,aAAa,gBAAgB,iBAAiB;;;wBCpD/D,gBAAgB,iBAAiB;;;UCPhC;WAEN;WAEA,YAAY,SAAS;;UAGf;WACN;WAEA;WACA;WACA;WACA;WAEA,gBAAgB,SAAS;;;;wBCHpB,iBAAiB,gBAAgB,gBAAoB;wBAkBrD,iBAAiB,gBAAgB,gBAAyB"}
|
package/dist/index.js
CHANGED
|
@@ -175,7 +175,7 @@ const SHARE_EXAMPLE = "such as share: { options: ['show'] }";
|
|
|
175
175
|
function parseStateModule(source, file = "state.ts") {
|
|
176
176
|
const program = parseModule(source, file);
|
|
177
177
|
const exported = defaultExport(program);
|
|
178
|
-
if (!exported) return failAt("state.ts must have a default export", source, 0, file);
|
|
178
|
+
if (!exported) return failAt("state.ts must have a default export, such as export default { count: 0 }", source, 0, file);
|
|
179
179
|
const properties = resolvedProperties(program, exported);
|
|
180
180
|
return {
|
|
181
181
|
keys: namesOf(properties),
|
|
@@ -215,7 +215,7 @@ function parseLogicModule(source, file = "controller.ts") {
|
|
|
215
215
|
const actionNames = namesOf(actions);
|
|
216
216
|
if (mutationNames && actionNames) {
|
|
217
217
|
const clash = mutationNames.find((name) => actionNames.includes(name));
|
|
218
|
-
if (clash) failAt(`\`${clash}\` is both a mutation and an action`, source, options.start, file);
|
|
218
|
+
if (clash) failAt(`\`${clash}\` is both a mutation and an action. Rename one of them`, source, options.start, file);
|
|
219
219
|
}
|
|
220
220
|
return {
|
|
221
221
|
id,
|
|
@@ -240,10 +240,10 @@ function readSharedOptions(node, source, file) {
|
|
|
240
240
|
if (!element || element.type !== "Literal" || typeof element.value !== "string") return failAt(`share's options must be names written as strings, ${SHARE_EXAMPLE}`, source, element?.start ?? list.start, file);
|
|
241
241
|
const name = element.value;
|
|
242
242
|
if (!isSharedOptionName(name)) return failAt(`"${name}" can't go in a link. Use letters, digits, "-" and "_"`, source, element.start, file);
|
|
243
|
-
if (options.includes(name)) return failAt(`"${name}" is in share's options twice`, source, element.start, file);
|
|
243
|
+
if (options.includes(name)) return failAt(`"${name}" is in share's options twice. Remove one`, source, element.start, file);
|
|
244
244
|
options.push(name);
|
|
245
245
|
}
|
|
246
|
-
if (options.length > MAX_SHARED_OPTIONS) return failAt(`A link can carry at most ${MAX_SHARED_OPTIONS} options`, source, list.start, file);
|
|
246
|
+
if (options.length > MAX_SHARED_OPTIONS) return failAt(`A link can carry at most ${MAX_SHARED_OPTIONS} options. Remove some from share's options`, source, list.start, file);
|
|
247
247
|
}
|
|
248
248
|
return options;
|
|
249
249
|
}
|
|
@@ -408,16 +408,25 @@ function toExprNode(node, source) {
|
|
|
408
408
|
alternate: toExprNode(node.alternate, source)
|
|
409
409
|
};
|
|
410
410
|
case "CallExpression":
|
|
411
|
-
case "NewExpression": return failAt("Bindings can't call functions", source, node.start);
|
|
411
|
+
case "NewExpression": return failAt("Bindings can't call functions. Work the value out in controller.ts and keep it in state", source, node.start);
|
|
412
412
|
case "AssignmentExpression":
|
|
413
|
-
case "UpdateExpression": return failAt("Bindings can't change values", source, node.start);
|
|
413
|
+
case "UpdateExpression": return failAt("Bindings can't change values. Change state in a mutation instead", source, node.start);
|
|
414
414
|
default: return failUnsupported(node, source);
|
|
415
415
|
}
|
|
416
416
|
}
|
|
417
|
+
const UNSUPPORTED_EXPRESSIONS = {
|
|
418
|
+
ArrayExpression: "lists",
|
|
419
|
+
ObjectExpression: "objects",
|
|
420
|
+
ArrowFunctionExpression: "functions",
|
|
421
|
+
FunctionExpression: "functions",
|
|
422
|
+
TemplateLiteral: "template strings",
|
|
423
|
+
SequenceExpression: "commas",
|
|
424
|
+
ThisExpression: "`this`"
|
|
425
|
+
};
|
|
417
426
|
function failUnsupported(node, source) {
|
|
418
|
-
let
|
|
419
|
-
if ("operator" in node)
|
|
420
|
-
return failAt(`Bindings can't use ${
|
|
427
|
+
let unsupported = UNSUPPORTED_EXPRESSIONS[node.type] ?? "this kind of expression";
|
|
428
|
+
if ("operator" in node) unsupported = `\`${node.operator}\``;
|
|
429
|
+
return failAt(`Bindings can't use ${unsupported}. Work the value out in controller.ts and keep it in state`, source, node.start);
|
|
421
430
|
}
|
|
422
431
|
function isOneOf(list, value) {
|
|
423
432
|
return list.includes(value);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../src/utils.ts","../src/errors.ts","../src/module.ts","../src/globals.ts","../src/ast/page/parse.ts","../src/dot.ts","../src/ast/expression/types.ts","../src/ast/expression/parse.ts"],"sourcesContent":["import type { Expression, ObjectExpression, Program, PropertyKey } from 'oxc-parser';\n\ntype TopLevelStatement = Program['body'][number];\n\nfunction propertyName(key: PropertyKey): string | null {\n if (key.type === 'Identifier') {\n return key.name;\n }\n if (key.type === 'Literal' && typeof key.value === 'string') {\n return key.value;\n }\n return null;\n}\n\nexport function unwrapExpression(node: Expression): Expression {\n while (\n node.type === 'TSAsExpression' ||\n node.type === 'TSSatisfiesExpression' ||\n node.type === 'TSNonNullExpression'\n ) {\n node = node.expression;\n }\n return node;\n}\n\nexport interface StaticProperty {\n readonly name: string;\n readonly value: Expression;\n readonly start: number;\n}\n\n// The properties of an object literal whose names are written out. Computed ones are skipped.\nexport function staticProperties(object: ObjectExpression): StaticProperty[] {\n const properties: StaticProperty[] = [];\n for (const property of object.properties) {\n if (property.type !== 'Property' || property.computed) {\n continue;\n }\n const name = propertyName(property.key);\n if (name !== null) {\n properties.push({ name, value: property.value, start: property.start });\n }\n }\n return properties;\n}\n\n// Unwraps `export const ...` and the like to the declaration. Other statements pass through.\nexport function withoutExport(statement: TopLevelStatement): TopLevelStatement | null {\n if (statement.type === 'ExportNamedDeclaration') {\n return statement.declaration;\n }\n return statement;\n}\n","import type { OxcError } from 'oxc-parser';\nimport { locationAt, SourceError } from '@monimesl/dot-core';\n\nexport class ScriptParseError extends SourceError {\n override readonly name = 'ScriptParseError';\n}\n\nexport function failAt(reason: string, source: string, offset: number, file?: string): never {\n throw new ScriptParseError(reason, file, locationAt(source, offset));\n}\n\nexport function failOnSyntaxError(\n errors: readonly OxcError[],\n source: string,\n file?: string,\n): void {\n const [error] = errors;\n if (error) {\n failAt(error.message, source, error.labels[0]?.start ?? 0, file);\n }\n}\n","import { parseSync } from 'oxc-parser';\nimport type { Expression, ObjectExpression, Program } from 'oxc-parser';\n\nimport { unwrapExpression } from './utils';\nimport { failAt, failOnSyntaxError } from './errors';\n\nexport function parseModule(source: string, file: string): Program {\n const { program, errors } = parseSync(file, source, { lang: 'ts', sourceType: 'module' });\n failOnSyntaxError(errors, source, file);\n return program;\n}\n\nexport function defaultExport(program: Program): Expression | undefined {\n for (const statement of program.body) {\n if (statement.type !== 'ExportDefaultDeclaration') {\n continue;\n }\n const { declaration } = statement;\n switch (declaration.type) {\n case 'FunctionDeclaration':\n case 'ClassDeclaration':\n case 'TSInterfaceDeclaration':\n return undefined;\n default:\n return declaration;\n }\n }\n return undefined;\n}\n\n// The `{ ... }` in `export default <callee>({ ... })`.\nexport function defineCall(\n program: Program,\n source: string,\n file: string,\n callee: string,\n): ObjectExpression {\n const exported = defaultExport(program);\n let options: ObjectExpression | undefined;\n if (exported) {\n options = callOptions(unwrapExpression(exported), callee);\n }\n if (!options) {\n return failAt(\n `${fileName(file)} must \\`export default ${callee}({ ... })\\``,\n source,\n exported?.start ?? 0,\n file,\n );\n }\n return options;\n}\n\nfunction callOptions(expression: Expression, callee: string): ObjectExpression | undefined {\n if (expression.type !== 'CallExpression') {\n return undefined;\n }\n if (expression.callee.type !== 'Identifier' || expression.callee.name !== callee) {\n return undefined;\n }\n const [options] = expression.arguments;\n if (options?.type !== 'ObjectExpression') {\n return undefined;\n }\n return options;\n}\n\n// The last segment of a path, with either separator.\nfunction fileName(path: string): string {\n const lastSeparator = Math.max(path.lastIndexOf('/'), path.lastIndexOf('\\\\'));\n return path.slice(lastSeparator + 1);\n}\n","import type { Program } from 'oxc-parser';\n\nimport { parseModule } from './module';\nimport { withoutExport } from './utils';\n\ninterface Node {\n readonly type: string;\n readonly [key: string]: unknown;\n}\n\ntype ReferenceVisitor = (identifier: Node, parent: Node | null, key: string) => void;\n\n// Which of `names` a module uses without declaring or importing, for the compiler to import.\nexport function unboundReferences(\n source: string,\n names: readonly string[],\n file = 'module.ts',\n): string[] {\n const program = parseModule(source, file);\n const bound = topLevelBindings(program);\n const references = new Set<string>();\n forEachReference(program, (identifier) => {\n references.add(identifier.name as string);\n });\n return names.filter((name) => references.has(name) && !bound.has(name));\n}\n\n// The first property read off each use of the global `name`, such as \"utils\" for\n// `dash.utils.base64.encode(text)`, and \"\" for a use that reads none, such as passing it along.\n// None when the module declares or imports its own `name`.\nexport function globalMemberUses(source: string, name: string, file = 'module.ts'): string[] {\n const program = parseModule(source, file);\n if (topLevelBindings(program).has(name)) {\n return [];\n }\n const uses: string[] = [];\n forEachReference(program, (identifier, parent, key) => {\n if (identifier.name === name) {\n uses.push(memberRead(parent, key));\n }\n });\n return uses;\n}\n\n// The property name in `name.property`, or \"\" when the identifier isn't read that way.\nfunction memberRead(parent: Node | null, key: string): string {\n if (parent?.type !== 'MemberExpression' || key !== 'object' || parent.computed === true) {\n return '';\n }\n const property = parent.property as Node | undefined;\n if (property?.type !== 'Identifier') {\n return '';\n }\n return property.name as string;\n}\n\nfunction topLevelBindings(program: Program): Set<string> {\n const names = new Set<string>();\n for (const statement of program.body) {\n const declaration = withoutExport(statement);\n switch (declaration?.type) {\n case 'ImportDeclaration':\n for (const specifier of declaration.specifiers) {\n names.add(specifier.local.name);\n }\n break;\n case 'VariableDeclaration':\n for (const declarator of declaration.declarations) {\n collectPatternNames(declarator.id, names);\n }\n break;\n case 'FunctionDeclaration':\n case 'ClassDeclaration':\n if (declaration.id) {\n names.add(declaration.id.name);\n }\n break;\n }\n }\n return names;\n}\n\nfunction collectPatternNames(pattern: unknown, names: Set<string>): void {\n if (!isNode(pattern)) {\n return;\n }\n switch (pattern.type) {\n case 'Identifier':\n names.add(pattern.name as string);\n break;\n case 'ObjectPattern':\n for (const property of pattern.properties as Node[]) {\n if (property.type === 'RestElement') {\n collectPatternNames(property.argument, names);\n } else {\n collectPatternNames(property.value, names);\n }\n }\n break;\n case 'ArrayPattern':\n for (const element of pattern.elements as unknown[]) {\n collectPatternNames(element, names);\n }\n break;\n case 'RestElement':\n collectPatternNames(pattern.argument, names);\n break;\n case 'AssignmentPattern':\n collectPatternNames(pattern.left, names);\n break;\n }\n}\n\n// Visits each identifier that refers to a variable, in source order. Imports are skipped, since\n// they declare names rather than use them.\nfunction forEachReference(program: Program, visit: ReferenceVisitor): void {\n visitReferences(program as unknown as Node, null, '', visit);\n}\n\nfunction visitReferences(\n node: Node,\n parent: Node | null,\n key: string,\n visit: ReferenceVisitor,\n): void {\n if (node.type === 'ImportDeclaration') {\n return;\n }\n if (node.type === 'Identifier' && isReference(parent, key)) {\n visit(node, parent, key);\n }\n for (const [childKey, value] of Object.entries(node)) {\n const children: unknown[] = Array.isArray(value) ? value : [value];\n for (const child of children) {\n if (isNode(child)) {\n visitReferences(child, node, childKey, visit);\n }\n }\n }\n}\n\n// False for identifiers that name a property or label rather than refer to a variable.\nfunction isReference(parent: Node | null, key: string): boolean {\n switch (parent?.type) {\n case 'MemberExpression':\n return key !== 'property' || parent.computed === true;\n case 'Property':\n case 'MethodDefinition':\n case 'PropertyDefinition':\n return key !== 'key' || parent.computed === true;\n case 'LabeledStatement':\n case 'BreakStatement':\n case 'ContinueStatement':\n return key !== 'label';\n default:\n return true;\n }\n}\n\nfunction isNode(value: unknown): value is Node {\n if (typeof value !== 'object' || value === null) {\n return false;\n }\n return typeof (value as { type?: unknown }).type === 'string';\n}\n","import { isPageId, isSharedOptionName, MAX_SHARED_OPTIONS, PAGE_HOOKS } from '@monimesl/dot-core';\nimport type { Expression, ObjectExpression, Program } from 'oxc-parser';\n\nimport type { PageModule, PageStateModule } from './types';\nimport { failAt } from '../../errors';\nimport { defaultExport, defineCall, parseModule } from '../../module';\nimport type { StaticProperty } from '../../utils';\nimport { staticProperties, unwrapExpression, withoutExport } from '../../utils';\n\nconst HOOKS = new Set<string>(PAGE_HOOKS);\nconst SHARE_EXAMPLE = \"such as share: { options: ['show'] }\";\n\nexport function parseStateModule(source: string, file = 'state.ts'): PageStateModule {\n const program = parseModule(source, file);\n const exported = defaultExport(program);\n if (!exported) {\n return failAt('state.ts must have a default export', source, 0, file);\n }\n const properties = resolvedProperties(program, exported);\n return {\n keys: namesOf(properties),\n keyOffsets: offsetsOf(properties ?? []),\n };\n}\n\nexport function parseLogicModule(source: string, file = 'controller.ts'): PageModule {\n const program = parseModule(source, file);\n const options = defineCall(program, source, file, 'definePage');\n let id: string | null = null;\n let share: string[] | null = null;\n let mutations: StaticProperty[] | null = [];\n let actions: StaticProperty[] | null = [];\n const hooks: string[] = [];\n for (const { name, value, start } of staticProperties(options)) {\n switch (name) {\n case 'initialState':\n case 'configs':\n break;\n case 'id':\n id = readPageId(value, source, file);\n break;\n case 'share':\n share = readSharedOptions(value, source, file);\n break;\n case 'hooks':\n hooks.push(...readHooks(value, source, file));\n break;\n case 'mutations':\n mutations = resolvedProperties(program, value);\n break;\n case 'actions':\n actions = resolvedProperties(program, value);\n break;\n default:\n if (isFunction(value)) {\n failAt(`\\`${name}\\` must go in \\`mutations\\` or \\`actions\\``, source, start, file);\n } else {\n failAt(\n `Unknown option \\`${name}\\`. definePage takes id, initialState, configs, share, hooks, mutations and actions`,\n source,\n start,\n file,\n );\n }\n }\n }\n const mutationNames = namesOf(mutations);\n const actionNames = namesOf(actions);\n if (mutationNames && actionNames) {\n const clash = mutationNames.find((name) => actionNames.includes(name));\n if (clash) {\n failAt(`\\`${clash}\\` is both a mutation and an action`, source, options.start, file);\n }\n }\n return {\n id,\n share,\n mutations: mutationNames,\n actions: actionNames,\n hooks,\n handlerOffsets: offsetsOf([...(mutations ?? []), ...(actions ?? [])]),\n };\n}\n\n// `share: { options: ['show'] }`, written out so the build can read it.\nfunction readSharedOptions(node: Expression, source: string, file: string): string[] {\n const object = unwrapExpression(node);\n if (object.type !== 'ObjectExpression') {\n return failAt(`Write \\`share\\` out in place, ${SHARE_EXAMPLE}`, source, node.start, file);\n }\n const properties = staticProperties(object);\n if (properties.length !== object.properties.length) {\n return failAt(`Write \\`share\\` out in place, ${SHARE_EXAMPLE}`, source, object.start, file);\n }\n const options: string[] = [];\n for (const property of properties) {\n if (property.name !== 'options') {\n return failAt(\n `Unknown share option \\`${property.name}\\`. share only takes options`,\n source,\n property.start,\n file,\n );\n }\n const list = unwrapExpression(property.value);\n if (list.type !== 'ArrayExpression') {\n return failAt(\n `share's options must be a list of names, ${SHARE_EXAMPLE}`,\n source,\n list.start,\n file,\n );\n }\n for (const element of list.elements) {\n if (!element || element.type !== 'Literal' || typeof element.value !== 'string') {\n return failAt(\n `share's options must be names written as strings, ${SHARE_EXAMPLE}`,\n source,\n element?.start ?? list.start,\n file,\n );\n }\n const name = element.value;\n if (!isSharedOptionName(name)) {\n return failAt(\n `\"${name}\" can't go in a link. Use letters, digits, \"-\" and \"_\"`,\n source,\n element.start,\n file,\n );\n }\n if (options.includes(name)) {\n return failAt(`\"${name}\" is in share's options twice`, source, element.start, file);\n }\n options.push(name);\n }\n if (options.length > MAX_SHARED_OPTIONS) {\n return failAt(\n `A link can carry at most ${MAX_SHARED_OPTIONS} options`,\n source,\n list.start,\n file,\n );\n }\n }\n return options;\n}\n\n// Only hooks written in an object literal are checked.\nfunction readHooks(node: Expression, source: string, file: string): string[] {\n if (node.type !== 'ObjectExpression') {\n return [];\n }\n const hooks: string[] = [];\n for (const hook of staticProperties(node)) {\n if (!HOOKS.has(hook.name)) {\n failAt(\n `Unknown page hook \\`${hook.name}\\`. The hooks are ${PAGE_HOOKS.join(', ')}`,\n source,\n hook.start,\n file,\n );\n }\n hooks.push(hook.name);\n }\n return hooks;\n}\n\nfunction isFunction(node: Expression): boolean {\n return node.type === 'FunctionExpression' || node.type === 'ArrowFunctionExpression';\n}\n\n// The properties of the object literal that `node` is or names. Null when any can't be read\n// without running the code.\nfunction resolvedProperties(program: Program, node: Expression): StaticProperty[] | null {\n const object = resolveObject(program, node);\n if (!object) {\n return null;\n }\n const properties = staticProperties(object);\n if (properties.length !== object.properties.length) {\n return null;\n }\n return properties;\n}\n\nfunction namesOf(properties: readonly StaticProperty[] | null): string[] | null {\n if (properties === null) {\n return null;\n }\n return properties.map((property) => property.name);\n}\n\nfunction offsetsOf(properties: readonly StaticProperty[]): Record<string, number> {\n const offsets: Record<string, number> = {};\n for (const property of properties) {\n offsets[property.name] = property.start;\n }\n return offsets;\n}\n\n// Follows `export default state` back to `const state = { ... }`.\nfunction resolveObject(program: Program, node: Expression): ObjectExpression | null {\n const target = unwrapExpression(node);\n if (target.type === 'ObjectExpression') {\n return target;\n }\n if (target.type !== 'Identifier') {\n return null;\n }\n for (const statement of program.body) {\n const declaration = withoutExport(statement);\n if (declaration?.type !== 'VariableDeclaration' || declaration.kind !== 'const') {\n continue;\n }\n for (const declarator of declaration.declarations) {\n if (declarator.id.type !== 'Identifier' || declarator.id.name !== target.name) {\n continue;\n }\n if (!declarator.init) {\n return null;\n }\n return resolveObject(program, declarator.init);\n }\n }\n return null;\n}\n\nexport function readPageId(node: Expression, source: string, file: string): string {\n const value = unwrapExpression(node);\n if (value.type !== 'Literal' || typeof value.value !== 'string') {\n return failAt(\n \"A page id must be written as a string, such as 'cart'\",\n source,\n node.start,\n file,\n );\n }\n if (!isPageId(value.value)) {\n return failAt(\n `\"${value.value}\" isn't a valid page id. Use letters, digits, \"-\" and \"_\", with \"/\" between folders`,\n source,\n node.start,\n file,\n );\n }\n return value.value;\n}\n","import { failAt } from './errors';\nimport { readPageId } from './ast/page/parse';\nimport { defineCall, parseModule } from './module';\nimport { staticProperties, unwrapExpression } from './utils';\n\nexport interface DotModuleIR {\n readonly pages: readonly string[];\n readonly lastPage: { readonly start: number; readonly end: number };\n}\n\nexport function parseDotModule(source: string, file = 'dot.ts'): DotModuleIR {\n const program = parseModule(source, file);\n const options = defineCall(program, source, file, 'defineDot');\n const pagesProperty = staticProperties(options).find((property) => property.name === 'pages');\n if (!pagesProperty) {\n return failAt(\n 'defineDot needs `pages`, a list of page folders with the entry page first',\n source,\n options.start,\n file,\n );\n }\n const { value, start } = pagesProperty;\n const pageList = unwrapExpression(value);\n if (pageList.type !== 'ArrayExpression') {\n return failAt('`pages` must be a list of page folders', source, start, file);\n }\n if (pageList.elements.length === 0) {\n return failAt('`pages` needs at least one page', source, start, file);\n }\n const pages = pageList.elements.map((element) => {\n if (!element || element.type === 'SpreadElement') {\n return failAt(\n '`pages` must list each page folder as a string',\n source,\n element?.start ?? start,\n file,\n );\n }\n return readPageId(element, source, file);\n });\n // The check above fails on a hole, so the last element is there.\n const lastPage = pageList.elements.at(-1)!;\n return { pages, lastPage: { start: lastPage.start, end: lastPage.end } };\n}\n","export const UNARY_OPERATORS = ['!', '-', '+', 'typeof'] as const;\n\nexport const BINARY_OPERATORS = [\n '==',\n '!=',\n '===',\n '!==',\n '<',\n '<=',\n '>',\n '>=',\n '+',\n '-',\n '*',\n '/',\n '%',\n '**',\n '&&',\n '||',\n '??',\n] as const;\n\nexport type LiteralValue = string | number | boolean | null;\n\ntype LiteralNode = { readonly type: 'Literal'; readonly value: LiteralValue };\n\ntype IdentifierNode = { readonly type: 'Identifier'; readonly name: string };\n\ntype MemberNode = {\n readonly type: 'Member';\n readonly object: ExprNode;\n readonly property: ExprNode;\n};\n\nexport type UnaryOperator = (typeof UNARY_OPERATORS)[number];\n\ntype UnaryExprNode = {\n readonly type: 'Unary';\n readonly operator: UnaryOperator;\n readonly argument: ExprNode;\n};\n\nexport type BinaryOperator = (typeof BINARY_OPERATORS)[number];\n\ntype BinaryExprNode = {\n readonly type: 'Binary';\n readonly operator: BinaryOperator;\n readonly left: ExprNode;\n readonly right: ExprNode;\n};\n\ntype ConditionalExprNode = {\n readonly type: 'Conditional';\n readonly test: ExprNode;\n readonly consequent: ExprNode;\n readonly alternate: ExprNode;\n};\n\nexport type ExprNode =\n LiteralNode | IdentifierNode | MemberNode | UnaryExprNode | BinaryExprNode | ConditionalExprNode;\n","import type { Expression } from 'oxc-parser';\nimport { parseSync } from 'oxc-parser';\n\nimport { failAt, failOnSyntaxError } from '../../errors';\nimport { BINARY_OPERATORS, type ExprNode, UNARY_OPERATORS } from './types';\n\n// Parses what's inside a `{{ }}` binding into an expression tree.\nexport function parseExpression(source: string): ExprNode {\n if (source.trim().length === 0) {\n failAt('The binding is empty', source, 0);\n }\n const { program, errors } = parseSync('binding.js', source, { preserveParens: false });\n failOnSyntaxError(errors, source);\n const statement = program.body[0];\n if (program.body.length !== 1 || statement?.type !== 'ExpressionStatement') {\n return failAt('A binding must be one expression', source, statement?.start ?? 0);\n }\n return toExprNode(statement.expression, source);\n}\n\nfunction toExprNode(node: Expression, source: string): ExprNode {\n switch (node.type) {\n case 'Literal':\n if (typeof node.value === 'bigint' || node.value instanceof RegExp) {\n return failUnsupported(node, source);\n }\n return { type: 'Literal', value: node.value };\n case 'Identifier':\n return { type: 'Identifier', name: node.name };\n case 'MemberExpression': {\n if (node.object.type === 'Super' || node.property.type === 'PrivateIdentifier') {\n return failUnsupported(node, source);\n }\n const object = toExprNode(node.object, source);\n if (node.computed) {\n return { type: 'Member', object, property: toExprNode(node.property, source) };\n }\n return { type: 'Member', object, property: { type: 'Literal', value: node.property.name } };\n }\n case 'UnaryExpression':\n if (!isOneOf(UNARY_OPERATORS, node.operator)) {\n return failUnsupported(node, source);\n }\n return {\n type: 'Unary',\n operator: node.operator,\n argument: toExprNode(node.argument, source),\n };\n case 'BinaryExpression':\n case 'LogicalExpression':\n if (node.left.type === 'PrivateIdentifier' || !isOneOf(BINARY_OPERATORS, node.operator)) {\n return failUnsupported(node, source);\n }\n return {\n type: 'Binary',\n operator: node.operator,\n left: toExprNode(node.left, source),\n right: toExprNode(node.right, source),\n };\n case 'ConditionalExpression':\n return {\n type: 'Conditional',\n test: toExprNode(node.test, source),\n consequent: toExprNode(node.consequent, source),\n alternate: toExprNode(node.alternate, source),\n };\n case 'CallExpression':\n case 'NewExpression':\n return failAt(\"Bindings can't call functions\", source, node.start);\n case 'AssignmentExpression':\n case 'UpdateExpression':\n return failAt(\"Bindings can't change values\", source, node.start);\n default:\n return failUnsupported(node, source);\n }\n}\n\nfunction failUnsupported(node: Expression, source: string): never {\n let detail = '';\n if ('operator' in node) {\n detail = ` \\`${node.operator}\\``;\n }\n return failAt(`Bindings can't use ${node.type}${detail}`, source, node.start);\n}\n\nfunction isOneOf<T extends string>(list: readonly T[], value: string): value is T {\n return (list as readonly string[]).includes(value);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/utils.ts","../src/errors.ts","../src/module.ts","../src/globals.ts","../src/ast/page/parse.ts","../src/dot.ts","../src/ast/expression/types.ts","../src/ast/expression/parse.ts"],"sourcesContent":["import type { Expression, ObjectExpression, Program, PropertyKey } from 'oxc-parser';\n\ntype TopLevelStatement = Program['body'][number];\n\nfunction propertyName(key: PropertyKey): string | null {\n if (key.type === 'Identifier') {\n return key.name;\n }\n if (key.type === 'Literal' && typeof key.value === 'string') {\n return key.value;\n }\n return null;\n}\n\nexport function unwrapExpression(node: Expression): Expression {\n while (\n node.type === 'TSAsExpression' ||\n node.type === 'TSSatisfiesExpression' ||\n node.type === 'TSNonNullExpression'\n ) {\n node = node.expression;\n }\n return node;\n}\n\nexport interface StaticProperty {\n readonly name: string;\n readonly value: Expression;\n readonly start: number;\n}\n\n// The properties of an object literal whose names are written out. Computed ones are skipped.\nexport function staticProperties(object: ObjectExpression): StaticProperty[] {\n const properties: StaticProperty[] = [];\n for (const property of object.properties) {\n if (property.type !== 'Property' || property.computed) {\n continue;\n }\n const name = propertyName(property.key);\n if (name !== null) {\n properties.push({ name, value: property.value, start: property.start });\n }\n }\n return properties;\n}\n\n// Unwraps `export const ...` and the like to the declaration. Other statements pass through.\nexport function withoutExport(statement: TopLevelStatement): TopLevelStatement | null {\n if (statement.type === 'ExportNamedDeclaration') {\n return statement.declaration;\n }\n return statement;\n}\n","import type { OxcError } from 'oxc-parser';\nimport { locationAt, SourceError } from '@monimesl/dot-core';\n\nexport class ScriptParseError extends SourceError {\n override readonly name = 'ScriptParseError';\n}\n\nexport function failAt(reason: string, source: string, offset: number, file?: string): never {\n throw new ScriptParseError(reason, file, locationAt(source, offset));\n}\n\nexport function failOnSyntaxError(\n errors: readonly OxcError[],\n source: string,\n file?: string,\n): void {\n const [error] = errors;\n if (error) {\n failAt(error.message, source, error.labels[0]?.start ?? 0, file);\n }\n}\n","import { parseSync } from 'oxc-parser';\nimport type { Expression, ObjectExpression, Program } from 'oxc-parser';\n\nimport { unwrapExpression } from './utils';\nimport { failAt, failOnSyntaxError } from './errors';\n\nexport function parseModule(source: string, file: string): Program {\n const { program, errors } = parseSync(file, source, { lang: 'ts', sourceType: 'module' });\n failOnSyntaxError(errors, source, file);\n return program;\n}\n\nexport function defaultExport(program: Program): Expression | undefined {\n for (const statement of program.body) {\n if (statement.type !== 'ExportDefaultDeclaration') {\n continue;\n }\n const { declaration } = statement;\n switch (declaration.type) {\n case 'FunctionDeclaration':\n case 'ClassDeclaration':\n case 'TSInterfaceDeclaration':\n return undefined;\n default:\n return declaration;\n }\n }\n return undefined;\n}\n\n// The `{ ... }` in `export default <callee>({ ... })`.\nexport function defineCall(\n program: Program,\n source: string,\n file: string,\n callee: string,\n): ObjectExpression {\n const exported = defaultExport(program);\n let options: ObjectExpression | undefined;\n if (exported) {\n options = callOptions(unwrapExpression(exported), callee);\n }\n if (!options) {\n return failAt(\n `${fileName(file)} must \\`export default ${callee}({ ... })\\``,\n source,\n exported?.start ?? 0,\n file,\n );\n }\n return options;\n}\n\nfunction callOptions(expression: Expression, callee: string): ObjectExpression | undefined {\n if (expression.type !== 'CallExpression') {\n return undefined;\n }\n if (expression.callee.type !== 'Identifier' || expression.callee.name !== callee) {\n return undefined;\n }\n const [options] = expression.arguments;\n if (options?.type !== 'ObjectExpression') {\n return undefined;\n }\n return options;\n}\n\n// The last segment of a path, with either separator.\nfunction fileName(path: string): string {\n const lastSeparator = Math.max(path.lastIndexOf('/'), path.lastIndexOf('\\\\'));\n return path.slice(lastSeparator + 1);\n}\n","import type { Program } from 'oxc-parser';\n\nimport { parseModule } from './module';\nimport { withoutExport } from './utils';\n\ninterface Node {\n readonly type: string;\n readonly [key: string]: unknown;\n}\n\ntype ReferenceVisitor = (identifier: Node, parent: Node | null, key: string) => void;\n\n// Which of `names` a module uses without declaring or importing, for the compiler to import.\nexport function unboundReferences(\n source: string,\n names: readonly string[],\n file = 'module.ts',\n): string[] {\n const program = parseModule(source, file);\n const bound = topLevelBindings(program);\n const references = new Set<string>();\n forEachReference(program, (identifier) => {\n references.add(identifier.name as string);\n });\n return names.filter((name) => references.has(name) && !bound.has(name));\n}\n\n// The first property read off each use of the global `name`, such as \"utils\" for\n// `dash.utils.base64.encode(text)`, and \"\" for a use that reads none, such as passing it along.\n// None when the module declares or imports its own `name`.\nexport function globalMemberUses(source: string, name: string, file = 'module.ts'): string[] {\n const program = parseModule(source, file);\n if (topLevelBindings(program).has(name)) {\n return [];\n }\n const uses: string[] = [];\n forEachReference(program, (identifier, parent, key) => {\n if (identifier.name === name) {\n uses.push(memberRead(parent, key));\n }\n });\n return uses;\n}\n\n// The property name in `name.property`, or \"\" when the identifier isn't read that way.\nfunction memberRead(parent: Node | null, key: string): string {\n if (parent?.type !== 'MemberExpression' || key !== 'object' || parent.computed === true) {\n return '';\n }\n const property = parent.property as Node | undefined;\n if (property?.type !== 'Identifier') {\n return '';\n }\n return property.name as string;\n}\n\nfunction topLevelBindings(program: Program): Set<string> {\n const names = new Set<string>();\n for (const statement of program.body) {\n const declaration = withoutExport(statement);\n switch (declaration?.type) {\n case 'ImportDeclaration':\n for (const specifier of declaration.specifiers) {\n names.add(specifier.local.name);\n }\n break;\n case 'VariableDeclaration':\n for (const declarator of declaration.declarations) {\n collectPatternNames(declarator.id, names);\n }\n break;\n case 'FunctionDeclaration':\n case 'ClassDeclaration':\n if (declaration.id) {\n names.add(declaration.id.name);\n }\n break;\n }\n }\n return names;\n}\n\nfunction collectPatternNames(pattern: unknown, names: Set<string>): void {\n if (!isNode(pattern)) {\n return;\n }\n switch (pattern.type) {\n case 'Identifier':\n names.add(pattern.name as string);\n break;\n case 'ObjectPattern':\n for (const property of pattern.properties as Node[]) {\n if (property.type === 'RestElement') {\n collectPatternNames(property.argument, names);\n } else {\n collectPatternNames(property.value, names);\n }\n }\n break;\n case 'ArrayPattern':\n for (const element of pattern.elements as unknown[]) {\n collectPatternNames(element, names);\n }\n break;\n case 'RestElement':\n collectPatternNames(pattern.argument, names);\n break;\n case 'AssignmentPattern':\n collectPatternNames(pattern.left, names);\n break;\n }\n}\n\n// Visits each identifier that refers to a variable, in source order. Imports are skipped, since\n// they declare names rather than use them.\nfunction forEachReference(program: Program, visit: ReferenceVisitor): void {\n visitReferences(program as unknown as Node, null, '', visit);\n}\n\nfunction visitReferences(\n node: Node,\n parent: Node | null,\n key: string,\n visit: ReferenceVisitor,\n): void {\n if (node.type === 'ImportDeclaration') {\n return;\n }\n if (node.type === 'Identifier' && isReference(parent, key)) {\n visit(node, parent, key);\n }\n for (const [childKey, value] of Object.entries(node)) {\n const children: unknown[] = Array.isArray(value) ? value : [value];\n for (const child of children) {\n if (isNode(child)) {\n visitReferences(child, node, childKey, visit);\n }\n }\n }\n}\n\n// False for identifiers that name a property or label rather than refer to a variable.\nfunction isReference(parent: Node | null, key: string): boolean {\n switch (parent?.type) {\n case 'MemberExpression':\n return key !== 'property' || parent.computed === true;\n case 'Property':\n case 'MethodDefinition':\n case 'PropertyDefinition':\n return key !== 'key' || parent.computed === true;\n case 'LabeledStatement':\n case 'BreakStatement':\n case 'ContinueStatement':\n return key !== 'label';\n default:\n return true;\n }\n}\n\nfunction isNode(value: unknown): value is Node {\n if (typeof value !== 'object' || value === null) {\n return false;\n }\n return typeof (value as { type?: unknown }).type === 'string';\n}\n","import { isPageId, isSharedOptionName, MAX_SHARED_OPTIONS, PAGE_HOOKS } from '@monimesl/dot-core';\nimport type { Expression, ObjectExpression, Program } from 'oxc-parser';\n\nimport type { PageModule, PageStateModule } from './types';\nimport { failAt } from '../../errors';\nimport { defaultExport, defineCall, parseModule } from '../../module';\nimport type { StaticProperty } from '../../utils';\nimport { staticProperties, unwrapExpression, withoutExport } from '../../utils';\n\nconst HOOKS = new Set<string>(PAGE_HOOKS);\nconst SHARE_EXAMPLE = \"such as share: { options: ['show'] }\";\n\nexport function parseStateModule(source: string, file = 'state.ts'): PageStateModule {\n const program = parseModule(source, file);\n const exported = defaultExport(program);\n if (!exported) {\n return failAt(\n 'state.ts must have a default export, such as export default { count: 0 }',\n source,\n 0,\n file,\n );\n }\n const properties = resolvedProperties(program, exported);\n return {\n keys: namesOf(properties),\n keyOffsets: offsetsOf(properties ?? []),\n };\n}\n\nexport function parseLogicModule(source: string, file = 'controller.ts'): PageModule {\n const program = parseModule(source, file);\n const options = defineCall(program, source, file, 'definePage');\n let id: string | null = null;\n let share: string[] | null = null;\n let mutations: StaticProperty[] | null = [];\n let actions: StaticProperty[] | null = [];\n const hooks: string[] = [];\n for (const { name, value, start } of staticProperties(options)) {\n switch (name) {\n case 'initialState':\n case 'configs':\n break;\n case 'id':\n id = readPageId(value, source, file);\n break;\n case 'share':\n share = readSharedOptions(value, source, file);\n break;\n case 'hooks':\n hooks.push(...readHooks(value, source, file));\n break;\n case 'mutations':\n mutations = resolvedProperties(program, value);\n break;\n case 'actions':\n actions = resolvedProperties(program, value);\n break;\n default:\n if (isFunction(value)) {\n failAt(`\\`${name}\\` must go in \\`mutations\\` or \\`actions\\``, source, start, file);\n } else {\n failAt(\n `Unknown option \\`${name}\\`. definePage takes id, initialState, configs, share, hooks, mutations and actions`,\n source,\n start,\n file,\n );\n }\n }\n }\n const mutationNames = namesOf(mutations);\n const actionNames = namesOf(actions);\n if (mutationNames && actionNames) {\n const clash = mutationNames.find((name) => actionNames.includes(name));\n if (clash) {\n failAt(\n `\\`${clash}\\` is both a mutation and an action. Rename one of them`,\n source,\n options.start,\n file,\n );\n }\n }\n return {\n id,\n share,\n mutations: mutationNames,\n actions: actionNames,\n hooks,\n handlerOffsets: offsetsOf([...(mutations ?? []), ...(actions ?? [])]),\n };\n}\n\n// `share: { options: ['show'] }`, written out so the build can read it.\nfunction readSharedOptions(node: Expression, source: string, file: string): string[] {\n const object = unwrapExpression(node);\n if (object.type !== 'ObjectExpression') {\n return failAt(`Write \\`share\\` out in place, ${SHARE_EXAMPLE}`, source, node.start, file);\n }\n const properties = staticProperties(object);\n if (properties.length !== object.properties.length) {\n return failAt(`Write \\`share\\` out in place, ${SHARE_EXAMPLE}`, source, object.start, file);\n }\n const options: string[] = [];\n for (const property of properties) {\n if (property.name !== 'options') {\n return failAt(\n `Unknown share option \\`${property.name}\\`. share only takes options`,\n source,\n property.start,\n file,\n );\n }\n const list = unwrapExpression(property.value);\n if (list.type !== 'ArrayExpression') {\n return failAt(\n `share's options must be a list of names, ${SHARE_EXAMPLE}`,\n source,\n list.start,\n file,\n );\n }\n for (const element of list.elements) {\n if (!element || element.type !== 'Literal' || typeof element.value !== 'string') {\n return failAt(\n `share's options must be names written as strings, ${SHARE_EXAMPLE}`,\n source,\n element?.start ?? list.start,\n file,\n );\n }\n const name = element.value;\n if (!isSharedOptionName(name)) {\n return failAt(\n `\"${name}\" can't go in a link. Use letters, digits, \"-\" and \"_\"`,\n source,\n element.start,\n file,\n );\n }\n if (options.includes(name)) {\n return failAt(\n `\"${name}\" is in share's options twice. Remove one`,\n source,\n element.start,\n file,\n );\n }\n options.push(name);\n }\n if (options.length > MAX_SHARED_OPTIONS) {\n return failAt(\n `A link can carry at most ${MAX_SHARED_OPTIONS} options. Remove some from share's options`,\n source,\n list.start,\n file,\n );\n }\n }\n return options;\n}\n\n// Only hooks written in an object literal are checked.\nfunction readHooks(node: Expression, source: string, file: string): string[] {\n if (node.type !== 'ObjectExpression') {\n return [];\n }\n const hooks: string[] = [];\n for (const hook of staticProperties(node)) {\n if (!HOOKS.has(hook.name)) {\n failAt(\n `Unknown page hook \\`${hook.name}\\`. The hooks are ${PAGE_HOOKS.join(', ')}`,\n source,\n hook.start,\n file,\n );\n }\n hooks.push(hook.name);\n }\n return hooks;\n}\n\nfunction isFunction(node: Expression): boolean {\n return node.type === 'FunctionExpression' || node.type === 'ArrowFunctionExpression';\n}\n\n// The properties of the object literal that `node` is or names. Null when any can't be read\n// without running the code.\nfunction resolvedProperties(program: Program, node: Expression): StaticProperty[] | null {\n const object = resolveObject(program, node);\n if (!object) {\n return null;\n }\n const properties = staticProperties(object);\n if (properties.length !== object.properties.length) {\n return null;\n }\n return properties;\n}\n\nfunction namesOf(properties: readonly StaticProperty[] | null): string[] | null {\n if (properties === null) {\n return null;\n }\n return properties.map((property) => property.name);\n}\n\nfunction offsetsOf(properties: readonly StaticProperty[]): Record<string, number> {\n const offsets: Record<string, number> = {};\n for (const property of properties) {\n offsets[property.name] = property.start;\n }\n return offsets;\n}\n\n// Follows `export default state` back to `const state = { ... }`.\nfunction resolveObject(program: Program, node: Expression): ObjectExpression | null {\n const target = unwrapExpression(node);\n if (target.type === 'ObjectExpression') {\n return target;\n }\n if (target.type !== 'Identifier') {\n return null;\n }\n for (const statement of program.body) {\n const declaration = withoutExport(statement);\n if (declaration?.type !== 'VariableDeclaration' || declaration.kind !== 'const') {\n continue;\n }\n for (const declarator of declaration.declarations) {\n if (declarator.id.type !== 'Identifier' || declarator.id.name !== target.name) {\n continue;\n }\n if (!declarator.init) {\n return null;\n }\n return resolveObject(program, declarator.init);\n }\n }\n return null;\n}\n\nexport function readPageId(node: Expression, source: string, file: string): string {\n const value = unwrapExpression(node);\n if (value.type !== 'Literal' || typeof value.value !== 'string') {\n return failAt(\n \"A page id must be written as a string, such as 'cart'\",\n source,\n node.start,\n file,\n );\n }\n if (!isPageId(value.value)) {\n return failAt(\n `\"${value.value}\" isn't a valid page id. Use letters, digits, \"-\" and \"_\", with \"/\" between folders`,\n source,\n node.start,\n file,\n );\n }\n return value.value;\n}\n","import { failAt } from './errors';\nimport { readPageId } from './ast/page/parse';\nimport { defineCall, parseModule } from './module';\nimport { staticProperties, unwrapExpression } from './utils';\n\nexport interface DotModuleIR {\n readonly pages: readonly string[];\n readonly lastPage: { readonly start: number; readonly end: number };\n}\n\nexport function parseDotModule(source: string, file = 'dot.ts'): DotModuleIR {\n const program = parseModule(source, file);\n const options = defineCall(program, source, file, 'defineDot');\n const pagesProperty = staticProperties(options).find((property) => property.name === 'pages');\n if (!pagesProperty) {\n return failAt(\n 'defineDot needs `pages`, a list of page folders with the entry page first',\n source,\n options.start,\n file,\n );\n }\n const { value, start } = pagesProperty;\n const pageList = unwrapExpression(value);\n if (pageList.type !== 'ArrayExpression') {\n return failAt('`pages` must be a list of page folders', source, start, file);\n }\n if (pageList.elements.length === 0) {\n return failAt('`pages` needs at least one page', source, start, file);\n }\n const pages = pageList.elements.map((element) => {\n if (!element || element.type === 'SpreadElement') {\n return failAt(\n '`pages` must list each page folder as a string',\n source,\n element?.start ?? start,\n file,\n );\n }\n return readPageId(element, source, file);\n });\n // The check above fails on a hole, so the last element is there.\n const lastPage = pageList.elements.at(-1)!;\n return { pages, lastPage: { start: lastPage.start, end: lastPage.end } };\n}\n","export const UNARY_OPERATORS = ['!', '-', '+', 'typeof'] as const;\n\nexport const BINARY_OPERATORS = [\n '==',\n '!=',\n '===',\n '!==',\n '<',\n '<=',\n '>',\n '>=',\n '+',\n '-',\n '*',\n '/',\n '%',\n '**',\n '&&',\n '||',\n '??',\n] as const;\n\nexport type LiteralValue = string | number | boolean | null;\n\ntype LiteralNode = { readonly type: 'Literal'; readonly value: LiteralValue };\n\ntype IdentifierNode = { readonly type: 'Identifier'; readonly name: string };\n\ntype MemberNode = {\n readonly type: 'Member';\n readonly object: ExprNode;\n readonly property: ExprNode;\n};\n\nexport type UnaryOperator = (typeof UNARY_OPERATORS)[number];\n\ntype UnaryExprNode = {\n readonly type: 'Unary';\n readonly operator: UnaryOperator;\n readonly argument: ExprNode;\n};\n\nexport type BinaryOperator = (typeof BINARY_OPERATORS)[number];\n\ntype BinaryExprNode = {\n readonly type: 'Binary';\n readonly operator: BinaryOperator;\n readonly left: ExprNode;\n readonly right: ExprNode;\n};\n\ntype ConditionalExprNode = {\n readonly type: 'Conditional';\n readonly test: ExprNode;\n readonly consequent: ExprNode;\n readonly alternate: ExprNode;\n};\n\nexport type ExprNode =\n LiteralNode | IdentifierNode | MemberNode | UnaryExprNode | BinaryExprNode | ConditionalExprNode;\n","import type { Expression } from 'oxc-parser';\nimport { parseSync } from 'oxc-parser';\n\nimport { failAt, failOnSyntaxError } from '../../errors';\nimport { BINARY_OPERATORS, type ExprNode, UNARY_OPERATORS } from './types';\n\n// Parses what's inside a `{{ }}` binding into an expression tree.\nexport function parseExpression(source: string): ExprNode {\n if (source.trim().length === 0) {\n failAt('The binding is empty', source, 0);\n }\n const { program, errors } = parseSync('binding.js', source, { preserveParens: false });\n failOnSyntaxError(errors, source);\n const statement = program.body[0];\n if (program.body.length !== 1 || statement?.type !== 'ExpressionStatement') {\n return failAt('A binding must be one expression', source, statement?.start ?? 0);\n }\n return toExprNode(statement.expression, source);\n}\n\nfunction toExprNode(node: Expression, source: string): ExprNode {\n switch (node.type) {\n case 'Literal':\n if (typeof node.value === 'bigint' || node.value instanceof RegExp) {\n return failUnsupported(node, source);\n }\n return { type: 'Literal', value: node.value };\n case 'Identifier':\n return { type: 'Identifier', name: node.name };\n case 'MemberExpression': {\n if (node.object.type === 'Super' || node.property.type === 'PrivateIdentifier') {\n return failUnsupported(node, source);\n }\n const object = toExprNode(node.object, source);\n if (node.computed) {\n return { type: 'Member', object, property: toExprNode(node.property, source) };\n }\n return { type: 'Member', object, property: { type: 'Literal', value: node.property.name } };\n }\n case 'UnaryExpression':\n if (!isOneOf(UNARY_OPERATORS, node.operator)) {\n return failUnsupported(node, source);\n }\n return {\n type: 'Unary',\n operator: node.operator,\n argument: toExprNode(node.argument, source),\n };\n case 'BinaryExpression':\n case 'LogicalExpression':\n if (node.left.type === 'PrivateIdentifier' || !isOneOf(BINARY_OPERATORS, node.operator)) {\n return failUnsupported(node, source);\n }\n return {\n type: 'Binary',\n operator: node.operator,\n left: toExprNode(node.left, source),\n right: toExprNode(node.right, source),\n };\n case 'ConditionalExpression':\n return {\n type: 'Conditional',\n test: toExprNode(node.test, source),\n consequent: toExprNode(node.consequent, source),\n alternate: toExprNode(node.alternate, source),\n };\n case 'CallExpression':\n case 'NewExpression':\n return failAt(\n \"Bindings can't call functions. Work the value out in controller.ts and keep it in state\",\n source,\n node.start,\n );\n case 'AssignmentExpression':\n case 'UpdateExpression':\n return failAt(\n \"Bindings can't change values. Change state in a mutation instead\",\n source,\n node.start,\n );\n default:\n return failUnsupported(node, source);\n }\n}\n\n// Plain names for what developers most often try in a binding.\nconst UNSUPPORTED_EXPRESSIONS: Readonly<Record<string, string>> = {\n ArrayExpression: 'lists',\n ObjectExpression: 'objects',\n ArrowFunctionExpression: 'functions',\n FunctionExpression: 'functions',\n TemplateLiteral: 'template strings',\n SequenceExpression: 'commas',\n ThisExpression: '`this`',\n};\n\nfunction failUnsupported(node: Expression, source: string): never {\n let unsupported = UNSUPPORTED_EXPRESSIONS[node.type] ?? 'this kind of expression';\n if ('operator' in node) {\n unsupported = `\\`${node.operator}\\``;\n }\n return failAt(\n `Bindings can't use ${unsupported}. Work the value out in controller.ts and keep it in state`,\n source,\n node.start,\n );\n}\n\nfunction isOneOf<T extends string>(list: readonly T[], value: string): value is T {\n return (list as readonly string[]).includes(value);\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@monimesl/dot-script-parser",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.3",
|
|
4
4
|
"description": "Dot page script parser: page state and logic -> intermediary representation",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"oxc-parser": "^0.151.0",
|
|
35
|
-
"@monimesl/dot-core": "1.0.0-beta.
|
|
35
|
+
"@monimesl/dot-core": "1.0.0-beta.3"
|
|
36
36
|
},
|
|
37
37
|
"publishConfig": {
|
|
38
38
|
"access": "public"
|