@monimesl/dot-script-parser 0.1.0-alpha.2 → 0.1.0-alpha.4

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 CHANGED
@@ -9,10 +9,12 @@ export declare function unboundReferences(source: string, names: readonly string
9
9
  //#endregion
10
10
  //#region src/dot.d.ts
11
11
  interface DotModuleIR {
12
- /** Page folders under `pages/`, in order; the first is where the dot starts. */
13
12
  readonly pages: readonly string[];
13
+ readonly lastPage: {
14
+ readonly start: number;
15
+ readonly end: number;
16
+ };
14
17
  }
15
- /** Reads `export default defineDot({ pages: [...] })`. The pages must be string literals. */
16
18
  export declare function parseDotModule(source: string, file?: string): DotModuleIR;
17
19
  //#endregion
18
20
  //#region src/errors.d.ts
@@ -64,12 +66,14 @@ export declare function parseExpression(source: string): ExprNode;
64
66
  //#region src/ast/page/types.d.ts
65
67
  interface PageStateModule {
66
68
  readonly keys: readonly string[] | null;
69
+ readonly keyOffsets: Readonly<Record<string, number>>;
67
70
  }
68
71
  interface PageModule {
69
72
  readonly id: string | null;
70
73
  readonly hooks: readonly string[];
71
74
  readonly mutations: readonly string[] | null;
72
75
  readonly actions: readonly string[] | null;
76
+ readonly handlerOffsets: Readonly<Record<string, number>>;
73
77
  }
74
78
  //#endregion
75
79
  //#region src/ast/page/parse.d.ts
@@ -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":";;;;;;;wBAcgB,kBACd,gBACA,0BACA;;;UCZe;;WAEN;;;wBAIK,eAAe,gBAAgB,gBAAkB;;;qBCRpD,yBAAyB;WAClB;;;;cCJP;cAEA;KAoBD;KAEA;WAAyB;WAA0B,OAAO;;KAE1D;WAA4B;WAA6B;;KAEzD;WACD;WACA,QAAQ;WACR,UAAU;;KAGT,wBAAwB;KAExB;WACD;WACA,UAAU;WACV,UAAU;;KAGT,yBAAyB;KAEzB;WACD;WACA,UAAU;WACV,MAAM;WACN,OAAO;;KAGN;WACD;WACA,MAAM;WACN,YAAY;WACZ,WAAW;;KAGV,WACV,cAAc,iBAAiB,aAAa,gBAAgB,iBAAiB;;;wBCpD/D,gBAAgB,iBAAiB;;;UCPhC;WAEN;;UAGM;WACN;WACA;WACA;WACA;;;;wBCCK,iBAAiB,gBAAgB,gBAAoB;wBASrD,iBAAiB,gBAAgB,gBAAyB"}
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":";;;;;;;wBAcgB,kBACd,gBACA,0BACA;;;UCZe;WACN;WACA;aAAqB;aAAwB;;;wBAGxC,eAAe,gBAAgB,gBAAkB;;;qBCPpD,yBAAyB;WAClB;;;;cCJP;cAEA;KAoBD;KAEA;WAAyB;WAA0B,OAAO;;KAE1D;WAA4B;WAA6B;;KAEzD;WACD;WACA,QAAQ;WACR,UAAU;;KAGT,wBAAwB;KAExB;WACD;WACA,UAAU;WACV,UAAU;;KAGT,yBAAyB;KAEzB;WACD;WACA,UAAU;WACV,MAAM;WACN,OAAO;;KAGN;WACD;WACA,MAAM;WACN,YAAY;WACZ,WAAW;;KAGV,WACV,cAAc,iBAAiB,aAAa,gBAAgB,iBAAiB;;;wBCpD/D,gBAAgB,iBAAiB;;;UCPhC;WAEN;WAEA,YAAY,SAAS;;UAGf;WACN;WACA;WACA;WACA;WAEA,gBAAgB,SAAS;;;;wBCFpB,iBAAiB,gBAAgB,gBAAoB;wBAarD,iBAAiB,gBAAgB,gBAAyB"}
package/dist/index.js CHANGED
@@ -1,17 +1,5 @@
1
1
  import { parseSync } from "oxc-parser";
2
2
  import { PAGE_HOOKS, SourceError, isPageId, locationAt } from "@monimesl/dot-core";
3
- //#region src/errors.ts
4
- var ScriptParseError = class extends SourceError {
5
- name = "ScriptParseError";
6
- };
7
- function failAt(reason, source, offset, file) {
8
- throw new ScriptParseError(reason, file, locationAt(source, offset));
9
- }
10
- function failOnSyntaxError(errors, source, file) {
11
- const [error] = errors;
12
- if (error) failAt(error.message, source, error.labels[0]?.start ?? 0, file);
13
- }
14
- //#endregion
15
3
  //#region src/utils.ts
16
4
  function propertyName(key) {
17
5
  if (key.type === "Identifier") return key.name;
@@ -40,12 +28,22 @@ function withoutExport(statement) {
40
28
  return statement;
41
29
  }
42
30
  //#endregion
31
+ //#region src/errors.ts
32
+ var ScriptParseError = class extends SourceError {
33
+ name = "ScriptParseError";
34
+ };
35
+ function failAt(reason, source, offset, file) {
36
+ throw new ScriptParseError(reason, file, locationAt(source, offset));
37
+ }
38
+ function failOnSyntaxError(errors, source, file) {
39
+ const [error] = errors;
40
+ if (error) failAt(error.message, source, error.labels[0]?.start ?? 0, file);
41
+ }
42
+ //#endregion
43
43
  //#region src/module.ts
44
44
  function parseModule(source, file) {
45
- let lang = "ts";
46
- if (file.endsWith(".tsx") || file.endsWith(".jsx")) lang = "tsx";
47
45
  const { program, errors } = parseSync(file, source, {
48
- lang,
46
+ lang: "ts",
49
47
  sourceType: "module"
50
48
  });
51
49
  failOnSyntaxError(errors, source, file);
@@ -152,7 +150,11 @@ function parseStateModule(source, file = "state.ts") {
152
150
  const program = parseModule(source, file);
153
151
  const exported = defaultExport(program);
154
152
  if (!exported) return failAt("state.ts must have a default export", source, 0, file);
155
- return { keys: resolvedKeys(program, exported) };
153
+ const properties = resolvedProperties(program, exported);
154
+ return {
155
+ keys: properties?.map((property) => property.name) ?? null,
156
+ keyOffsets: offsetsOf(properties ?? [])
157
+ };
156
158
  }
157
159
  function parseLogicModule(source, file = "controller.ts") {
158
160
  const program = parseModule(source, file);
@@ -162,7 +164,8 @@ function parseLogicModule(source, file = "controller.ts") {
162
164
  let actions = [];
163
165
  const hooks = [];
164
166
  for (const { name, value, start } of staticProperties(options)) switch (name) {
165
- case "initialState": break;
167
+ case "initialState":
168
+ case "configs": break;
166
169
  case "id":
167
170
  id = pageId(value, source, file);
168
171
  break;
@@ -174,30 +177,39 @@ function parseLogicModule(source, file = "controller.ts") {
174
177
  }
175
178
  break;
176
179
  case "mutations":
177
- mutations = resolvedKeys(program, value);
180
+ mutations = resolvedProperties(program, value);
178
181
  break;
179
182
  case "actions":
180
- actions = resolvedKeys(program, value);
183
+ actions = resolvedProperties(program, value);
181
184
  break;
182
185
  default: if (isFunction(value)) failAt(`\`${name}\` must go in \`mutations\` or \`actions\``, source, start, file);
183
- else failAt(`Unknown option \`${name}\`. definePage takes id, initialState, hooks, mutations and actions`, source, start, file);
186
+ else failAt(`Unknown option \`${name}\`. definePage takes id, initialState, configs, hooks, mutations and actions`, source, start, file);
184
187
  }
185
- const clash = mutations?.find((name) => actions?.includes(name));
188
+ const mutationNames = mutations?.map((property) => property.name) ?? null;
189
+ const actionNames = actions?.map((property) => property.name) ?? null;
190
+ const clash = mutationNames?.find((name) => actionNames?.includes(name));
186
191
  if (clash) failAt(`\`${clash}\` is both a mutation and an action`, source, options.start, file);
187
192
  return {
188
193
  id,
189
- mutations,
190
- actions,
191
- hooks
194
+ mutations: mutationNames,
195
+ actions: actionNames,
196
+ hooks,
197
+ handlerOffsets: offsetsOf([...mutations ?? [], ...actions ?? []])
192
198
  };
193
199
  }
194
200
  function isFunction(node) {
195
201
  return node.type === "FunctionExpression" || node.type === "ArrowFunctionExpression";
196
202
  }
197
- function resolvedKeys(program, node) {
203
+ function resolvedProperties(program, node) {
198
204
  const object = resolveObject(program, node);
199
205
  if (!object) return null;
200
- return staticKeys(object);
206
+ const properties = staticProperties(object);
207
+ return properties.length === object.properties.length ? properties : null;
208
+ }
209
+ function offsetsOf(properties) {
210
+ const offsets = {};
211
+ for (const property of properties) offsets[property.name] = property.start;
212
+ return offsets;
201
213
  }
202
214
  /** Follows `export default state` back to `const state = { ... }`. */
203
215
  function resolveObject(program, node) {
@@ -211,11 +223,6 @@ function resolveObject(program, node) {
211
223
  }
212
224
  return null;
213
225
  }
214
- function staticKeys(object) {
215
- const properties = staticProperties(object);
216
- if (properties.length !== object.properties.length) return null;
217
- return properties.map((property) => property.name);
218
- }
219
226
  /** Reads a page id, which must be a string literal made of safe characters. */
220
227
  function pageId(node, source, file) {
221
228
  const value = unwrapExpression(node);
@@ -225,7 +232,6 @@ function pageId(node, source, file) {
225
232
  }
226
233
  //#endregion
227
234
  //#region src/dot.ts
228
- /** Reads `export default defineDot({ pages: [...] })`. The pages must be string literals. */
229
235
  function parseDotModule(source, file = "dot.ts") {
230
236
  const options = defineCall(parseModule(source, file), source, file, "defineDot");
231
237
  const pagesProperty = staticProperties(options).find((property) => property.name === "pages");
@@ -234,10 +240,18 @@ function parseDotModule(source, file = "dot.ts") {
234
240
  const array = unwrapExpression(value);
235
241
  if (array.type !== "ArrayExpression") return failAt("`pages` must be an array of page folders", source, start, file);
236
242
  if (array.elements.length === 0) return failAt("`pages` needs at least one page", source, start, file);
237
- return { pages: array.elements.map((element) => {
243
+ const pages = array.elements.map((element) => {
238
244
  if (!element || element.type === "SpreadElement") return failAt("`pages` must list each page folder as a string", source, element?.start ?? start, file);
239
245
  return pageId(element, source, file);
240
- }) };
246
+ });
247
+ const last = array.elements.at(-1);
248
+ return {
249
+ pages,
250
+ lastPage: {
251
+ start: last.start,
252
+ end: last.end
253
+ }
254
+ };
241
255
  }
242
256
  //#endregion
243
257
  //#region src/ast/expression/types.ts
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../src/errors.ts","../src/utils.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 { 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 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 // Where the property starts in the source, for error locations.\n readonly start: number;\n}\n\n// The properties of an object literal whose names are written out, skipping computed ones.\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// The declaration inside `export const ...` and the like; other statements as they are.\nexport function withoutExport(statement: TopLevelStatement): TopLevelStatement | null {\n if (statement.type === 'ExportNamedDeclaration') {\n return statement.declaration;\n }\n return statement;\n}\n","import type { Expression, ObjectExpression, Program } from 'oxc-parser';\nimport { parseSync } from 'oxc-parser';\n\nimport { failAt, failOnSyntaxError } from './errors';\nimport { unwrapExpression } from './utils';\n\nexport function parseModule(source: string, file: string): Program {\n let lang: 'ts' | 'tsx' = 'ts';\n if (file.endsWith('.tsx') || file.endsWith('.jsx')) {\n lang = 'tsx';\n }\n const { program, errors } = parseSync(file, source, { lang, 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\nexport function defineCall(\n program: Program,\n source: string,\n file: string,\n callee: string,\n): ObjectExpression {\n const exported = defaultExport(program);\n const call = exported && unwrapExpression(exported);\n const options = call?.type === 'CallExpression' ? call.arguments[0] : undefined;\n if (\n call?.type !== 'CallExpression' ||\n call.callee.type !== 'Identifier' ||\n call.callee.name !== callee ||\n options?.type !== 'ObjectExpression'\n ) {\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\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\n/**\n * Which of `names` a module reads without declaring or importing them at its top level. The\n * compiler imports those for the module, so a dot's code can use framework functions as globals.\n */\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 collectReferences(program as unknown as Node, null, '', references);\n return names.filter((name) => references.has(name) && !bound.has(name));\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 declaration.specifiers.forEach((specifier) => names.add(specifier.local.name));\n break;\n case 'VariableDeclaration':\n declaration.declarations.forEach((declarator) =>\n collectPatternNames(declarator.id as unknown as Node, 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: Node, names: Set<string>): void {\n const visit = (child: unknown) => {\n if (isNode(child)) {\n collectPatternNames(child, names);\n }\n };\n switch (pattern.type) {\n case 'Identifier':\n names.add(pattern.name as string);\n break;\n case 'ObjectPattern':\n (pattern.properties as Node[]).forEach((property) =>\n visit(property.type === 'RestElement' ? property.argument : property.value),\n );\n break;\n case 'ArrayPattern':\n (pattern.elements as unknown[]).forEach(visit);\n break;\n case 'RestElement':\n visit(pattern.argument);\n break;\n case 'AssignmentPattern':\n visit(pattern.left);\n break;\n }\n}\n\nfunction collectReferences(node: Node, parent: Node | null, key: string, out: Set<string>): void {\n if (node.type === 'ImportDeclaration') {\n return;\n }\n if (node.type === 'Identifier' && isReference(parent, key)) {\n out.add(node.name as string);\n }\n for (const [childKey, value] of Object.entries(node)) {\n for (const child of Array.isArray(value) ? value : [value]) {\n if (isNode(child)) {\n collectReferences(child, node, childKey, out);\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 return typeof (value as Node | null)?.type === 'string';\n}\n","import { isPageId, 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 { staticProperties, unwrapExpression, withoutExport } from '../../utils';\n\nconst HOOKS = new Set<string>(PAGE_HOOKS);\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 return { keys: resolvedKeys(program, exported) };\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 mutations: string[] | null = [];\n let actions: string[] | null = [];\n const hooks: string[] = [];\n for (const { name, value, start } of staticProperties(options)) {\n switch (name) {\n case 'initialState':\n break;\n case 'id':\n id = pageId(value, source, file);\n break;\n case 'hooks':\n if (value.type !== 'ObjectExpression') {\n break;\n }\n for (const hook of staticProperties(value)) {\n if (!HOOKS.has(hook.name)) {\n failAt(\n `Unknown page hook \\`${hook.name}\\`. Page hooks: ${PAGE_HOOKS.join(', ')}`,\n source,\n hook.start,\n file,\n );\n }\n hooks.push(hook.name);\n }\n break;\n case 'mutations':\n mutations = resolvedKeys(program, value);\n break;\n case 'actions':\n actions = resolvedKeys(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, hooks, mutations and actions`,\n source,\n start,\n file,\n );\n }\n }\n }\n const clash = mutations?.find((name) => actions?.includes(name));\n if (clash) {\n failAt(`\\`${clash}\\` is both a mutation and an action`, source, options.start, file);\n }\n return { id, mutations, actions, hooks };\n}\n\nfunction isFunction(node: Expression): boolean {\n return node.type === 'FunctionExpression' || node.type === 'ArrowFunctionExpression';\n}\n\n// The keys of the object literal `node` is or names, or null when they cannot be read statically.\nfunction resolvedKeys(program: Program, node: Expression): string[] | null {\n const object = resolveObject(program, node);\n if (!object) {\n return null;\n }\n return staticKeys(object);\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\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 return declarator.init ? resolveObject(program, declarator.init) : null;\n }\n }\n }\n return null;\n}\n\nfunction staticKeys(object: ObjectExpression): string[] | null {\n const properties = staticProperties(object);\n if (properties.length !== object.properties.length) {\n return null;\n }\n return properties.map((property) => property.name);\n}\n\n/** Reads a page id, which must be a string literal made of safe characters. */\nexport function pageId(node: Expression, source: string, file: string): string {\n const value = unwrapExpression(node);\n if (value.type !== 'Literal' || typeof value.value !== 'string') {\n return failAt('A page id must be a string literal', source, node.start, file);\n }\n if (!isPageId(value.value)) {\n return failAt(\n `Invalid page id \"${value.value}\". Use letters, digits, \"-\" and \"_\", with \"/\" between segments`,\n source,\n node.start,\n file,\n );\n }\n return value.value;\n}\n","import { failAt } from './errors';\nimport { defineCall, parseModule } from './module';\nimport { pageId } from './ast/page/parse';\nimport { staticProperties, unwrapExpression } from './utils';\n\nexport interface DotModuleIR {\n /** Page folders under `pages/`, in order; the first is where the dot starts. */\n readonly pages: readonly string[];\n}\n\n/** Reads `export default defineDot({ pages: [...] })`. The pages must be string literals. */\nexport function parseDotModule(source: string, file = 'dot.ts'): DotModuleIR {\n const program = parseModule(source, file);\n const options = defineCall(program, source, file, 'defineDot');\n\n const pagesProperty = staticProperties(options).find((property) => property.name === 'pages');\n if (!pagesProperty) {\n return failAt(\n \"defineDot needs `pages`: the dot's page folders, starting page first\",\n source,\n options.start,\n file,\n );\n }\n const { value, start } = pagesProperty;\n const array = unwrapExpression(value);\n if (array.type !== 'ArrayExpression') {\n return failAt('`pages` must be an array of page folders', source, start, file);\n }\n if (array.elements.length === 0) {\n return failAt('`pages` needs at least one page', source, start, file);\n }\n\n const pages = array.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 pageId(element, source, file);\n });\n return { pages };\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\nexport type LiteralNode = { readonly type: 'Literal'; readonly value: LiteralValue };\n\nexport type IdentifierNode = { readonly type: 'Identifier'; readonly name: string };\n\nexport type MemberNode = {\n readonly type: 'Member';\n readonly object: ExprNode;\n readonly property: ExprNode;\n};\n\nexport type UnaryOperator = (typeof UNARY_OPERATORS)[number];\n\nexport type UnaryExprNode = {\n readonly type: 'Unary';\n readonly operator: UnaryOperator;\n readonly argument: ExprNode;\n};\n\nexport type BinaryOperator = (typeof BINARY_OPERATORS)[number];\n\nexport type BinaryExprNode = {\n readonly type: 'Binary';\n readonly operator: BinaryOperator;\n readonly left: ExprNode;\n readonly right: ExprNode;\n};\n\nexport type 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 the body of a binding (`{{ }}`) into an expression tree.\nexport function parseExpression(source: string): ExprNode {\n if (source.trim().length === 0) {\n failAt('Empty expression', source, 0);\n }\n const { program, errors } = parseSync('binding.js', source, { preserveParens: false });\n failOnSyntaxError(errors, source);\n const [statement, extra] = program.body;\n if (!statement || extra || statement.type !== 'ExpressionStatement') {\n return failAt('Expected a single expression statement', source, statement?.start ?? 0);\n }\n return convert(statement.expression, source);\n}\n\nfunction convert(node: Expression, source: string): ExprNode {\n switch (node.type) {\n case 'Literal':\n if (typeof node.value === 'bigint' || node.value instanceof RegExp) {\n break;\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 break;\n }\n const object = convert(node.object, source);\n if (node.computed) {\n return { type: 'Member', object, property: convert(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 break;\n }\n return { type: 'Unary', operator: node.operator, argument: convert(node.argument, source) };\n }\n case 'BinaryExpression':\n case 'LogicalExpression': {\n if (node.left.type === 'PrivateIdentifier' || !isOneOf(BINARY_OPERATORS, node.operator)) {\n break;\n }\n return {\n type: 'Binary',\n operator: node.operator,\n left: convert(node.left, source),\n right: convert(node.right, source),\n };\n }\n case 'ConditionalExpression': {\n return {\n type: 'Conditional',\n test: convert(node.test, source),\n consequent: convert(node.consequent, source),\n alternate: convert(node.alternate, source),\n };\n }\n case 'CallExpression':\n case 'NewExpression':\n return failAt('Function calls are currently not allowed in bindings', source, node.start);\n case 'AssignmentExpression':\n case 'UpdateExpression':\n return failAt('Update expressions are currently not allowed in bindings', source, node.start);\n }\n let detail = '';\n if ('operator' in node) {\n detail = ` \\`${node.operator}\\``;\n }\n return failAt(`Unsupported syntax in binding: ${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, skipping computed ones.\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// The declaration inside `export const ...` and the like; other statements as they are.\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\nexport function defineCall(\n program: Program,\n source: string,\n file: string,\n callee: string,\n): ObjectExpression {\n const exported = defaultExport(program);\n const call = exported && unwrapExpression(exported);\n const options = call?.type === 'CallExpression' ? call.arguments[0] : undefined;\n if (\n call?.type !== 'CallExpression' ||\n call.callee.type !== 'Identifier' ||\n call.callee.name !== callee ||\n options?.type !== 'ObjectExpression'\n ) {\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\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\n/**\n * Which of `names` a module reads without declaring or importing them at its top level. The\n * compiler imports those for the module, so a dot's code can use framework functions as globals.\n */\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 collectReferences(program as unknown as Node, null, '', references);\n return names.filter((name) => references.has(name) && !bound.has(name));\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 declaration.specifiers.forEach((specifier) => names.add(specifier.local.name));\n break;\n case 'VariableDeclaration':\n declaration.declarations.forEach((declarator) =>\n collectPatternNames(declarator.id as unknown as Node, 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: Node, names: Set<string>): void {\n const visit = (child: unknown) => {\n if (isNode(child)) {\n collectPatternNames(child, names);\n }\n };\n switch (pattern.type) {\n case 'Identifier':\n names.add(pattern.name as string);\n break;\n case 'ObjectPattern':\n (pattern.properties as Node[]).forEach((property) =>\n visit(property.type === 'RestElement' ? property.argument : property.value),\n );\n break;\n case 'ArrayPattern':\n (pattern.elements as unknown[]).forEach(visit);\n break;\n case 'RestElement':\n visit(pattern.argument);\n break;\n case 'AssignmentPattern':\n visit(pattern.left);\n break;\n }\n}\n\nfunction collectReferences(node: Node, parent: Node | null, key: string, out: Set<string>): void {\n if (node.type === 'ImportDeclaration') {\n return;\n }\n if (node.type === 'Identifier' && isReference(parent, key)) {\n out.add(node.name as string);\n }\n for (const [childKey, value] of Object.entries(node)) {\n for (const child of Array.isArray(value) ? value : [value]) {\n if (isNode(child)) {\n collectReferences(child, node, childKey, out);\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 return typeof (value as Node | null)?.type === 'string';\n}\n","import { isPageId, 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);\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: properties?.map((property) => property.name) ?? null,\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 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 = pageId(value, source, file);\n break;\n case 'hooks':\n if (value.type !== 'ObjectExpression') {\n break;\n }\n for (const hook of staticProperties(value)) {\n if (!HOOKS.has(hook.name)) {\n failAt(\n `Unknown page hook \\`${hook.name}\\`. Page hooks: ${PAGE_HOOKS.join(', ')}`,\n source,\n hook.start,\n file,\n );\n }\n hooks.push(hook.name);\n }\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, hooks, mutations and actions`,\n source,\n start,\n file,\n );\n }\n }\n }\n const mutationNames = mutations?.map((property) => property.name) ?? null;\n const actionNames = actions?.map((property) => property.name) ?? null;\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 return {\n id,\n mutations: mutationNames,\n actions: actionNames,\n hooks,\n handlerOffsets: offsetsOf([...(mutations ?? []), ...(actions ?? [])]),\n };\n}\n\nfunction isFunction(node: Expression): boolean {\n return node.type === 'FunctionExpression' || node.type === 'ArrowFunctionExpression';\n}\n\n// The properties of the object literal `node` is or names, or null when they cannot all be read\n// statically.\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 return properties.length === object.properties.length ? properties : null;\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\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 return declarator.init ? resolveObject(program, declarator.init) : null;\n }\n }\n }\n return null;\n}\n\n/** Reads a page id, which must be a string literal made of safe characters. */\nexport function pageId(node: Expression, source: string, file: string): string {\n const value = unwrapExpression(node);\n if (value.type !== 'Literal' || typeof value.value !== 'string') {\n return failAt('A page id must be a string literal', source, node.start, file);\n }\n if (!isPageId(value.value)) {\n return failAt(\n `Invalid page id \"${value.value}\". Use letters, digits, \"-\" and \"_\", with \"/\" between segments`,\n source,\n node.start,\n file,\n );\n }\n return value.value;\n}\n","import { failAt } from './errors';\nimport { pageId } 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`: the dot's page folders, starting page first\",\n source,\n options.start,\n file,\n );\n }\n const { value, start } = pagesProperty;\n const array = unwrapExpression(value);\n if (array.type !== 'ArrayExpression') {\n return failAt('`pages` must be an array of page folders', source, start, file);\n }\n if (array.elements.length === 0) {\n return failAt('`pages` needs at least one page', source, start, file);\n }\n const pages = array.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 pageId(element, source, file);\n });\n const last = array.elements.at(-1)!;\n return { pages, lastPage: { start: last.start, end: last.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\nexport type LiteralNode = { readonly type: 'Literal'; readonly value: LiteralValue };\n\nexport type IdentifierNode = { readonly type: 'Identifier'; readonly name: string };\n\nexport type MemberNode = {\n readonly type: 'Member';\n readonly object: ExprNode;\n readonly property: ExprNode;\n};\n\nexport type UnaryOperator = (typeof UNARY_OPERATORS)[number];\n\nexport type UnaryExprNode = {\n readonly type: 'Unary';\n readonly operator: UnaryOperator;\n readonly argument: ExprNode;\n};\n\nexport type BinaryOperator = (typeof BINARY_OPERATORS)[number];\n\nexport type BinaryExprNode = {\n readonly type: 'Binary';\n readonly operator: BinaryOperator;\n readonly left: ExprNode;\n readonly right: ExprNode;\n};\n\nexport type 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 the body of a binding (`{{ }}`) into an expression tree.\nexport function parseExpression(source: string): ExprNode {\n if (source.trim().length === 0) {\n failAt('Empty expression', source, 0);\n }\n const { program, errors } = parseSync('binding.js', source, { preserveParens: false });\n failOnSyntaxError(errors, source);\n const [statement, extra] = program.body;\n if (!statement || extra || statement.type !== 'ExpressionStatement') {\n return failAt('Expected a single expression statement', source, statement?.start ?? 0);\n }\n return convert(statement.expression, source);\n}\n\nfunction convert(node: Expression, source: string): ExprNode {\n switch (node.type) {\n case 'Literal':\n if (typeof node.value === 'bigint' || node.value instanceof RegExp) {\n break;\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 break;\n }\n const object = convert(node.object, source);\n if (node.computed) {\n return { type: 'Member', object, property: convert(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 break;\n }\n return { type: 'Unary', operator: node.operator, argument: convert(node.argument, source) };\n }\n case 'BinaryExpression':\n case 'LogicalExpression': {\n if (node.left.type === 'PrivateIdentifier' || !isOneOf(BINARY_OPERATORS, node.operator)) {\n break;\n }\n return {\n type: 'Binary',\n operator: node.operator,\n left: convert(node.left, source),\n right: convert(node.right, source),\n };\n }\n case 'ConditionalExpression': {\n return {\n type: 'Conditional',\n test: convert(node.test, source),\n consequent: convert(node.consequent, source),\n alternate: convert(node.alternate, source),\n };\n }\n case 'CallExpression':\n case 'NewExpression':\n return failAt('Function calls are currently not allowed in bindings', source, node.start);\n case 'AssignmentExpression':\n case 'UpdateExpression':\n return failAt('Update expressions are currently not allowed in bindings', source, node.start);\n }\n let detail = '';\n if ('operator' in node) {\n detail = ` \\`${node.operator}\\``;\n }\n return failAt(`Unsupported syntax in binding: ${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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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@monimesl/dot-script-parser",
3
- "version": "0.1.0-alpha.2",
3
+ "version": "0.1.0-alpha.4",
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": "0.1.0-alpha.2"
35
+ "@monimesl/dot-core": "0.1.0-alpha.4"
36
36
  },
37
37
  "publishConfig": {
38
38
  "access": "public"