@gadgetinc/ggt 1.0.1 → 1.0.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/README.md +192 -128
- package/lib/__generated__/graphql.js.map +1 -1
- package/lib/commands/add.js +385 -0
- package/lib/commands/add.js.map +1 -0
- package/lib/commands/deploy.js +20 -102
- package/lib/commands/deploy.js.map +1 -1
- package/lib/commands/dev.js +43 -114
- package/lib/commands/dev.js.map +1 -1
- package/lib/commands/list.js +3 -6
- package/lib/commands/list.js.map +1 -1
- package/lib/commands/login.js +2 -5
- package/lib/commands/login.js.map +1 -1
- package/lib/commands/logout.js +2 -5
- package/lib/commands/logout.js.map +1 -1
- package/lib/commands/open.js +45 -86
- package/lib/commands/open.js.map +1 -1
- package/lib/commands/pull.js +19 -76
- package/lib/commands/pull.js.map +1 -1
- package/lib/commands/push.js +19 -76
- package/lib/commands/push.js.map +1 -1
- package/lib/commands/root.js +4 -3
- package/lib/commands/root.js.map +1 -1
- package/lib/commands/status.js +3 -8
- package/lib/commands/status.js.map +1 -1
- package/lib/commands/version.js +6 -5
- package/lib/commands/version.js.map +1 -1
- package/lib/commands/whoami.js +2 -5
- package/lib/commands/whoami.js.map +1 -1
- package/lib/ggt.js.map +1 -1
- package/lib/main.js.map +1 -1
- package/lib/services/app/api/api.js.map +1 -1
- package/lib/services/app/api/operation.js +11 -0
- package/lib/services/app/api/operation.js.map +1 -1
- package/lib/services/app/app.js +21 -2
- package/lib/services/app/app.js.map +1 -1
- package/lib/services/app/arg.js.map +1 -1
- package/lib/services/app/client.js +1 -5
- package/lib/services/app/client.js.map +1 -1
- package/lib/services/app/edit/edit.js.map +1 -1
- package/lib/services/app/edit/operation.js +52 -0
- package/lib/services/app/edit/operation.js.map +1 -1
- package/lib/services/app/error.js.map +1 -1
- package/lib/services/command/arg.js +3 -1
- package/lib/services/command/arg.js.map +1 -1
- package/lib/services/command/command.js +1 -0
- package/lib/services/command/command.js.map +1 -1
- package/lib/services/command/context.js.map +1 -1
- package/lib/services/config/config.js.map +1 -1
- package/lib/services/config/env.js.map +1 -1
- package/lib/services/config/package-json.js.map +1 -1
- package/lib/services/filesync/changes.js.map +1 -1
- package/lib/services/filesync/conflicts.js.map +1 -1
- package/lib/services/filesync/directory.js.map +1 -1
- package/lib/services/filesync/error.js +1 -0
- package/lib/services/filesync/error.js.map +1 -1
- package/lib/services/filesync/file.js.map +1 -1
- package/lib/services/filesync/filesync.js +179 -174
- package/lib/services/filesync/filesync.js.map +1 -1
- package/lib/services/filesync/hashes.js.map +1 -1
- package/lib/services/filesync/strategy.js.map +1 -1
- package/lib/services/filesync/sync-json.js.map +1 -1
- package/lib/services/http/auth.js.map +1 -1
- package/lib/services/http/http.js.map +1 -1
- package/lib/services/output/confirm.js.map +1 -1
- package/lib/services/output/footer.js.map +1 -1
- package/lib/services/output/log/field.js.map +1 -1
- package/lib/services/output/log/format/format.js.map +1 -1
- package/lib/services/output/log/format/json.js.map +1 -1
- package/lib/services/output/log/format/pretty.js.map +1 -1
- package/lib/services/output/log/level.js.map +1 -1
- package/lib/services/output/log/logger.js.map +1 -1
- package/lib/services/output/log/structured.js.map +1 -1
- package/lib/services/output/notify.js.map +1 -1
- package/lib/services/output/output.js.map +1 -1
- package/lib/services/output/print.js.map +1 -1
- package/lib/services/output/problems.js.map +1 -1
- package/lib/services/output/prompt.js.map +1 -1
- package/lib/services/output/report.js.map +1 -1
- package/lib/services/output/select.js.map +1 -1
- package/lib/services/output/spinner.js.map +1 -1
- package/lib/services/output/sprint.js.map +1 -1
- package/lib/services/output/symbols.js.map +1 -1
- package/lib/services/output/table.js.map +1 -1
- package/lib/services/output/timestamp.js.map +1 -1
- package/lib/services/output/update.js.map +1 -1
- package/lib/services/user/session.js.map +1 -1
- package/lib/services/user/user.js.map +1 -1
- package/lib/services/util/assert.js.map +1 -1
- package/lib/services/util/boolean.js.map +1 -1
- package/lib/services/util/collection.js.map +1 -1
- package/lib/services/util/function.js.map +1 -1
- package/lib/services/util/is.js.map +1 -1
- package/lib/services/util/json.js.map +1 -1
- package/lib/services/util/number.js.map +1 -1
- package/lib/services/util/object.js.map +1 -1
- package/lib/services/util/paths.js.map +1 -1
- package/lib/services/util/promise.js.map +1 -1
- package/lib/services/util/types.js.map +1 -1
- package/npm-shrinkwrap.json +2071 -1684
- package/package.json +30 -30
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/services/command/context.ts"],"sourcesContent":["import type { EmptyObject } from \"type-fest\";\nimport type { RootArgs } from \"../../commands/root.js\";\nimport type { Application, Environment } from \"../app/app.js\";\nimport { createLogger, type Logger } from \"../output/log/logger.js\";\nimport type { StructuredLoggerOptions } from \"../output/log/structured.js\";\nimport type { User } from \"../user/user.js\";\nimport { defaults, pick } from \"../util/object.js\";\nimport { PromiseSignal } from \"../util/promise.js\";\nimport type { AnyVoid } from \"../util/types.js\";\nimport { parseArgs, type ArgsDefinition, type ArgsDefinitionResult, type ParseArgsOptions } from \"./arg.js\";\nimport type { AvailableCommand } from \"./command.js\";\n\n/**\n * Represents the options that can be passed to {@linkcode Context.init}.\n */\nexport type ContextInit<Args extends ArgsDefinition> = ParseArgsOptions &\n StructuredLoggerOptions & {\n /**\n * The command that this context is running.\n */\n command?: AvailableCommand;\n\n /**\n * The {@linkcode ArgsDefinition} to use to parse the arguments (`argv`).\n */\n parse?: Args;\n };\n\n/**\n * Represents the options that can be passed to {@linkcode Context.child}.\n *\n * @see {@linkcode Context.child}\n * @see {@linkcode ContextInit}\n */\nexport type ChildContextInit<Args extends ArgsDefinition, Parsed extends ArgsDefinitionResult<ArgsDefinition>> = Partial<\n ContextInit<Args>\n> & {\n /**\n * Replaces the parsed arguments of the parent context.\n */\n overwrite?: Partial<Omit<Parsed, \"_\">>;\n};\n\n/**\n * Represents the context of a command-line operation.\n */\nexport class Context<\n Args extends ArgsDefinition = EmptyObject,\n ParentArgs extends ArgsDefinition = RootArgs,\n ThisArgs extends ArgsDefinition = ParentArgs & Args,\n> extends AbortController {\n /**\n * The parsed command-line arguments for the current context and any\n * parent contexts.\n */\n readonly args: ArgsDefinitionResult<ThisArgs>;\n\n /**\n * A promise that resolves when the context is aborted and all the\n * registered onAbort callbacks have finished.\n */\n readonly done = new PromiseSignal<void>();\n\n /**\n * The logger for the current context.\n */\n #log: Logger;\n\n /**\n * The callbacks that will be called when this context is aborted.\n */\n #onAborts: OnAbort[] = [];\n\n /**\n * The parent context, if any.\n */\n #parent?: Context<ArgsDefinition, ParentArgs>;\n\n /**\n * The command that this context is running.\n */\n #command?: AvailableCommand;\n\n /**\n * The user who is running this command, if any.\n */\n #user?: User;\n\n /**\n * The app this command is running against, if any.\n */\n #app?: Application;\n\n /**\n * The environment this command is running against, if any.\n */\n #env?: Environment;\n\n private constructor({\n parent,\n command,\n args,\n log,\n }: {\n parent?: Context<ArgsDefinition, ParentArgs>;\n command?: AvailableCommand;\n args: ArgsDefinitionResult<ThisArgs>;\n log: Logger;\n }) {\n super();\n this.args = args;\n this.#log = log;\n this.#parent = parent;\n this.#command = command;\n\n // in case this context is ...spread into another object\n this.abort = this.abort.bind(this);\n this.child = this.child.bind(this);\n this.onAbort = this.onAbort.bind(this);\n\n // when the context is aborted, call all the registered callbacks\n this.signal.addEventListener(\n \"abort\",\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n async () => {\n let error: unknown;\n\n // call the callbacks in reverse order, like go's defer\n for (const callback of this.#onAborts.reverse()) {\n try {\n await callback(this.signal.reason);\n } catch (e: unknown) {\n error = e;\n this.log.error(\"error during abort\", { error });\n }\n }\n\n if (error) {\n this.done.reject(error);\n } else {\n this.done.resolve();\n }\n },\n );\n }\n\n /**\n * A {@linkcode Logger} that can print to stdout and log structured\n * messages to stderr.\n */\n get log(): Logger {\n return this.#log;\n }\n\n get command(): AvailableCommand | \"root\" {\n return this.#command ?? this.#parent?.command ?? \"root\";\n }\n\n get user(): User | undefined {\n return this.#user ?? this.#parent?.user;\n }\n\n set user(user: User) {\n this.#user = user;\n if (this.#parent) {\n this.#parent.user = user;\n }\n\n this.#log = this.#log.child({\n fields: { user: { id: user.id } },\n devFields: { user },\n });\n }\n\n // eslint-disable-next-line @typescript-eslint/member-ordering\n get app(): Application | undefined {\n return this.#app ?? this.#parent?.app;\n }\n\n set app(app: Application) {\n this.#app = app;\n if (this.#parent) {\n this.#parent.app = app;\n }\n\n this.#log = this.#log.child({ fields: { app } });\n }\n\n // eslint-disable-next-line @typescript-eslint/member-ordering\n get env(): Environment | undefined {\n return this.#env ?? this.#parent?.env;\n }\n\n set env(env: Environment) {\n this.#env = env;\n if (this.#parent) {\n this.#parent.env = env;\n }\n\n this.#log = this.#log.child({ fields: { env } });\n }\n\n /**\n * Initializes a new context.\n *\n * @see {@linkcode ContextInit}\n */\n static init<Args extends ArgsDefinition = EmptyObject>({ parse: spec, ...options }: ContextInit<Args>): Context<Args> {\n return new Context({\n args: spec ? parseArgs(spec, pick(options, [\"argv\", \"permissive\", \"stopAtPositional\"])) : ({} as ArgsDefinitionResult<Args>),\n log: createLogger(pick(options, [\"name\", \"fields\", \"devFields\"])),\n });\n }\n\n /**\n * Returns a new context that is a child of the current context.\n *\n * @see {@linkcode ChildContextInit}\n */\n child<ChildArgs extends ArgsDefinition = EmptyObject>({\n parse: spec,\n command = this.#command,\n ...options\n }: ChildContextInit<ChildArgs, ArgsDefinitionResult<ThisArgs>>): Context<ChildArgs, ThisArgs> {\n const ctx = new Context<ChildArgs, ThisArgs>({\n parent: this,\n command,\n args: {\n ...this.args,\n ...options.overwrite,\n ...(spec\n ? parseArgs(spec, defaults(pick(options, [\"argv\", \"permissive\", \"stopAtPositional\"]), { argv: this.args._ }))\n : ({} as ArgsDefinitionResult<ChildArgs>)),\n },\n log: this.log.child(pick(options, [\"name\", \"fields\", \"devFields\"])),\n });\n\n this.onAbort(() => ctx.abort());\n\n return ctx;\n }\n\n /**\n * Registers a callback that will be called when the context is\n * aborted (e.g. when the user presses Ctrl+C).\n *\n * @param callback - The callback to call when the context is aborted.\n */\n onAbort(callback: OnAbort): void {\n this.#onAborts.push(callback);\n }\n}\n\n/**\n * A callback that will be called when the context is aborted.\n */\nexport type OnAbort = (reason: unknown) => AnyVoid;\n"],"names":["createLogger","defaults","pick","PromiseSignal","parseArgs","Context","AbortController","log","command","parent","user","child","fields","id","devFields","app","env","init","parse","spec","options","args","ctx","overwrite","argv","_","onAbort","abort","callback","onAborts","push","done","bind","signal","addEventListener","error","reverse","reason","e","reject","resolve"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/services/command/context.ts"],"sourcesContent":["import type { EmptyObject } from \"type-fest\";\nimport type { RootArgs } from \"../../commands/root.js\";\nimport type { Application, Environment } from \"../app/app.js\";\nimport { createLogger, type Logger } from \"../output/log/logger.js\";\nimport type { StructuredLoggerOptions } from \"../output/log/structured.js\";\nimport type { User } from \"../user/user.js\";\nimport { defaults, pick } from \"../util/object.js\";\nimport { PromiseSignal } from \"../util/promise.js\";\nimport type { AnyVoid } from \"../util/types.js\";\nimport { parseArgs, type ArgsDefinition, type ArgsDefinitionResult, type ParseArgsOptions } from \"./arg.js\";\nimport type { AvailableCommand } from \"./command.js\";\n\n/**\n * Represents the options that can be passed to {@linkcode Context.init}.\n */\nexport type ContextInit<Args extends ArgsDefinition> = ParseArgsOptions &\n StructuredLoggerOptions & {\n /**\n * The command that this context is running.\n */\n command?: AvailableCommand;\n\n /**\n * The {@linkcode ArgsDefinition} to use to parse the arguments (`argv`).\n */\n parse?: Args;\n };\n\n/**\n * Represents the options that can be passed to {@linkcode Context.child}.\n *\n * @see {@linkcode Context.child}\n * @see {@linkcode ContextInit}\n */\nexport type ChildContextInit<Args extends ArgsDefinition, Parsed extends ArgsDefinitionResult<ArgsDefinition>> = Partial<\n ContextInit<Args>\n> & {\n /**\n * Replaces the parsed arguments of the parent context.\n */\n overwrite?: Partial<Omit<Parsed, \"_\">>;\n};\n\n/**\n * Represents the context of a command-line operation.\n */\nexport class Context<\n Args extends ArgsDefinition = EmptyObject,\n ParentArgs extends ArgsDefinition = RootArgs,\n ThisArgs extends ArgsDefinition = ParentArgs & Args,\n> extends AbortController {\n /**\n * The parsed command-line arguments for the current context and any\n * parent contexts.\n */\n readonly args: ArgsDefinitionResult<ThisArgs>;\n\n /**\n * A promise that resolves when the context is aborted and all the\n * registered onAbort callbacks have finished.\n */\n readonly done = new PromiseSignal<void>();\n\n /**\n * The logger for the current context.\n */\n #log: Logger;\n\n /**\n * The callbacks that will be called when this context is aborted.\n */\n #onAborts: OnAbort[] = [];\n\n /**\n * The parent context, if any.\n */\n #parent?: Context<ArgsDefinition, ParentArgs>;\n\n /**\n * The command that this context is running.\n */\n #command?: AvailableCommand;\n\n /**\n * The user who is running this command, if any.\n */\n #user?: User;\n\n /**\n * The app this command is running against, if any.\n */\n #app?: Application;\n\n /**\n * The environment this command is running against, if any.\n */\n #env?: Environment;\n\n private constructor({\n parent,\n command,\n args,\n log,\n }: {\n parent?: Context<ArgsDefinition, ParentArgs>;\n command?: AvailableCommand;\n args: ArgsDefinitionResult<ThisArgs>;\n log: Logger;\n }) {\n super();\n this.args = args;\n this.#log = log;\n this.#parent = parent;\n this.#command = command;\n\n // in case this context is ...spread into another object\n this.abort = this.abort.bind(this);\n this.child = this.child.bind(this);\n this.onAbort = this.onAbort.bind(this);\n\n // when the context is aborted, call all the registered callbacks\n this.signal.addEventListener(\n \"abort\",\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n async () => {\n let error: unknown;\n\n // call the callbacks in reverse order, like go's defer\n for (const callback of this.#onAborts.reverse()) {\n try {\n await callback(this.signal.reason);\n } catch (e: unknown) {\n error = e;\n this.log.error(\"error during abort\", { error });\n }\n }\n\n if (error) {\n this.done.reject(error);\n } else {\n this.done.resolve();\n }\n },\n );\n }\n\n /**\n * A {@linkcode Logger} that can print to stdout and log structured\n * messages to stderr.\n */\n get log(): Logger {\n return this.#log;\n }\n\n get command(): AvailableCommand | \"root\" {\n return this.#command ?? this.#parent?.command ?? \"root\";\n }\n\n get user(): User | undefined {\n return this.#user ?? this.#parent?.user;\n }\n\n set user(user: User) {\n this.#user = user;\n if (this.#parent) {\n this.#parent.user = user;\n }\n\n this.#log = this.#log.child({\n fields: { user: { id: user.id } },\n devFields: { user },\n });\n }\n\n // eslint-disable-next-line @typescript-eslint/member-ordering\n get app(): Application | undefined {\n return this.#app ?? this.#parent?.app;\n }\n\n set app(app: Application) {\n this.#app = app;\n if (this.#parent) {\n this.#parent.app = app;\n }\n\n this.#log = this.#log.child({ fields: { app } });\n }\n\n // eslint-disable-next-line @typescript-eslint/member-ordering\n get env(): Environment | undefined {\n return this.#env ?? this.#parent?.env;\n }\n\n set env(env: Environment) {\n this.#env = env;\n if (this.#parent) {\n this.#parent.env = env;\n }\n\n this.#log = this.#log.child({ fields: { env } });\n }\n\n /**\n * Initializes a new context.\n *\n * @see {@linkcode ContextInit}\n */\n static init<Args extends ArgsDefinition = EmptyObject>({ parse: spec, ...options }: ContextInit<Args>): Context<Args> {\n return new Context({\n args: spec ? parseArgs(spec, pick(options, [\"argv\", \"permissive\", \"stopAtPositional\"])) : ({} as ArgsDefinitionResult<Args>),\n log: createLogger(pick(options, [\"name\", \"fields\", \"devFields\"])),\n });\n }\n\n /**\n * Returns a new context that is a child of the current context.\n *\n * @see {@linkcode ChildContextInit}\n */\n child<ChildArgs extends ArgsDefinition = EmptyObject>({\n parse: spec,\n command = this.#command,\n ...options\n }: ChildContextInit<ChildArgs, ArgsDefinitionResult<ThisArgs>>): Context<ChildArgs, ThisArgs> {\n const ctx = new Context<ChildArgs, ThisArgs>({\n parent: this,\n command,\n args: {\n ...this.args,\n ...options.overwrite,\n ...(spec\n ? parseArgs(spec, defaults(pick(options, [\"argv\", \"permissive\", \"stopAtPositional\"]), { argv: this.args._ }))\n : ({} as ArgsDefinitionResult<ChildArgs>)),\n },\n log: this.log.child(pick(options, [\"name\", \"fields\", \"devFields\"])),\n });\n\n this.onAbort(() => ctx.abort());\n\n return ctx;\n }\n\n /**\n * Registers a callback that will be called when the context is\n * aborted (e.g. when the user presses Ctrl+C).\n *\n * @param callback - The callback to call when the context is aborted.\n */\n onAbort(callback: OnAbort): void {\n this.#onAborts.push(callback);\n }\n}\n\n/**\n * A callback that will be called when the context is aborted.\n */\nexport type OnAbort = (reason: unknown) => AnyVoid;\n"],"names":["createLogger","defaults","pick","PromiseSignal","parseArgs","Context","AbortController","log","command","parent","user","child","fields","id","devFields","app","env","init","parse","spec","options","args","ctx","overwrite","argv","_","onAbort","abort","callback","onAborts","push","done","bind","signal","addEventListener","error","reverse","reason","e","reject","resolve"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/services/config/config.ts"],"sourcesContent":["import isWsl from \"is-wsl\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport process from \"node:process\";\nimport { Level, parseLevel } from \"../output/log/level.js\";\nimport { env } from \"./env.js\";\nimport { packageJson } from \"./package-json.js\";\n\nexport const config = {\n get logLevel() {\n return parseLevel(process.env[\"GGT_LOG_LEVEL\"], Level.PRINT);\n },\n\n get logFormat() {\n return process.env[\"GGT_LOG_FORMAT\"] === \"json\" ? \"json\" : \"pretty\";\n },\n\n /**\n * Returns the full version string including name, version, platform,\n * arch, and Node.js version. This is passed as the user agent for all\n * outgoing http requests.\n *\n * @example \"ggt/1.2.3 darwin-arm64 node-v16.0.0\"\n */\n get versionFull(): string {\n return `${packageJson.name}/${packageJson.version} ${this.platform}-${this.arch} node-${process.version}`;\n },\n\n get arch(): string {\n return os.arch() === \"ia32\" ? \"x86\" : os.arch();\n },\n\n get platform(): NodeJS.Platform | \"wsl\" {\n return isWsl ? \"wsl\" : os.platform();\n },\n\n get windows(): boolean {\n return process.platform === \"win32\";\n },\n\n get windowsOrWsl(): boolean {\n return this.windows || isWsl;\n },\n\n get macos(): boolean {\n return process.platform === \"darwin\";\n },\n\n get shell(): string | undefined {\n const SHELL = process.env[\"SHELL\"] ?? os.userInfo().shell?.split(path.sep).pop();\n if (SHELL) {\n return SHELL.split(\"/\").at(-1);\n }\n if (this.windows && process.env[\"COMSPEC\"]) {\n return process.env[\"COMSPEC\"].split(/\\\\|\\//).at(-1);\n }\n return \"unknown\";\n },\n\n get homeDir(): string {\n if (process.env[\"HOME\"]) {\n return process.env[\"HOME\"];\n }\n\n if (this.windows) {\n if (process.env[\"HOMEDRIVE\"] && process.env[\"HOMEPATH\"]) {\n return path.join(process.env[\"HOMEDRIVE\"], process.env[\"HOMEPATH\"]);\n }\n if (process.env[\"USERPROFILE\"]) {\n return process.env[\"USERPROFILE\"];\n }\n }\n\n return os.homedir() || os.tmpdir();\n },\n\n /**\n * - Unix: `~/.config/ggt`\n * - Windows: `%LOCALAPPDATA%\\ggt`\n *\n * Can be overridden by `GGT_CONFIG_DIR`\n */\n get configDir(): string {\n if (process.env[\"GGT_CONFIG_DIR\"]) {\n return process.env[\"GGT_CONFIG_DIR\"];\n }\n\n const base = process.env[\"XDG_CONFIG_HOME\"] || (this.windows && process.env[\"LOCALAPPDATA\"]) || path.join(this.homeDir, \".config\");\n return path.join(base, \"ggt\");\n },\n\n /**\n * - Linux: `~/.cache/ggt`\n * - macOS: `~/Library/Caches/ggt`\n * - Windows: `%LOCALAPPDATA%\\ggt`\n *\n * Can be overridden with `GGT_CACHE_DIR`\n */\n get cacheDir(): string {\n if (process.env[\"GGT_CACHE_DIR\"]) {\n return process.env[\"GGT_CACHE_DIR\"];\n }\n\n if (this.macos) {\n return path.join(this.homeDir, \"Library/Caches/ggt\");\n }\n\n const base = process.env[\"XDG_CACHE_HOME\"] || (this.windows && process.env[\"LOCALAPPDATA\"]) || path.join(this.homeDir, \".cache\");\n return path.join(base, \"ggt\");\n },\n\n /**\n * - Unix: `~/.local/share/ggt`\n * - Windows: `%LOCALAPPDATA%\\ggt`\n *\n * Can be overridden with `GGT_DATA_DIR`\n */\n get dataDir(): string {\n if (process.env[\"GGT_DATA_DIR\"]) {\n return process.env[\"GGT_DATA_DIR\"];\n }\n\n const base = process.env[\"XDG_DATA_HOME\"] || (this.windows && process.env[\"LOCALAPPDATA\"]) || path.join(this.homeDir, \".local/share\");\n return path.join(base, \"ggt\");\n },\n\n /**\n * Domains for various Gadget services.\n */\n domains: {\n /**\n * The domain for the Gadget applications. This is where the user's application is hosted.\n */\n get app() {\n return process.env[\"GGT_GADGET_APP_DOMAIN\"] || (env.productionLike ? \"gadget.app\" : \"ggt.pub\");\n },\n\n /**\n * The domain for the Gadget services. This is where Gadget's API is hosted.\n */\n get services() {\n return process.env[\"GGT_GADGET_SERVICES_DOMAIN\"] || (env.productionLike ? \"app.gadget.dev\" : \"app.ggt.dev\");\n },\n },\n};\n\n/**\n * Returns an absolute path within the {@linkcode config.configDir}\n * directory.\n *\n * @param segments - The segments of the path to join.\n * @returns The absolute path to the file or directory.\n */\nexport const configPath = (...segments: string[]): string => path.join(config.configDir, ...segments);\n\n/**\n * Returns an absolute path within the {@linkcode config.homeDir}\n * directory.\n *\n * @param segments - The segments of the path to join.\n * @returns The absolute path to the file or directory.\n */\nexport const homePath = (...segments: string[]): string => path.join(config.homeDir, ...segments);\n"],"names":["isWsl","os","path","process","Level","parseLevel","env","packageJson","config","logLevel","PRINT","logFormat","versionFull","name","version","platform","arch","windows","windowsOrWsl","macos","shell","SHELL","userInfo","split","sep","pop","at","homeDir","join","homedir","tmpdir","configDir","base","cacheDir","dataDir","domains","app","productionLike","services","configPath","segments","homePath"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/services/config/config.ts"],"sourcesContent":["import isWsl from \"is-wsl\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport process from \"node:process\";\nimport { Level, parseLevel } from \"../output/log/level.js\";\nimport { env } from \"./env.js\";\nimport { packageJson } from \"./package-json.js\";\n\nexport const config = {\n get logLevel() {\n return parseLevel(process.env[\"GGT_LOG_LEVEL\"], Level.PRINT);\n },\n\n get logFormat() {\n return process.env[\"GGT_LOG_FORMAT\"] === \"json\" ? \"json\" : \"pretty\";\n },\n\n /**\n * Returns the full version string including name, version, platform,\n * arch, and Node.js version. This is passed as the user agent for all\n * outgoing http requests.\n *\n * @example \"ggt/1.2.3 darwin-arm64 node-v16.0.0\"\n */\n get versionFull(): string {\n return `${packageJson.name}/${packageJson.version} ${this.platform}-${this.arch} node-${process.version}`;\n },\n\n get arch(): string {\n return os.arch() === \"ia32\" ? \"x86\" : os.arch();\n },\n\n get platform(): NodeJS.Platform | \"wsl\" {\n return isWsl ? \"wsl\" : os.platform();\n },\n\n get windows(): boolean {\n return process.platform === \"win32\";\n },\n\n get windowsOrWsl(): boolean {\n return this.windows || isWsl;\n },\n\n get macos(): boolean {\n return process.platform === \"darwin\";\n },\n\n get shell(): string | undefined {\n const SHELL = process.env[\"SHELL\"] ?? os.userInfo().shell?.split(path.sep).pop();\n if (SHELL) {\n return SHELL.split(\"/\").at(-1);\n }\n if (this.windows && process.env[\"COMSPEC\"]) {\n return process.env[\"COMSPEC\"].split(/\\\\|\\//).at(-1);\n }\n return \"unknown\";\n },\n\n get homeDir(): string {\n if (process.env[\"HOME\"]) {\n return process.env[\"HOME\"];\n }\n\n if (this.windows) {\n if (process.env[\"HOMEDRIVE\"] && process.env[\"HOMEPATH\"]) {\n return path.join(process.env[\"HOMEDRIVE\"], process.env[\"HOMEPATH\"]);\n }\n if (process.env[\"USERPROFILE\"]) {\n return process.env[\"USERPROFILE\"];\n }\n }\n\n return os.homedir() || os.tmpdir();\n },\n\n /**\n * - Unix: `~/.config/ggt`\n * - Windows: `%LOCALAPPDATA%\\ggt`\n *\n * Can be overridden by `GGT_CONFIG_DIR`\n */\n get configDir(): string {\n if (process.env[\"GGT_CONFIG_DIR\"]) {\n return process.env[\"GGT_CONFIG_DIR\"];\n }\n\n const base = process.env[\"XDG_CONFIG_HOME\"] || (this.windows && process.env[\"LOCALAPPDATA\"]) || path.join(this.homeDir, \".config\");\n return path.join(base, \"ggt\");\n },\n\n /**\n * - Linux: `~/.cache/ggt`\n * - macOS: `~/Library/Caches/ggt`\n * - Windows: `%LOCALAPPDATA%\\ggt`\n *\n * Can be overridden with `GGT_CACHE_DIR`\n */\n get cacheDir(): string {\n if (process.env[\"GGT_CACHE_DIR\"]) {\n return process.env[\"GGT_CACHE_DIR\"];\n }\n\n if (this.macos) {\n return path.join(this.homeDir, \"Library/Caches/ggt\");\n }\n\n const base = process.env[\"XDG_CACHE_HOME\"] || (this.windows && process.env[\"LOCALAPPDATA\"]) || path.join(this.homeDir, \".cache\");\n return path.join(base, \"ggt\");\n },\n\n /**\n * - Unix: `~/.local/share/ggt`\n * - Windows: `%LOCALAPPDATA%\\ggt`\n *\n * Can be overridden with `GGT_DATA_DIR`\n */\n get dataDir(): string {\n if (process.env[\"GGT_DATA_DIR\"]) {\n return process.env[\"GGT_DATA_DIR\"];\n }\n\n const base = process.env[\"XDG_DATA_HOME\"] || (this.windows && process.env[\"LOCALAPPDATA\"]) || path.join(this.homeDir, \".local/share\");\n return path.join(base, \"ggt\");\n },\n\n /**\n * Domains for various Gadget services.\n */\n domains: {\n /**\n * The domain for the Gadget applications. This is where the user's application is hosted.\n */\n get app() {\n return process.env[\"GGT_GADGET_APP_DOMAIN\"] || (env.productionLike ? \"gadget.app\" : \"ggt.pub\");\n },\n\n /**\n * The domain for the Gadget services. This is where Gadget's API is hosted.\n */\n get services() {\n return process.env[\"GGT_GADGET_SERVICES_DOMAIN\"] || (env.productionLike ? \"app.gadget.dev\" : \"app.ggt.dev\");\n },\n },\n};\n\n/**\n * Returns an absolute path within the {@linkcode config.configDir}\n * directory.\n *\n * @param segments - The segments of the path to join.\n * @returns The absolute path to the file or directory.\n */\nexport const configPath = (...segments: string[]): string => path.join(config.configDir, ...segments);\n\n/**\n * Returns an absolute path within the {@linkcode config.homeDir}\n * directory.\n *\n * @param segments - The segments of the path to join.\n * @returns The absolute path to the file or directory.\n */\nexport const homePath = (...segments: string[]): string => path.join(config.homeDir, ...segments);\n"],"names":["isWsl","os","path","process","Level","parseLevel","env","packageJson","config","logLevel","PRINT","logFormat","versionFull","name","version","platform","arch","windows","windowsOrWsl","macos","shell","SHELL","userInfo","split","sep","pop","at","homeDir","join","homedir","tmpdir","configDir","base","cacheDir","dataDir","domains","app","productionLike","services","configPath","segments","homePath"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/services/config/env.ts"],"sourcesContent":["import process from \"node:process\";\n\n/**\n * Captures the current environment ggt is running in.\n */\nexport const env = {\n get value(): string {\n return process.env[\"GGT_ENV\"] || \"production\";\n },\n\n get productionLike(): boolean {\n return !this.developmentOrTestLike;\n },\n\n get developmentLike(): boolean {\n return this.value.startsWith(\"development\");\n },\n\n get testLike(): boolean {\n return this.value.startsWith(\"test\");\n },\n\n get developmentOrTestLike(): boolean {\n return this.developmentLike || this.testLike;\n },\n};\n"],"names":["process","env","value","productionLike","developmentOrTestLike","developmentLike","startsWith","testLike"],"mappings":"AAAA,OAAOA,aAAa,eAAe;AAEnC;;CAEC,GACD,OAAO,MAAMC,MAAM;IACjB,IAAIC,SAAgB;QAClB,OAAOF,QAAQC,GAAG,CAAC,UAAU,IAAI;IACnC;IAEA,IAAIE,kBAA0B;QAC5B,OAAO,CAAC,IAAI,CAACC,qBAAqB;IACpC;IAEA,IAAIC,mBAA2B;QAC7B,OAAO,IAAI,CAACH,KAAK,CAACI,UAAU,CAAC;IAC/B;IAEA,IAAIC,YAAoB;QACtB,OAAO,IAAI,CAACL,KAAK,CAACI,UAAU,CAAC;IAC/B;IAEA,IAAIF,yBAAiC;QACnC,OAAO,IAAI,CAACC,eAAe,IAAI,IAAI,CAACE,QAAQ;IAC9C;AACF,EAAE"}
|
|
1
|
+
{"version":3,"sources":["../../../src/services/config/env.ts"],"sourcesContent":["import process from \"node:process\";\n\n/**\n * Captures the current environment ggt is running in.\n */\nexport const env = {\n get value(): string {\n return process.env[\"GGT_ENV\"] || \"production\";\n },\n\n get productionLike(): boolean {\n return !this.developmentOrTestLike;\n },\n\n get developmentLike(): boolean {\n return this.value.startsWith(\"development\");\n },\n\n get testLike(): boolean {\n return this.value.startsWith(\"test\");\n },\n\n get developmentOrTestLike(): boolean {\n return this.developmentLike || this.testLike;\n },\n};\n"],"names":["process","env","value","productionLike","developmentOrTestLike","developmentLike","startsWith","testLike"],"rangeMappings":";;;;;;;;;;;;;;;;;;;","mappings":"AAAA,OAAOA,aAAa,eAAe;AAEnC;;CAEC,GACD,OAAO,MAAMC,MAAM;IACjB,IAAIC,SAAgB;QAClB,OAAOF,QAAQC,GAAG,CAAC,UAAU,IAAI;IACnC;IAEA,IAAIE,kBAA0B;QAC5B,OAAO,CAAC,IAAI,CAACC,qBAAqB;IACpC;IAEA,IAAIC,mBAA2B;QAC7B,OAAO,IAAI,CAACH,KAAK,CAACI,UAAU,CAAC;IAC/B;IAEA,IAAIC,YAAoB;QACtB,OAAO,IAAI,CAACL,KAAK,CAACI,UAAU,CAAC;IAC/B;IAEA,IAAIF,yBAAiC;QACnC,OAAO,IAAI,CAACC,eAAe,IAAI,IAAI,CAACE,QAAQ;IAC9C;AACF,EAAE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/services/config/package-json.ts"],"sourcesContent":["import fs from \"fs-extra\";\nimport type { Package } from \"normalize-package-data\";\nimport normalizePackageData from \"normalize-package-data\";\nimport { workspacePath } from \"../util/paths.js\";\n\n/**\n * The package.json of the ggt package.\n */\nexport const packageJson = (await fs.readJson(workspacePath(\"package.json\"))) as Package;\n\nnormalizePackageData(packageJson, true);\n"],"names":["fs","normalizePackageData","workspacePath","packageJson","readJson"],"mappings":"AAAA,OAAOA,QAAQ,WAAW;AAE1B,OAAOC,0BAA0B,yBAAyB;AAC1D,SAASC,aAAa,QAAQ,mBAAmB;AAEjD;;CAEC,GACD,OAAO,MAAMC,cAAe,MAAMH,GAAGI,QAAQ,CAACF,cAAc,iBAA6B;AAEzFD,qBAAqBE,aAAa"}
|
|
1
|
+
{"version":3,"sources":["../../../src/services/config/package-json.ts"],"sourcesContent":["import fs from \"fs-extra\";\nimport type { Package } from \"normalize-package-data\";\nimport normalizePackageData from \"normalize-package-data\";\nimport { workspacePath } from \"../util/paths.js\";\n\n/**\n * The package.json of the ggt package.\n */\nexport const packageJson = (await fs.readJson(workspacePath(\"package.json\"))) as Package;\n\nnormalizePackageData(packageJson, true);\n"],"names":["fs","normalizePackageData","workspacePath","packageJson","readJson"],"rangeMappings":";;;;;;","mappings":"AAAA,OAAOA,QAAQ,WAAW;AAE1B,OAAOC,0BAA0B,yBAAyB;AAC1D,SAASC,aAAa,QAAQ,mBAAmB;AAEjD;;CAEC,GACD,OAAO,MAAMC,cAAe,MAAMH,GAAGI,QAAQ,CAACF,cAAc,iBAA6B;AAEzFD,qBAAqBE,aAAa"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/services/filesync/changes.ts"],"sourcesContent":["import chalk from \"chalk\";\nimport pluralize from \"pluralize\";\nimport type { Context } from \"../command/context.js\";\nimport { config } from \"../config/config.js\";\nimport { Level } from \"../output/log/level.js\";\nimport { println } from \"../output/print.js\";\nimport { sprint, sprintln } from \"../output/sprint.js\";\nimport { symbol } from \"../output/symbols.js\";\nimport { sprintTable, type SprintTableOptions } from \"../output/table.js\";\nimport { memo } from \"../util/function.js\";\nimport { isNever, isString } from \"../util/is.js\";\nimport type { ChangesWithHash } from \"./hashes.js\";\n\nexport type Create = { type: \"create\"; oldPath?: string };\nexport type Update = { type: \"update\" };\nexport type Delete = { type: \"delete\" };\nexport type Change = Create | Update | Delete;\n\nexport class Changes extends Map<string, Change> {\n created = memo((): string[] => {\n return Array.from(this.entries())\n .filter(([, change]) => change.type === \"create\")\n .map(([path]) => path);\n });\n\n updated = memo((): string[] => {\n return Array.from(this.entries())\n .filter(([, change]) => change.type === \"update\")\n .map(([path]) => path);\n });\n\n deleted = memo((): string[] => {\n return Array.from(this.entries())\n .filter(([, change]) => change.type === \"delete\")\n .map(([path]) => path);\n });\n}\n\nexport type PrintChangesOptions = Partial<SprintTableOptions> & {\n /**\n * The tense to use for the change type.\n */\n tense: \"past\" | \"present\";\n\n /**\n * Whether to include `.gadget/` files in the output.\n *\n * @default undefined (true if there are no other changes, false otherwise)\n */\n includeDotGadget?: boolean;\n\n /**\n * The maximum number of changes to print.\n *\n * @default Infinity\n */\n limit?: number;\n};\n\nconst createdSymbol = chalk.greenBright(\"+\");\nconst updatedSymbol = chalk.blueBright(\"±\");\nconst deletedSymbol = chalk.redBright(\"-\");\nconst renameSymbol = chalk.yellowBright(\"→\");\n\n/**\n * Prints the changes to the console.\n *\n * @param _ctx - The current context.\n * @see {@linkcode SprintChangesOptions}\n */\nexport const sprintChanges = (\n _ctx: Context,\n { changes, tense, includeDotGadget, limit = Infinity, ...tableOptions }: { changes: Changes | ChangesWithHash } & PrintChangesOptions,\n): string => {\n if (config.logLevel <= Level.TRACE) {\n // print all changes when tracing\n limit = Infinity;\n }\n\n let changesToPrint = Array.from(changes.entries());\n\n if (includeDotGadget === undefined && changesToPrint.every(([filepath]) => filepath.startsWith(\".gadget/\"))) {\n // we weren't explicitly told to exclude `.gadget/` files, and all\n // the changes are to files within `.gadget/`, so include them since\n // there's nothing else to show\n includeDotGadget = true;\n }\n\n if (!includeDotGadget) {\n changesToPrint = changesToPrint.filter(([filepath]) => !filepath.startsWith(\".gadget/\"));\n }\n\n const renamed = chalk.yellowBright(tense === \"past\" ? \"renamed\" : \"rename\");\n const created = chalk.greenBright(tense === \"past\" ? \"created\" : \"create\");\n const updated = chalk.blueBright(tense === \"past\" ? \"updated\" : \"update\");\n const deleted = chalk.redBright(tense === \"past\" ? \"deleted\" : \"delete\");\n\n const rows = changesToPrint\n .sort((a, b) => a[0].localeCompare(b[0]))\n .slice(0, limit)\n .map(([path, change]) => {\n switch (true) {\n case change.type === \"create\" && isString(change.oldPath):\n return [renameSymbol, chalk.yellowBright(change.oldPath), renamed, renameSymbol, chalk.yellowBright(path)];\n case change.type === \"create\":\n return [createdSymbol, chalk.greenBright(path), created];\n case change.type === \"update\":\n return [updatedSymbol, chalk.blueBright(path), updated];\n case change.type === \"delete\":\n return [deletedSymbol, chalk.redBright(path), deleted];\n default:\n return isNever(change);\n }\n });\n\n if (changesToPrint.length > limit) {\n rows.push([chalk.gray(symbol.ellipsis), sprint`{gray ${changesToPrint.length - limit} more}`, \"\"]);\n }\n\n let footer: string | undefined;\n if (changesToPrint.length >= 5) {\n const breakdown = [];\n\n const createdCount = changesToPrint.filter(([, change]) => change.type === \"create\").length;\n if (createdCount > 0) {\n const created = tense === \"past\" ? `${createdCount} created` : pluralize(\"create\", createdCount, true);\n breakdown.push(sprint`{greenBright ${created}}`);\n }\n\n const updatedCount = changesToPrint.filter(([, change]) => change.type === \"update\").length;\n if (updatedCount > 0) {\n const updated = tense === \"past\" ? `${updatedCount} updated` : pluralize(\"update\", updatedCount, true);\n breakdown.push(sprint`{blueBright ${updated}}`);\n }\n\n const deletedCount = changesToPrint.filter(([, change]) => change.type === \"delete\").length;\n if (deletedCount > 0) {\n const deleted = tense === \"past\" ? `${deletedCount} deleted` : pluralize(\"delete\", deletedCount, true);\n breakdown.push(sprint`{redBright ${deleted}}`);\n }\n\n footer = sprintln`\n ${pluralize(\"change\", changesToPrint.length, true)} in total. ${breakdown.join(\", \")}.\n `;\n }\n\n return sprintTable({\n rows,\n footer,\n ensureEmptyLineAbove: true,\n ensureEmptyLineAboveBody: false,\n ensureEmptyLineAboveFooter: true,\n indent: 0,\n ...tableOptions,\n });\n};\n\n/**\n * Prints the changes to the console.\n *\n * @param _ctx - The current context.\n * @see {@linkcode SprintChangesOptions}\n */\nexport const printChanges = (_ctx: Context, options: { changes: Changes | ChangesWithHash } & PrintChangesOptions): void => {\n println(sprintChanges(_ctx, options));\n};\n"],"names":["chalk","pluralize","config","Level","println","sprint","sprintln","symbol","sprintTable","memo","isNever","isString","Changes","Map","created","Array","from","entries","filter","change","type","map","path","updated","deleted","createdSymbol","greenBright","updatedSymbol","blueBright","deletedSymbol","redBright","renameSymbol","yellowBright","sprintChanges","_ctx","changes","tense","includeDotGadget","limit","Infinity","tableOptions","logLevel","TRACE","changesToPrint","undefined","every","filepath","startsWith","renamed","rows","sort","a","b","localeCompare","slice","oldPath","length","push","gray","ellipsis","footer","breakdown","createdCount","updatedCount","deletedCount","join","ensureEmptyLineAbove","ensureEmptyLineAboveBody","ensureEmptyLineAboveFooter","indent","printChanges","options"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/services/filesync/changes.ts"],"sourcesContent":["import chalk from \"chalk\";\nimport pluralize from \"pluralize\";\nimport type { Context } from \"../command/context.js\";\nimport { config } from \"../config/config.js\";\nimport { Level } from \"../output/log/level.js\";\nimport { println } from \"../output/print.js\";\nimport { sprint, sprintln } from \"../output/sprint.js\";\nimport { symbol } from \"../output/symbols.js\";\nimport { sprintTable, type SprintTableOptions } from \"../output/table.js\";\nimport { memo } from \"../util/function.js\";\nimport { isNever, isString } from \"../util/is.js\";\nimport type { ChangesWithHash } from \"./hashes.js\";\n\nexport type Create = { type: \"create\"; oldPath?: string };\nexport type Update = { type: \"update\" };\nexport type Delete = { type: \"delete\" };\nexport type Change = Create | Update | Delete;\n\nexport class Changes extends Map<string, Change> {\n created = memo((): string[] => {\n return Array.from(this.entries())\n .filter(([, change]) => change.type === \"create\")\n .map(([path]) => path);\n });\n\n updated = memo((): string[] => {\n return Array.from(this.entries())\n .filter(([, change]) => change.type === \"update\")\n .map(([path]) => path);\n });\n\n deleted = memo((): string[] => {\n return Array.from(this.entries())\n .filter(([, change]) => change.type === \"delete\")\n .map(([path]) => path);\n });\n}\n\nexport type PrintChangesOptions = Partial<SprintTableOptions> & {\n /**\n * The tense to use for the change type.\n */\n tense: \"past\" | \"present\";\n\n /**\n * Whether to include `.gadget/` files in the output.\n *\n * @default undefined (true if there are no other changes, false otherwise)\n */\n includeDotGadget?: boolean;\n\n /**\n * The maximum number of changes to print.\n *\n * @default Infinity\n */\n limit?: number;\n};\n\nconst createdSymbol = chalk.greenBright(\"+\");\nconst updatedSymbol = chalk.blueBright(\"±\");\nconst deletedSymbol = chalk.redBright(\"-\");\nconst renameSymbol = chalk.yellowBright(\"→\");\n\n/**\n * Prints the changes to the console.\n *\n * @param _ctx - The current context.\n * @see {@linkcode SprintChangesOptions}\n */\nexport const sprintChanges = (\n _ctx: Context,\n { changes, tense, includeDotGadget, limit = Infinity, ...tableOptions }: { changes: Changes | ChangesWithHash } & PrintChangesOptions,\n): string => {\n if (config.logLevel <= Level.TRACE) {\n // print all changes when tracing\n limit = Infinity;\n }\n\n let changesToPrint = Array.from(changes.entries());\n\n if (includeDotGadget === undefined && changesToPrint.every(([filepath]) => filepath.startsWith(\".gadget/\"))) {\n // we weren't explicitly told to exclude `.gadget/` files, and all\n // the changes are to files within `.gadget/`, so include them since\n // there's nothing else to show\n includeDotGadget = true;\n }\n\n if (!includeDotGadget) {\n changesToPrint = changesToPrint.filter(([filepath]) => !filepath.startsWith(\".gadget/\"));\n }\n\n const renamed = chalk.yellowBright(tense === \"past\" ? \"renamed\" : \"rename\");\n const created = chalk.greenBright(tense === \"past\" ? \"created\" : \"create\");\n const updated = chalk.blueBright(tense === \"past\" ? \"updated\" : \"update\");\n const deleted = chalk.redBright(tense === \"past\" ? \"deleted\" : \"delete\");\n\n const rows = changesToPrint\n .sort((a, b) => a[0].localeCompare(b[0]))\n .slice(0, limit)\n .map(([path, change]) => {\n switch (true) {\n case change.type === \"create\" && isString(change.oldPath):\n return [renameSymbol, chalk.yellowBright(change.oldPath), renamed, renameSymbol, chalk.yellowBright(path)];\n case change.type === \"create\":\n return [createdSymbol, chalk.greenBright(path), created];\n case change.type === \"update\":\n return [updatedSymbol, chalk.blueBright(path), updated];\n case change.type === \"delete\":\n return [deletedSymbol, chalk.redBright(path), deleted];\n default:\n return isNever(change);\n }\n });\n\n if (changesToPrint.length > limit) {\n rows.push([chalk.gray(symbol.ellipsis), sprint`{gray ${changesToPrint.length - limit} more}`, \"\"]);\n }\n\n let footer: string | undefined;\n if (changesToPrint.length >= 5) {\n const breakdown = [];\n\n const createdCount = changesToPrint.filter(([, change]) => change.type === \"create\").length;\n if (createdCount > 0) {\n const created = tense === \"past\" ? `${createdCount} created` : pluralize(\"create\", createdCount, true);\n breakdown.push(sprint`{greenBright ${created}}`);\n }\n\n const updatedCount = changesToPrint.filter(([, change]) => change.type === \"update\").length;\n if (updatedCount > 0) {\n const updated = tense === \"past\" ? `${updatedCount} updated` : pluralize(\"update\", updatedCount, true);\n breakdown.push(sprint`{blueBright ${updated}}`);\n }\n\n const deletedCount = changesToPrint.filter(([, change]) => change.type === \"delete\").length;\n if (deletedCount > 0) {\n const deleted = tense === \"past\" ? `${deletedCount} deleted` : pluralize(\"delete\", deletedCount, true);\n breakdown.push(sprint`{redBright ${deleted}}`);\n }\n\n footer = sprintln`\n ${pluralize(\"change\", changesToPrint.length, true)} in total. ${breakdown.join(\", \")}.\n `;\n }\n\n return sprintTable({\n rows,\n footer,\n ensureEmptyLineAbove: true,\n ensureEmptyLineAboveBody: false,\n ensureEmptyLineAboveFooter: true,\n indent: 0,\n ...tableOptions,\n });\n};\n\n/**\n * Prints the changes to the console.\n *\n * @param _ctx - The current context.\n * @see {@linkcode SprintChangesOptions}\n */\nexport const printChanges = (_ctx: Context, options: { changes: Changes | ChangesWithHash } & PrintChangesOptions): void => {\n println(sprintChanges(_ctx, options));\n};\n"],"names":["chalk","pluralize","config","Level","println","sprint","sprintln","symbol","sprintTable","memo","isNever","isString","Changes","Map","created","Array","from","entries","filter","change","type","map","path","updated","deleted","createdSymbol","greenBright","updatedSymbol","blueBright","deletedSymbol","redBright","renameSymbol","yellowBright","sprintChanges","_ctx","changes","tense","includeDotGadget","limit","Infinity","tableOptions","logLevel","TRACE","changesToPrint","undefined","every","filepath","startsWith","renamed","rows","sort","a","b","localeCompare","slice","oldPath","length","push","gray","ellipsis","footer","breakdown","createdCount","updatedCount","deletedCount","join","ensureEmptyLineAbove","ensureEmptyLineAboveBody","ensureEmptyLineAboveFooter","indent","printChanges","options"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/services/filesync/conflicts.ts"],"sourcesContent":["import chalk from \"chalk\";\nimport { printTable } from \"../output/table.js\";\nimport { ChangesWithHash, isEqualHash, type ChangeWithHash } from \"./hashes.js\";\n\n/**\n * A map of conflicting changes made between the user's local filesystem\n * and Gadget's filesystem where the key is the path of the conflicting\n * file and the value is an object containing the conflicting changes.\n */\nexport class Conflicts extends Map<string, { localChange: ChangeWithHash; gadgetChange: ChangeWithHash }> {}\n\n/**\n * Returns the conflicting changes between the user's local filesystem\n * and Gadget's filesystem.\n */\nexport const getConflicts = ({\n localChanges,\n environmentChanges,\n}: {\n localChanges: ChangesWithHash;\n environmentChanges: ChangesWithHash;\n}): Conflicts => {\n const conflicts = new Conflicts();\n\n for (const [filepath, localChange] of localChanges) {\n const gadgetChange = environmentChanges.get(filepath);\n if (!gadgetChange) {\n // gadget doesn't have this change, so there's no conflict\n continue;\n }\n\n if (localChange.type === \"delete\" && gadgetChange.type === \"delete\") {\n // local and gadget both deleted the same file\n continue;\n }\n\n if (\n \"targetHash\" in localChange &&\n \"targetHash\" in gadgetChange &&\n isEqualHash(filepath, localChange.targetHash, gadgetChange.targetHash)\n ) {\n // local and gadget both created/updated the same file with the same content\n continue;\n }\n\n // local and gadget both updated the same file with different\n // content or one updated and the other deleted\n conflicts.set(filepath, { localChange, gadgetChange });\n }\n\n // ignore .gadget/ file conflicts and always use gadget's version\n // since gadget is the source of truth for .gadget/ files\n for (const filepath of conflicts.keys()) {\n if (filepath.startsWith(\".gadget/\")) {\n conflicts.delete(filepath);\n }\n }\n\n return conflicts;\n};\n\n/**\n * Returns a new `Changes` object that contains only the changes that do\n * not have conflicts.\n *\n * @param options - The options to use.\n * @param options.conflicts - The conflicts to check against.\n * @param options.changes - The changes to filter.\n * @returns A new {@linkcode Changes} object without conflicts.\n */\nexport const withoutConflictingChanges = ({ conflicts, changes }: { conflicts: Conflicts; changes: ChangesWithHash }): ChangesWithHash => {\n const changesWithoutConflicts = new ChangesWithHash(changes);\n\n for (const [filepath] of changesWithoutConflicts) {\n if (conflicts.has(filepath)) {\n changesWithoutConflicts.delete(filepath);\n }\n }\n\n return changesWithoutConflicts;\n};\n\n/**\n * Prints a table of conflicts between local changes and gadget changes.\n *\n * @param options - The options to use.\n * @param options.conflicts - The conflicts to print.\n */\n// TODO: write a snapshot test for this!\nexport const printConflicts = ({ conflicts }: { conflicts: Conflicts }): void => {\n const created = chalk.greenBright(\"+ created\");\n const updated = chalk.blueBright(\"± updated\");\n const deleted = chalk.redBright(\"- deleted\");\n\n printTable({\n title: \"These files have conflicting changes.\",\n ensureEmptyLineAbove: true,\n ensureEmptyLineAboveBody: true,\n colAligns: [\"left\", \"center\", \"center\"],\n headers: [\"\", \"You\", \"Environment\"],\n rows: Array.from(conflicts.entries())\n .sort((a, b) => a[0].localeCompare(b[0]))\n .map(([path, { localChange, gadgetChange }]) => {\n switch (true) {\n case localChange.type === \"create\" && gadgetChange.type === \"create\":\n return [path, created, created];\n case localChange.type === \"create\" && gadgetChange.type === \"update\":\n return [path, created, updated];\n case localChange.type === \"create\" && gadgetChange.type === \"delete\":\n return [path, created, deleted];\n case localChange.type === \"update\" && gadgetChange.type === \"create\":\n return [path, updated, created];\n case localChange.type === \"update\" && gadgetChange.type === \"update\":\n return [path, updated, updated];\n case localChange.type === \"update\" && gadgetChange.type === \"delete\":\n return [path, updated, deleted];\n case localChange.type === \"delete\" && gadgetChange.type === \"create\":\n return [path, deleted, created];\n case localChange.type === \"delete\" && gadgetChange.type === \"update\":\n return [path, deleted, updated];\n default:\n throw new Error(`Unexpected conflict: ${localChange.type} vs ${gadgetChange.type}`);\n }\n }),\n });\n};\n"],"names":["chalk","printTable","ChangesWithHash","isEqualHash","Conflicts","Map","getConflicts","localChanges","environmentChanges","conflicts","filepath","localChange","gadgetChange","get","type","targetHash","set","keys","startsWith","delete","withoutConflictingChanges","changes","changesWithoutConflicts","has","printConflicts","created","greenBright","updated","blueBright","deleted","redBright","title","ensureEmptyLineAbove","ensureEmptyLineAboveBody","colAligns","headers","rows","Array","from","entries","sort","a","b","localeCompare","map","path","Error"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/services/filesync/conflicts.ts"],"sourcesContent":["import chalk from \"chalk\";\nimport { printTable } from \"../output/table.js\";\nimport { ChangesWithHash, isEqualHash, type ChangeWithHash } from \"./hashes.js\";\n\n/**\n * A map of conflicting changes made between the user's local filesystem\n * and Gadget's filesystem where the key is the path of the conflicting\n * file and the value is an object containing the conflicting changes.\n */\nexport class Conflicts extends Map<string, { localChange: ChangeWithHash; gadgetChange: ChangeWithHash }> {}\n\n/**\n * Returns the conflicting changes between the user's local filesystem\n * and Gadget's filesystem.\n */\nexport const getConflicts = ({\n localChanges,\n environmentChanges,\n}: {\n localChanges: ChangesWithHash;\n environmentChanges: ChangesWithHash;\n}): Conflicts => {\n const conflicts = new Conflicts();\n\n for (const [filepath, localChange] of localChanges) {\n const gadgetChange = environmentChanges.get(filepath);\n if (!gadgetChange) {\n // gadget doesn't have this change, so there's no conflict\n continue;\n }\n\n if (localChange.type === \"delete\" && gadgetChange.type === \"delete\") {\n // local and gadget both deleted the same file\n continue;\n }\n\n if (\n \"targetHash\" in localChange &&\n \"targetHash\" in gadgetChange &&\n isEqualHash(filepath, localChange.targetHash, gadgetChange.targetHash)\n ) {\n // local and gadget both created/updated the same file with the same content\n continue;\n }\n\n // local and gadget both updated the same file with different\n // content or one updated and the other deleted\n conflicts.set(filepath, { localChange, gadgetChange });\n }\n\n // ignore .gadget/ file conflicts and always use gadget's version\n // since gadget is the source of truth for .gadget/ files\n for (const filepath of conflicts.keys()) {\n if (filepath.startsWith(\".gadget/\")) {\n conflicts.delete(filepath);\n }\n }\n\n return conflicts;\n};\n\n/**\n * Returns a new `Changes` object that contains only the changes that do\n * not have conflicts.\n *\n * @param options - The options to use.\n * @param options.conflicts - The conflicts to check against.\n * @param options.changes - The changes to filter.\n * @returns A new {@linkcode Changes} object without conflicts.\n */\nexport const withoutConflictingChanges = ({ conflicts, changes }: { conflicts: Conflicts; changes: ChangesWithHash }): ChangesWithHash => {\n const changesWithoutConflicts = new ChangesWithHash(changes);\n\n for (const [filepath] of changesWithoutConflicts) {\n if (conflicts.has(filepath)) {\n changesWithoutConflicts.delete(filepath);\n }\n }\n\n return changesWithoutConflicts;\n};\n\n/**\n * Prints a table of conflicts between local changes and gadget changes.\n *\n * @param options - The options to use.\n * @param options.conflicts - The conflicts to print.\n */\n// TODO: write a snapshot test for this!\nexport const printConflicts = ({ conflicts }: { conflicts: Conflicts }): void => {\n const created = chalk.greenBright(\"+ created\");\n const updated = chalk.blueBright(\"± updated\");\n const deleted = chalk.redBright(\"- deleted\");\n\n printTable({\n title: \"These files have conflicting changes.\",\n ensureEmptyLineAbove: true,\n ensureEmptyLineAboveBody: true,\n colAligns: [\"left\", \"center\", \"center\"],\n headers: [\"\", \"You\", \"Environment\"],\n rows: Array.from(conflicts.entries())\n .sort((a, b) => a[0].localeCompare(b[0]))\n .map(([path, { localChange, gadgetChange }]) => {\n switch (true) {\n case localChange.type === \"create\" && gadgetChange.type === \"create\":\n return [path, created, created];\n case localChange.type === \"create\" && gadgetChange.type === \"update\":\n return [path, created, updated];\n case localChange.type === \"create\" && gadgetChange.type === \"delete\":\n return [path, created, deleted];\n case localChange.type === \"update\" && gadgetChange.type === \"create\":\n return [path, updated, created];\n case localChange.type === \"update\" && gadgetChange.type === \"update\":\n return [path, updated, updated];\n case localChange.type === \"update\" && gadgetChange.type === \"delete\":\n return [path, updated, deleted];\n case localChange.type === \"delete\" && gadgetChange.type === \"create\":\n return [path, deleted, created];\n case localChange.type === \"delete\" && gadgetChange.type === \"update\":\n return [path, deleted, updated];\n default:\n throw new Error(`Unexpected conflict: ${localChange.type} vs ${gadgetChange.type}`);\n }\n }),\n });\n};\n"],"names":["chalk","printTable","ChangesWithHash","isEqualHash","Conflicts","Map","getConflicts","localChanges","environmentChanges","conflicts","filepath","localChange","gadgetChange","get","type","targetHash","set","keys","startsWith","delete","withoutConflictingChanges","changes","changesWithoutConflicts","has","printConflicts","created","greenBright","updated","blueBright","deleted","redBright","title","ensureEmptyLineAbove","ensureEmptyLineAboveBody","colAligns","headers","rows","Array","from","entries","sort","a","b","localeCompare","map","path","Error"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/services/filesync/directory.ts"],"sourcesContent":["/**\n * DO NOT MODIFY\n *\n * Everything in this file also exists in gadget to ensure that this logic\n * is the same between the two projects.\n */\nimport fs from \"fs-extra\";\nimport type { Ignore } from \"ignore\";\nimport ignore from \"ignore\";\nimport assert from \"node:assert\";\nimport { createHash } from \"node:crypto\";\nimport path from \"node:path\";\nimport { Transform } from \"node:stream\";\nimport { pipeline } from \"node:stream/promises\";\nimport normalizePath from \"normalize-path\";\n\n/**\n * Paths that are always ignored, regardless of the contents of the `.ignore` file.\n */\nexport const ALWAYS_IGNORE_PATHS = [\".DS_Store\", \"node_modules\", \".git\"] as const;\n\n/**\n * Paths that are ignored when hashing the directory.\n *\n * NOTE: This is the _only_ thing that is allowed to be different between gadget and ggt.\n */\nexport const HASHING_IGNORE_PATHS = [\".gadget/sync.json\", \".gadget/backup\", \"yarn-error.log\"] as const;\n\n/**\n * Represents a directory that is being synced.\n */\nexport class Directory {\n /**\n * A gitignore-style file parser used to determine which files to\n * ignore while syncing.\n *\n * @see https://www.npmjs.com/package/ignore\n */\n private _ignorer!: Ignore;\n\n /**\n * Whether the directory is currently being hashed.\n */\n private _isHashing = false;\n\n private constructor(\n /**\n * An absolute path to the directory that is being synced.\n */\n readonly path: string,\n ) {}\n\n /**\n * Initializes a directory to be synced.\n *\n * If the directory does not exist, it is created.\n *\n * @param dir - The directory to initialize.\n * @returns A Promise that resolves to a Directory instance.\n */\n static async init(dir: string): Promise<Directory> {\n const directory = new Directory(dir);\n await directory.loadIgnoreFile();\n return directory;\n }\n\n /**\n * Returns the relative path from this directory to the specified path.\n *\n * @param to - The path to which the relative path is calculated.\n * @returns The relative path from this directory to the specified path.\n */\n relative(to: string): string {\n if (!path.isAbsolute(to)) {\n // the filepath is already relative\n return to;\n }\n\n return path.relative(this.path, to);\n }\n\n /**\n * Returns the absolute path by resolving the given path segments\n * relative to the directory path.\n *\n * @param pathSegments - The path segments to resolve.\n * @returns The absolute path.\n */\n absolute(...pathSegments: string[]): string {\n const result = path.resolve(this.path, ...pathSegments);\n assert(result.startsWith(this.path), `expected ${result} to be within ${this.path}`);\n return result;\n }\n\n /**\n * Similar to {@linkcode relative} in that it converts an absolute\n * path into a relative one from {@linkcode path}. However, it also\n * changes any slashes to be posix/unix-like forward slashes,\n * condenses repeated slashes into a single slash, and adds a trailing\n * slash if the path is a directory.\n *\n * This is used when sending files to Gadget to ensure that the paths\n * are consistent across platforms.\n *\n * @see https://www.npmjs.com/package/normalize-path\n */\n normalize(filepath: string, isDirectory: boolean): string {\n if (path.isAbsolute(filepath)) {\n filepath = this.relative(filepath);\n }\n\n // true = trim trailing slashes\n filepath = normalizePath(filepath, true);\n\n if (isDirectory) {\n filepath += \"/\";\n }\n\n return filepath;\n }\n\n /**\n * Loads the `.ignore` file in the directory. If the file does not\n * exist, it is silently ignored.\n */\n async loadIgnoreFile(): Promise<void> {\n this._ignorer = ignore.default();\n this._ignorer.add(ALWAYS_IGNORE_PATHS);\n\n try {\n const content = await fs.readFile(this.absolute(\".ignore\"), \"utf8\");\n this._ignorer.add(content);\n } catch (error) {\n swallowEnoent(error);\n }\n }\n\n /**\n * Determines if a file should be ignored based on its filepath.\n *\n * @param filepath - The filepath of the file to check.\n * @returns True if the file should be ignored, false otherwise.\n */\n ignores(filepath: string): boolean {\n filepath = this.relative(filepath);\n if (filepath === \"\") {\n // don't ignore the root dir\n return false;\n }\n\n if (filepath.startsWith(\"..\")) {\n // anything above the root dir is ignored\n return true;\n }\n\n // false = don't trim trailing slashes\n filepath = normalizePath(filepath, false);\n if (this._isHashing && HASHING_IGNORE_PATHS.some((ignored) => filepath.startsWith(ignored))) {\n // special case for hashing\n return true;\n }\n\n return this._ignorer.ignores(filepath);\n }\n\n /**\n * Recursively walks through the directory and yields all non-ignored\n * files and directories within it.\n *\n * @yields - The normalized path of each file and directory.\n */\n async *walk({ dir = this.path } = {}): AsyncGenerator<string> {\n // don't yield the root directory\n if (dir !== this.path) {\n yield this.normalize(dir, true);\n }\n\n for await (const entry of await fs.opendir(dir)) {\n const filepath = path.join(dir, entry.name);\n if (this.ignores(filepath)) {\n continue;\n }\n\n if (entry.isDirectory()) {\n yield* this.walk({ dir: filepath });\n } else if (entry.isFile()) {\n yield this.normalize(filepath, false);\n }\n }\n }\n\n /**\n * Calculates the hash of each file and directory and returns an\n * object containing the hashes keyed by the normalized file path.\n *\n * @returns A Promise that resolves to an object containing the hashes\n * of each file.\n */\n async hashes(): Promise<Hashes> {\n try {\n this._isHashing = true;\n const files = {} as Hashes;\n\n for await (const normalizedPath of this.walk()) {\n const absolutePath = this.absolute(normalizedPath);\n files[normalizedPath] = await hash(absolutePath);\n }\n\n return files;\n } finally {\n this._isHashing = false;\n }\n }\n\n async hasFiles(): Promise<boolean> {\n return !(await this.isEmptyOrNonExistent());\n }\n\n async isEmptyOrNonExistent(): Promise<boolean> {\n let isEmptyOrNonExistent = true;\n try {\n for await (const _ of this.walk()) {\n isEmptyOrNonExistent = false;\n break;\n }\n } catch (error) {\n swallowEnoent(error);\n }\n return isEmptyOrNonExistent;\n }\n}\n\n/**\n * Key/value pairs where the key is the normalized path and the value is\n * the result of {@linkcode hash} for that path.\n */\nexport type Hashes = Record<string, Hash>;\n\nexport type Hash = {\n /**\n * The SHA-1 hash of the file or directory.\n *\n * If the path points to a directory, the hash is calculated based on\n * the directory's basename. If the path points to a file, the hash is\n * calculated based on the file's basename and contents.\n */\n sha1: string;\n\n /**\n * The Unix-style file permissions of the file or directory, or\n * undefined if the platform that generated this hash doesn't support\n * them.\n *\n * @example 0o644\n * @see supportsPermissions\n */\n permissions?: number;\n};\n\n/**\n * Whether the current platform supports Unix-style file permissions.\n *\n * Windows doesn't support Unix-style file permissions and all file\n * permissions retrieved via `node:fs` on Windows are translated to 666\n * or 444.\n */\nexport const supportsPermissions = process.platform === \"linux\" || process.platform === \"darwin\";\n\n/**\n * Calculates the {@linkcode Hash} of the file or directory at the\n * specified absolute path.\n *\n * @param absolutePath - The absolute path to the file or directory.\n * @returns A Promise that resolves to the {@linkcode Hash} of the file\n * or directory.\n */\nconst hash = async (absolutePath: string): Promise<Hash> => {\n const sha1 = createHash(\"sha1\");\n sha1.update(path.basename(absolutePath));\n\n const stats = await fs.stat(absolutePath);\n\n let permissions;\n if (supportsPermissions) {\n // strip everything but the permissions\n permissions = stats.mode & 0o777;\n }\n\n if (stats.isDirectory()) {\n return { sha1: sha1.digest(\"hex\"), permissions };\n }\n\n // windows uses CRLF line endings whereas unix uses LF line endings so\n // we always strip out CR bytes (0x0d) when hashing files. this does\n // make us blind to files that only differ by CR bytes, but that's a\n // tradeoff we're willing to make.\n const removeCR = new Transform({\n transform(chunk: Buffer, _encoding, callback) {\n if (!chunk.includes(0x0d)) {\n callback(undefined, chunk);\n return;\n }\n\n const filteredChunk = Buffer.alloc(chunk.length);\n let i = 0;\n for (const byte of chunk) {\n if (byte !== 0x0d) {\n filteredChunk[i++] = byte;\n }\n }\n\n callback(undefined, filteredChunk.slice(0, i));\n },\n });\n\n await pipeline(fs.createReadStream(absolutePath), removeCR, sha1);\n\n return { sha1: sha1.digest(\"hex\"), permissions };\n};\n\n/**\n * Swallows ENOENT errors and throws any other errors.\n *\n * @param error - The error to handle.\n * @throws The original error if it is not an ENOENT error.\n */\nexport const swallowEnoent = (error: unknown): void => {\n if (error && typeof error === \"object\" && \"code\" in error && error.code === \"ENOENT\") {\n return;\n }\n throw error;\n};\n"],"names":["fs","ignore","assert","createHash","path","Transform","pipeline","normalizePath","ALWAYS_IGNORE_PATHS","HASHING_IGNORE_PATHS","Directory","init","dir","directory","loadIgnoreFile","relative","to","isAbsolute","absolute","pathSegments","result","resolve","startsWith","normalize","filepath","isDirectory","_ignorer","default","add","content","readFile","error","swallowEnoent","ignores","_isHashing","some","ignored","walk","entry","opendir","join","name","isFile","hashes","files","normalizedPath","absolutePath","hash","hasFiles","isEmptyOrNonExistent","_","supportsPermissions","process","platform","sha1","update","basename","stats","stat","permissions","mode","digest","removeCR","transform","chunk","_encoding","callback","includes","undefined","filteredChunk","Buffer","alloc","length","i","byte","slice","createReadStream","code"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/services/filesync/directory.ts"],"sourcesContent":["/**\n * DO NOT MODIFY\n *\n * Everything in this file also exists in gadget to ensure that this logic\n * is the same between the two projects.\n */\nimport fs from \"fs-extra\";\nimport type { Ignore } from \"ignore\";\nimport ignore from \"ignore\";\nimport assert from \"node:assert\";\nimport { createHash } from \"node:crypto\";\nimport path from \"node:path\";\nimport { Transform } from \"node:stream\";\nimport { pipeline } from \"node:stream/promises\";\nimport normalizePath from \"normalize-path\";\n\n/**\n * Paths that are always ignored, regardless of the contents of the `.ignore` file.\n */\nexport const ALWAYS_IGNORE_PATHS = [\".DS_Store\", \"node_modules\", \".git\"] as const;\n\n/**\n * Paths that are ignored when hashing the directory.\n *\n * NOTE: This is the _only_ thing that is allowed to be different between gadget and ggt.\n */\nexport const HASHING_IGNORE_PATHS = [\".gadget/sync.json\", \".gadget/backup\", \"yarn-error.log\"] as const;\n\n/**\n * Represents a directory that is being synced.\n */\nexport class Directory {\n /**\n * A gitignore-style file parser used to determine which files to\n * ignore while syncing.\n *\n * @see https://www.npmjs.com/package/ignore\n */\n private _ignorer!: Ignore;\n\n /**\n * Whether the directory is currently being hashed.\n */\n private _isHashing = false;\n\n private constructor(\n /**\n * An absolute path to the directory that is being synced.\n */\n readonly path: string,\n ) {}\n\n /**\n * Initializes a directory to be synced.\n *\n * If the directory does not exist, it is created.\n *\n * @param dir - The directory to initialize.\n * @returns A Promise that resolves to a Directory instance.\n */\n static async init(dir: string): Promise<Directory> {\n const directory = new Directory(dir);\n await directory.loadIgnoreFile();\n return directory;\n }\n\n /**\n * Returns the relative path from this directory to the specified path.\n *\n * @param to - The path to which the relative path is calculated.\n * @returns The relative path from this directory to the specified path.\n */\n relative(to: string): string {\n if (!path.isAbsolute(to)) {\n // the filepath is already relative\n return to;\n }\n\n return path.relative(this.path, to);\n }\n\n /**\n * Returns the absolute path by resolving the given path segments\n * relative to the directory path.\n *\n * @param pathSegments - The path segments to resolve.\n * @returns The absolute path.\n */\n absolute(...pathSegments: string[]): string {\n const result = path.resolve(this.path, ...pathSegments);\n assert(result.startsWith(this.path), `expected ${result} to be within ${this.path}`);\n return result;\n }\n\n /**\n * Similar to {@linkcode relative} in that it converts an absolute\n * path into a relative one from {@linkcode path}. However, it also\n * changes any slashes to be posix/unix-like forward slashes,\n * condenses repeated slashes into a single slash, and adds a trailing\n * slash if the path is a directory.\n *\n * This is used when sending files to Gadget to ensure that the paths\n * are consistent across platforms.\n *\n * @see https://www.npmjs.com/package/normalize-path\n */\n normalize(filepath: string, isDirectory: boolean): string {\n if (path.isAbsolute(filepath)) {\n filepath = this.relative(filepath);\n }\n\n // true = trim trailing slashes\n filepath = normalizePath(filepath, true);\n\n if (isDirectory) {\n filepath += \"/\";\n }\n\n return filepath;\n }\n\n /**\n * Loads the `.ignore` file in the directory. If the file does not\n * exist, it is silently ignored.\n */\n async loadIgnoreFile(): Promise<void> {\n this._ignorer = ignore.default();\n this._ignorer.add(ALWAYS_IGNORE_PATHS);\n\n try {\n const content = await fs.readFile(this.absolute(\".ignore\"), \"utf8\");\n this._ignorer.add(content);\n } catch (error) {\n swallowEnoent(error);\n }\n }\n\n /**\n * Determines if a file should be ignored based on its filepath.\n *\n * @param filepath - The filepath of the file to check.\n * @returns True if the file should be ignored, false otherwise.\n */\n ignores(filepath: string): boolean {\n filepath = this.relative(filepath);\n if (filepath === \"\") {\n // don't ignore the root dir\n return false;\n }\n\n if (filepath.startsWith(\"..\")) {\n // anything above the root dir is ignored\n return true;\n }\n\n // false = don't trim trailing slashes\n filepath = normalizePath(filepath, false);\n if (this._isHashing && HASHING_IGNORE_PATHS.some((ignored) => filepath.startsWith(ignored))) {\n // special case for hashing\n return true;\n }\n\n return this._ignorer.ignores(filepath);\n }\n\n /**\n * Recursively walks through the directory and yields all non-ignored\n * files and directories within it.\n *\n * @yields - The normalized path of each file and directory.\n */\n async *walk({ dir = this.path } = {}): AsyncGenerator<string> {\n // don't yield the root directory\n if (dir !== this.path) {\n yield this.normalize(dir, true);\n }\n\n for await (const entry of await fs.opendir(dir)) {\n const filepath = path.join(dir, entry.name);\n if (this.ignores(filepath)) {\n continue;\n }\n\n if (entry.isDirectory()) {\n yield* this.walk({ dir: filepath });\n } else if (entry.isFile()) {\n yield this.normalize(filepath, false);\n }\n }\n }\n\n /**\n * Calculates the hash of each file and directory and returns an\n * object containing the hashes keyed by the normalized file path.\n *\n * @returns A Promise that resolves to an object containing the hashes\n * of each file.\n */\n async hashes(): Promise<Hashes> {\n try {\n this._isHashing = true;\n const files = {} as Hashes;\n\n for await (const normalizedPath of this.walk()) {\n const absolutePath = this.absolute(normalizedPath);\n files[normalizedPath] = await hash(absolutePath);\n }\n\n return files;\n } finally {\n this._isHashing = false;\n }\n }\n\n async hasFiles(): Promise<boolean> {\n return !(await this.isEmptyOrNonExistent());\n }\n\n async isEmptyOrNonExistent(): Promise<boolean> {\n let isEmptyOrNonExistent = true;\n try {\n for await (const _ of this.walk()) {\n isEmptyOrNonExistent = false;\n break;\n }\n } catch (error) {\n swallowEnoent(error);\n }\n return isEmptyOrNonExistent;\n }\n}\n\n/**\n * Key/value pairs where the key is the normalized path and the value is\n * the result of {@linkcode hash} for that path.\n */\nexport type Hashes = Record<string, Hash>;\n\nexport type Hash = {\n /**\n * The SHA-1 hash of the file or directory.\n *\n * If the path points to a directory, the hash is calculated based on\n * the directory's basename. If the path points to a file, the hash is\n * calculated based on the file's basename and contents.\n */\n sha1: string;\n\n /**\n * The Unix-style file permissions of the file or directory, or\n * undefined if the platform that generated this hash doesn't support\n * them.\n *\n * @example 0o644\n * @see supportsPermissions\n */\n permissions?: number;\n};\n\n/**\n * Whether the current platform supports Unix-style file permissions.\n *\n * Windows doesn't support Unix-style file permissions and all file\n * permissions retrieved via `node:fs` on Windows are translated to 666\n * or 444.\n */\nexport const supportsPermissions = process.platform === \"linux\" || process.platform === \"darwin\";\n\n/**\n * Calculates the {@linkcode Hash} of the file or directory at the\n * specified absolute path.\n *\n * @param absolutePath - The absolute path to the file or directory.\n * @returns A Promise that resolves to the {@linkcode Hash} of the file\n * or directory.\n */\nconst hash = async (absolutePath: string): Promise<Hash> => {\n const sha1 = createHash(\"sha1\");\n sha1.update(path.basename(absolutePath));\n\n const stats = await fs.stat(absolutePath);\n\n let permissions;\n if (supportsPermissions) {\n // strip everything but the permissions\n permissions = stats.mode & 0o777;\n }\n\n if (stats.isDirectory()) {\n return { sha1: sha1.digest(\"hex\"), permissions };\n }\n\n // windows uses CRLF line endings whereas unix uses LF line endings so\n // we always strip out CR bytes (0x0d) when hashing files. this does\n // make us blind to files that only differ by CR bytes, but that's a\n // tradeoff we're willing to make.\n const removeCR = new Transform({\n transform(chunk: Buffer, _encoding, callback) {\n if (!chunk.includes(0x0d)) {\n callback(undefined, chunk);\n return;\n }\n\n const filteredChunk = Buffer.alloc(chunk.length);\n let i = 0;\n for (const byte of chunk) {\n if (byte !== 0x0d) {\n filteredChunk[i++] = byte;\n }\n }\n\n callback(undefined, filteredChunk.slice(0, i));\n },\n });\n\n await pipeline(fs.createReadStream(absolutePath), removeCR, sha1);\n\n return { sha1: sha1.digest(\"hex\"), permissions };\n};\n\n/**\n * Swallows ENOENT errors and throws any other errors.\n *\n * @param error - The error to handle.\n * @throws The original error if it is not an ENOENT error.\n */\nexport const swallowEnoent = (error: unknown): void => {\n if (error && typeof error === \"object\" && \"code\" in error && error.code === \"ENOENT\") {\n return;\n }\n throw error;\n};\n"],"names":["fs","ignore","assert","createHash","path","Transform","pipeline","normalizePath","ALWAYS_IGNORE_PATHS","HASHING_IGNORE_PATHS","Directory","init","dir","directory","loadIgnoreFile","relative","to","isAbsolute","absolute","pathSegments","result","resolve","startsWith","normalize","filepath","isDirectory","_ignorer","default","add","content","readFile","error","swallowEnoent","ignores","_isHashing","some","ignored","walk","entry","opendir","join","name","isFile","hashes","files","normalizedPath","absolutePath","hash","hasFiles","isEmptyOrNonExistent","_","supportsPermissions","process","platform","sha1","update","basename","stats","stat","permissions","mode","digest","removeCR","transform","chunk","_encoding","callback","includes","undefined","filteredChunk","Buffer","alloc","length","i","byte","slice","createReadStream","code"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/services/filesync/error.ts"],"sourcesContent":["import { ClientError } from \"../app/error.js\";\nimport type { Context } from \"../command/context.js\";\nimport { sprintProblems, type Problems } from \"../output/problems.js\";\nimport { GGTError, IsBug } from \"../output/report.js\";\nimport { sprint, sprintln } from \"../output/sprint.js\";\nimport { isGraphQLErrors, isGraphQLResult, isObject, isString } from \"../util/is.js\";\nimport type { Directory } from \"./directory.js\";\nimport type { SyncJsonArgs } from \"./sync-json.js\";\n\nexport class YarnNotFoundError extends GGTError {\n isBug = IsBug.NO;\n\n constructor() {\n super(\"Yarn not found\");\n }\n\n protected render(): string {\n return sprint`\n Yarn must be installed to sync your application. You can install it by running:\n\n $ npm install --global yarn\n\n For more information, see: https://classic.yarnpkg.com/en/docs/install\n `;\n }\n}\n\nexport class UnknownDirectoryError extends GGTError {\n isBug = IsBug.NO;\n\n constructor(\n readonly ctx: Context<SyncJsonArgs>,\n readonly opts: { directory: Directory },\n ) {\n super('The \".gadget/sync.json\" file was invalid or not found');\n }\n\n protected render(): string {\n const cmd = this.ctx.command;\n const dir = this.opts.directory.path;\n\n switch (cmd) {\n case \"open\":\n case \"status\":\n return sprint`\n A \".gadget/sync.json\" file is missing in this directory:\n\n ${dir}\n\n In order to use \"ggt ${cmd}\", you must run it within a directory\n that has already been initialized with \"ggt dev\".\n `;\n case \"dev\":\n return sprint`\n A \".gadget/sync.json\" file is missing in this directory:\n\n ${dir}\n\n If you're running \"ggt dev\" for the first time, we recommend\n using a gadget specific directory like this:\n\n ggt dev ~/gadget/${this.ctx.args[\"--app\"] ?? \"<name>\"}\n\n To use a non-empty directory without a \".gadget/sync.json\" file,\n run \"ggt dev\" again with the \"--allow-unknown-directory\" flag:\n\n ggt dev ${dir} --allow-unknown-directory\n `;\n default:\n return sprint`\n A \".gadget/sync.json\" file is missing in this directory:\n\n ${dir}\n\n If you're certain you want to use this directory, you can run\n \"ggt ${cmd}\" again with the \"--allow-unknown-directory\" flag:\n\n ggt ${cmd} --allow-unknown-directory\n `;\n }\n }\n}\n\nexport class TooManyMergeAttemptsError extends GGTError {\n isBug = IsBug.MAYBE;\n\n constructor(readonly attempts: number) {\n super(`Failed to synchronize files after ${attempts} attempts.`);\n }\n\n protected render(): string {\n return sprint`\n We merged your local files with your environment's files ${this.attempts} times,\n but your local and environment's files still don't match.\n\n Make sure no one else is editing files on your environment, and try again.\n `;\n }\n}\n\nexport class DeployDisallowedError extends GGTError {\n isBug = IsBug.MAYBE;\n\n constructor(readonly fatalErrors: Problems) {\n super(\"This application is not allowed to be deployed due to fatal errors.\");\n }\n\n protected render(): string {\n let output = sprintln`{red Gadget has detected the following fatal errors with your files:}`;\n output += sprintProblems({ ensureEmptyLineAbove: true, problems: this.fatalErrors, showFileTypes: false });\n output += sprintln({ ensureEmptyLineAbove: true })`{red Please fix these errors and try again.}`;\n return output;\n }\n}\n\nexport const isFilesVersionMismatchError = (error: unknown): boolean => {\n if (error instanceof ClientError) {\n error = error.cause;\n }\n if (isGraphQLResult(error)) {\n error = error.errors;\n }\n if (isGraphQLErrors(error)) {\n error = error[0];\n }\n return isObject(error) && \"message\" in error && isString(error.message) && error.message.includes(\"Files version mismatch\");\n};\n\nexport const swallowFilesVersionMismatch = (ctx: Context, error: unknown): void => {\n if (isFilesVersionMismatchError(error)) {\n ctx.log.debug(\"swallowing files version mismatch\", { error });\n return;\n }\n throw error;\n};\n"],"names":["ClientError","sprintProblems","GGTError","IsBug","sprint","sprintln","isGraphQLErrors","isGraphQLResult","isObject","isString","YarnNotFoundError","render","constructor","isBug","NO","UnknownDirectoryError","cmd","ctx","command","dir","opts","directory","path","args","TooManyMergeAttemptsError","attempts","MAYBE","DeployDisallowedError","output","ensureEmptyLineAbove","problems","fatalErrors","showFileTypes","isFilesVersionMismatchError","error","cause","errors","message","includes","swallowFilesVersionMismatch","log","debug"],"mappings":";AAAA,SAASA,WAAW,QAAQ,kBAAkB;AAE9C,SAASC,cAAc,QAAuB,wBAAwB;AACtE,SAASC,QAAQ,EAAEC,KAAK,QAAQ,sBAAsB;AACtD,SAASC,MAAM,EAAEC,QAAQ,QAAQ,sBAAsB;AACvD,SAASC,eAAe,EAAEC,eAAe,EAAEC,QAAQ,EAAEC,QAAQ,QAAQ,gBAAgB;AAIrF,OAAO,MAAMC,0BAA0BR;IAO3BS,SAAiB;QACzB,OAAOP,MAAM,CAAC;;;;;;IAMd,CAAC;IACH;IAZAQ,aAAc;QACZ,KAAK,CAAC;QAHRC,uBAAAA,SAAQV,MAAMW,EAAE;IAIhB;AAWF;AAEA,OAAO,MAAMC,8BAA8Bb;IAU/BS,SAAiB;QACzB,MAAMK,MAAM,IAAI,CAACC,GAAG,CAACC,OAAO;QAC5B,MAAMC,MAAM,IAAI,CAACC,IAAI,CAACC,SAAS,CAACC,IAAI;QAEpC,OAAQN;YACN,KAAK;YACL,KAAK;gBACH,OAAOZ,MAAM,CAAC;;;YAGV,EAAEe,IAAI;;+BAEa,EAAEH,IAAI;;QAE7B,CAAC;YACH,KAAK;gBACH,OAAOZ,MAAM,CAAC;;;YAGV,EAAEe,IAAI;;;;;6BAKW,EAAE,IAAI,CAACF,GAAG,CAACM,IAAI,CAAC,QAAQ,IAAI,SAAS;;;;;oBAK9C,EAAEJ,IAAI;QAClB,CAAC;YACH;gBACE,OAAOf,MAAM,CAAC;;;YAGV,EAAEe,IAAI;;;eAGH,EAAEH,IAAI;;gBAEL,EAAEA,IAAI;QACd,CAAC;QACL;IACF;
|
|
1
|
+
{"version":3,"sources":["../../../src/services/filesync/error.ts"],"sourcesContent":["import { ClientError } from \"../app/error.js\";\nimport type { Context } from \"../command/context.js\";\nimport { sprintProblems, type Problems } from \"../output/problems.js\";\nimport { GGTError, IsBug } from \"../output/report.js\";\nimport { sprint, sprintln } from \"../output/sprint.js\";\nimport { isGraphQLErrors, isGraphQLResult, isObject, isString } from \"../util/is.js\";\nimport type { Directory } from \"./directory.js\";\nimport type { SyncJsonArgs } from \"./sync-json.js\";\n\nexport class YarnNotFoundError extends GGTError {\n isBug = IsBug.NO;\n\n constructor() {\n super(\"Yarn not found\");\n }\n\n protected render(): string {\n return sprint`\n Yarn must be installed to sync your application. You can install it by running:\n\n $ npm install --global yarn\n\n For more information, see: https://classic.yarnpkg.com/en/docs/install\n `;\n }\n}\n\nexport class UnknownDirectoryError extends GGTError {\n isBug = IsBug.NO;\n\n constructor(\n readonly ctx: Context<SyncJsonArgs>,\n readonly opts: { directory: Directory },\n ) {\n super('The \".gadget/sync.json\" file was invalid or not found');\n }\n\n protected render(): string {\n const cmd = this.ctx.command;\n const dir = this.opts.directory.path;\n\n switch (cmd) {\n case \"add\":\n case \"open\":\n case \"status\":\n return sprint`\n A \".gadget/sync.json\" file is missing in this directory:\n\n ${dir}\n\n In order to use \"ggt ${cmd}\", you must run it within a directory\n that has already been initialized with \"ggt dev\".\n `;\n case \"dev\":\n return sprint`\n A \".gadget/sync.json\" file is missing in this directory:\n\n ${dir}\n\n If you're running \"ggt dev\" for the first time, we recommend\n using a gadget specific directory like this:\n\n ggt dev ~/gadget/${this.ctx.args[\"--app\"] ?? \"<name>\"}\n\n To use a non-empty directory without a \".gadget/sync.json\" file,\n run \"ggt dev\" again with the \"--allow-unknown-directory\" flag:\n\n ggt dev ${dir} --allow-unknown-directory\n `;\n default:\n return sprint`\n A \".gadget/sync.json\" file is missing in this directory:\n\n ${dir}\n\n If you're certain you want to use this directory, you can run\n \"ggt ${cmd}\" again with the \"--allow-unknown-directory\" flag:\n\n ggt ${cmd} --allow-unknown-directory\n `;\n }\n }\n}\n\nexport class TooManyMergeAttemptsError extends GGTError {\n isBug = IsBug.MAYBE;\n\n constructor(readonly attempts: number) {\n super(`Failed to synchronize files after ${attempts} attempts.`);\n }\n\n protected render(): string {\n return sprint`\n We merged your local files with your environment's files ${this.attempts} times,\n but your local and environment's files still don't match.\n\n Make sure no one else is editing files on your environment, and try again.\n `;\n }\n}\n\nexport class DeployDisallowedError extends GGTError {\n isBug = IsBug.MAYBE;\n\n constructor(readonly fatalErrors: Problems) {\n super(\"This application is not allowed to be deployed due to fatal errors.\");\n }\n\n protected render(): string {\n let output = sprintln`{red Gadget has detected the following fatal errors with your files:}`;\n output += sprintProblems({ ensureEmptyLineAbove: true, problems: this.fatalErrors, showFileTypes: false });\n output += sprintln({ ensureEmptyLineAbove: true })`{red Please fix these errors and try again.}`;\n return output;\n }\n}\n\nexport const isFilesVersionMismatchError = (error: unknown): boolean => {\n if (error instanceof ClientError) {\n error = error.cause;\n }\n if (isGraphQLResult(error)) {\n error = error.errors;\n }\n if (isGraphQLErrors(error)) {\n error = error[0];\n }\n return isObject(error) && \"message\" in error && isString(error.message) && error.message.includes(\"Files version mismatch\");\n};\n\nexport const swallowFilesVersionMismatch = (ctx: Context, error: unknown): void => {\n if (isFilesVersionMismatchError(error)) {\n ctx.log.debug(\"swallowing files version mismatch\", { error });\n return;\n }\n throw error;\n};\n"],"names":["ClientError","sprintProblems","GGTError","IsBug","sprint","sprintln","isGraphQLErrors","isGraphQLResult","isObject","isString","YarnNotFoundError","render","constructor","isBug","NO","UnknownDirectoryError","cmd","ctx","command","dir","opts","directory","path","args","TooManyMergeAttemptsError","attempts","MAYBE","DeployDisallowedError","output","ensureEmptyLineAbove","problems","fatalErrors","showFileTypes","isFilesVersionMismatchError","error","cause","errors","message","includes","swallowFilesVersionMismatch","log","debug"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/services/filesync/file.ts"],"sourcesContent":["import type { FileSyncEncoding } from \"../../__generated__/graphql.js\";\n\nexport type File = {\n path: string;\n oldPath?: string | null;\n mode: number;\n content: string;\n encoding: FileSyncEncoding;\n};\n"],"names":[],"mappings":"AAEA,WAME"}
|
|
1
|
+
{"version":3,"sources":["../../../src/services/filesync/file.ts"],"sourcesContent":["import type { FileSyncEncoding } from \"../../__generated__/graphql.js\";\n\nexport type File = {\n path: string;\n oldPath?: string | null;\n mode: number;\n content: string;\n encoding: FileSyncEncoding;\n};\n"],"names":[],"rangeMappings":"","mappings":"AAEA,WAME"}
|